Unidade 4 · receitas da casa
Receitas da casa
Quando o mesmo gesto se repete — etiqueta, área da mesa, total do pão — você escreve a receita uma vez. def, parâmetro, return, escopo, ponto de entrada.
Não no primeiro recado
No recado você imprime. No crachá, guarda. Na via, decide. Na fila, repete. Copiar print("VIA") três vezes já doeu — e ainda não tinha nome para “pergunte um N positivo”. Função existe para isso: um gesto, um nome, devolve ou mostra, e o resto do arquivo só chama.
Se tivesse vindo na unidade 1, você fatiaria um programa de uma linha. Agora há o que fatiar: loop, input, conta, recado. A receita só vale a pena quando a mão já copiou.
Receita na cozinha, não na hora do palpite
Arquivo etiqueta.py. A função etiqueta recebe um texto e o imprime entre linhas. Parâmetro é o nome do ingrediente na receita; argumento é o valor na hora de usar.
def etiqueta(texto):
print("---")
print(texto)
print("---")
etiqueta("Arquivo morto")
Dois-pontos no fim do def. Tudo indentado (4 espaços) pertence à função. Sem indentação o Python recusa — a linguagem usa recuo no lugar de chaves { }.
No editor da unidade, Tab insere quatro espaços, como no dia a dia. Depois de uma linha que termina em :, Enter já começa recuado. Misture tab e espaço no mesmo bloco e o interpretador reclama; fique nos espaços.
Se você chama a função antes de defini-la, no fluxo de cima para baixo: NameError. Defina primeiro, use depois — ou organize o arquivo com um ponto de entrada no fim.
Defina etiqueta(texto) que imprime o parâmetro (pelo menos um print).
def etiqueta(texto): print(texto)Como passar o ingrediente
Posicional: a ordem dos parênteses é a ordem da receita. area(3, 2) — 3 entra no primeiro parâmetro, 2 no segundo.
Nomeado: você chama pelo nome, a ordem pode mudar. area(altura=2, largura=3). Já vimos isso em sep= e end=.
Valor padrão: def etiqueta(texto, marca="-"). Se ninguém passar marca, vale o traço. Quem chama pode sobrescrever: etiqueta("urgente", marca="*").
Docstring logo abaixo do def, indentada, entre """: uma frase do que a função faz. Ferramentas e humanos leem. Não substitui um nome claro.
def area(largura, altura):
"""Área de um retângulo em unidades quadradas."""
return largura * altura
Devolver, não só mostrar
Imprimir é efeito na tela. Calcular área de um retângulo (etiqueta adesiva, box de produto) precisa entregar o número para o resto do programa usar — somar, arredondar, mandar para outro print.
def area(largura, altura):
return largura * altura
m2 = area(3, 2)
print(f"{m2} m²")
Sem return, a conta acontece e some; quem chamou recebe None. Três contas equivalentes para potência, se um dia precisar: n * n, n ** 2, pow(n, 2) — aqui o caso natural é só o produto da largura pela altura.
Escreva area(largura, altura) que devolve o produto (não imprima dentro da função).
def area(largura, altura): return largura * alturaO arquivo precisa de um disparo
Definir main não executa nada. def só registra a receita. Alguém precisa chamar main() — em geral no fim do arquivo, ou dentro do idioma abaixo.
Ponto de entrada idiomático em Python — o arquivo só “dispara” quando rodado direto, não quando importado:
def area(largura, altura):
return largura * altura
def main():
print(area(3, 2))
if __name__ == "__main__":
main()
__name__ vale "__main__" quando o arquivo é o que você passou para python. Assim as funções podem ser reaproveitadas em outro arquivo sem executar o teste sozinhas.
Você escreveu def main(): com um print dentro. O arquivo roda e a tela fica vazia. Por quê?
Gaveta de um cômodo só
Escopo: variável criada dentro de uma função só existe ali. Se capa faz titulo = "relatório" e etiqueta tenta print(titulo) sem receber parâmetro, NameError. A ponte é o argumento: etiqueta(titulo) de um lado, def etiqueta(texto) do outro. Os nomes podem ser diferentes; o valor é que viaja.
Métodos tipo .strip() continuam sendo de string: se sua função devolve número, não tem o que stripar.
titulo é criado dentro de capa(). etiqueta() sem parâmetros faz print(titulo). Resultado?
Devolver True ou False sem novela
Uma função que só pergunta “é par?” pode devolver a expressão crua:
def e_par(n):
return n % 2 == 0
Equivalente mais falado: return True if n % 2 == 0 else False. Os dois estão certos; o primeiro é mais curto. O if numa só linha (ternário) existe; não abuse se a leitura sofrer. A comparação já é um bool.
Uma linha de return que devolva se n é par (ternário ou a expressão n % 2 == 0).
return n % 2 == 0 ou return True if n % 2 == 0 else FalsePeças que já conhecemos, juntas
get_positivo não existe no Python. Você inventa. Dentro do loop, em vez de break + return lá fora, pode return n direto: sair da função já sai do loop.
def get_positivo():
while True:
n = int(input("Quantas vias? "))
if n > 0:
return n
def vias(n):
for _ in range(n):
print("VIA")
def main():
vias(get_positivo())
if __name__ == "__main__":
main()
break ainda vale: sai só do loop; aí você return n depois do while. Os dois caminhos existem.
Oficina · recibo mínimo
total(preco, qtd) que return o produto. No ponto de entrada, leia os dois valores (números, unidade 1), chame total e imprima com duas casas. Arquivo: recibo.py.
Cole o recibo: função com return e um ponto de entrada.
def total(preco, qtd):
return preco * qtd
if __name__ == "__main__":
p = float(input("Preço: "))
q = int(input("Qtd: "))
print(f"{total(p, q):.2f}")