Lista 12 · Funções¶
Esta é a primeira lista em que você escreve funções, no formato de
Python para Telecomunicações: cada exercício abaixo é uma função, com um
bloco de testes que já vem pronto no fim do arquivo. Se aparecer a mensagem
de sucesso, está certo; se aparecer AssertionError, a linha apontada é o
caso que a sua função ainda não atende.
O assunto é o do Capítulo 12: def,
parâmetro, argumento e return. Antes de entregar qualquer exercício,
pergunte-se: minha função devolve o valor, ou só mostra na tela? É o
defeito mais comum desta lista — a função que imprime o número certo e
esquece o return.
Como esta lista funciona
Abra o caderno no Colab e salve uma cópia no seu Drive antes de começar (Arquivo → Salvar uma cópia no Drive). Sem isso, você perde o que escrever.
Nos exercícios com célula de teste, escreva a solução no lugar do
# TODO e rode a célula de teste logo abaixo. Ela mesma diz o que
passou e o que falhou; se aparecer AssertionError, a linha apontada é
o caso que a sua solução ainda não atende. Não altere a célula de teste.
O código de cada exercício também está aqui embaixo, caso você prefira colar num editor local.
Parte A · no papel¶
Faça esta parte antes de ligar o computador
Escreva a resposta no caderno, depois rode para conferir. Prever e errar ensina; rodar primeiro e ler a saída, não.
No papel, antes do computador.
A1. Rastreie as chamadas. Complete a tabela com o que cada chamada imprime.
def linha_fatura(servico, valor):
print(f"{servico}: R$ {valor:.2f}")
linha_fatura("Internet", 99.9)
linha_fatura("Telefone", 45.5)
| Chamada | O que imprime |
|---|---|
linha_fatura("Internet", 99.9) |
|
linha_fatura("Telefone", 45.5) |
A2. Parâmetro ou argumento? Para cada item abaixo, diga se ele é um parâmetro ou um argumento.
| Item | Parâmetro ou argumento? |
|---|---|
preco, na linha do def |
|
quantidade, na linha do def |
|
9.90, na chamada |
|
3, na chamada |
A3. A armadilha do capítulo. O que este programa imprime, linha por linha?
| Linha | O que imprime |
|---|---|
resultado = dobro(5) |
|
print(resultado) |
resultado guardou o quê, de fato? Por que a função parece ter funcionado,
mesmo estando incompleta?
A4. Conserte. Esta função devia devolver o dobro do valor recebido, mas
todo teste falha, sempre comparando com None. Reescreva-a corretamente, no
caderno.
A5. Quantos argumentos? Esta função tem dois parâmetros:
Para cada chamada abaixo, diga se ela funciona ou dá erro — e, se der erro, qual:
| Chamada | Funciona ou dá erro? |
|---|---|
custo_total(9.90, 3) |
|
custo_total(9.90) |
|
custo_total(9.90, 3, 1) |
Parte B · no computador¶
Exercício 01¶
Escreva a função media, que recebe três notas e devolve a média
aritmética delas.
Dica: é a mesma conta da Unidade 1 — some as três notas e divida por 3.
def media(nota1, nota2, nota3):
"""Devolve a média aritmética das três notas."""
# TODO: some as três notas e divida o resultado por 3
pass
# --- testes (não altere) ---
assert media(7.0, 8.0, 9.0) == 8.0
assert media(10.0, 10.0, 10.0) == 10.0
assert media(0.0, 0.0, 0.0) == 0.0
assert media(4, 5, 6) == 5.0
print("Exercício 01: todos os testes passaram!")
Exercício 02¶
Um plano de telefonia inclui uma franquia de minutos por mês; usar além dela gera cobrança extra.
Escreva a função minutos_excedentes, que recebe os minutos usados no mês e
a franquia do plano e devolve quantos minutos passaram da franquia — ou 0,
se o cliente não passou.
def minutos_excedentes(minutos_usados, minutos_franquia):
"""Devolve quantos minutos passaram da franquia, ou 0 se não passou."""
# TODO: se minutos_usados for maior que minutos_franquia, devolva a
# diferença; senão, devolva 0
pass
# --- testes (não altere) ---
assert minutos_excedentes(220, 200) == 20
assert minutos_excedentes(200, 200) == 0
assert minutos_excedentes(0, 200) == 0
assert minutos_excedentes(150, 200) == 0
print("Exercício 02: todos os testes passaram!")
Exercício 03¶
Escreva a função troco, que recebe o valor pago e o valor da compra e
devolve o troco, arredondado para duas casas decimais.
Dica: round(valor, 2) arredonda para duas casas — útil porque contas com
números decimais às vezes sobram casas demais.
def troco(valor_pago, valor_compra):
"""Devolve o troco (valor_pago - valor_compra), com duas casas."""
# TODO: calcule a diferença e devolva com round(..., 2)
pass
# --- testes (não altere) ---
assert troco(50, 37.50) == 12.5
assert troco(20, 20) == 0
assert troco(15, 0) == 15
assert troco(100, 33.33) == 66.67
print("Exercício 03: todos os testes passaram!")
Exercício 04¶
Escreva a função preco_com_desconto, que recebe um preço e um percentual
de desconto e devolve o preço já com o desconto aplicado, arredondado para
duas casas decimais.
def preco_com_desconto(preco, percentual_desconto):
"""Devolve o preço após aplicar o percentual de desconto."""
# TODO: calcule o valor do desconto, subtraia do preço e devolva
# com round(..., 2)
pass
# --- testes (não altere) ---
assert preco_com_desconto(200, 10) == 180.0
assert preco_com_desconto(200, 0) == 200.0
assert preco_com_desconto(200, 100) == 0.0
assert preco_com_desconto(50, 50) == 25.0
print("Exercício 04: todos os testes passaram!")
Exercício 05¶
A conta do mês tem duas partes: a mensalidade, que todo mundo paga, e a cobrança dos minutos que passaram da franquia. Quem não passou paga só a mensalidade.
Escreva a função conta_do_mes, que recebe os minutos usados, a franquia do
plano, o preço do minuto excedente e a mensalidade, e devolve o valor total da
conta, arredondado para duas casas decimais.
Esta é a primeira função da lista que faz duas coisas em sequência: decidir
quanto foi o excedente e só então calcular o total. Escreva o if primeiro,
guarde o excedente numa variável, e faça a conta depois — é mais fácil de ler e
muito mais fácil de consertar do que tudo numa expressão só.
Repare que o segundo exemplo devolve
49.9, e não49.90. O Python não guarda o zero do fim:49.90e49.9são o mesmo número. Quem quer as duas casas na tela usa f-string — mas o que a função devolve é o número.
def conta_do_mes(minutos_usados, minutos_franquia, preco_excedente, mensalidade):
"""Devolve o total da conta: mensalidade mais os minutos que passaram."""
# TODO: com um if, descubra quantos minutos passaram da franquia
# (zero, se o cliente não passou) e guarde numa variável
# TODO: devolva a mensalidade mais o excedente vezes o preço,
# arredondado para duas casas com round(..., 2)
pass
# --- testes (não altere) ---
assert conta_do_mes(220, 200, 0.25, 49.90) == 54.9
assert conta_do_mes(150, 200, 0.25, 49.90) == 49.9
assert conta_do_mes(200, 200, 0.25, 49.90) == 49.9
assert conta_do_mes(0, 200, 0.25, 49.90) == 49.9
assert conta_do_mes(400, 200, 0.10, 0.0) == 20.0
print("Exercício 05: todos os testes passaram!")
Exercício 06¶
Escreva a função classifica_nota, que recebe uma nota (de 0 a 10) e
devolve uma classificação:
| Nota | Devolve |
|---|---|
| 7 ou mais | "aprovado" |
| de 5 (inclusive) até 7 (exclusive) | "recuperacao" |
| abaixo de 5 | "reprovado" |
classifica_nota(8.5) # -> "aprovado"
classifica_nota(6.0) # -> "recuperacao"
classifica_nota(3.0) # -> "reprovado"
Dica: é o mesmo formato de if/elif/else da Unidade 2, agora com
return no lugar de print.
def classifica_nota(nota):
"""Classifica a nota em 'aprovado', 'recuperacao' ou 'reprovado'."""
# TODO: use if/elif/else, com um return em cada caminho
pass
# --- testes (não altere) ---
assert classifica_nota(8.5) == "aprovado"
assert classifica_nota(7.0) == "aprovado"
assert classifica_nota(6.9) == "recuperacao"
assert classifica_nota(5.0) == "recuperacao"
assert classifica_nota(4.9) == "reprovado"
assert classifica_nota(0.0) == "reprovado"
print("Exercício 06: todos os testes passaram!")