Escrevendo Funções
Visão Geral
Perguntas
Como eu posso criar minhas próprias funções?
Objetivos
Explique e identifique a diferença entre a definição da função e a chamada da função.
Escreva uma função que receba um número fixo de argumentos e produza um único resultado.
Organize programas em funções para que sejam mais fáceis de entender.
- Seres humanos só conseguem manter algumas coisas “em memória” de cada vez.
- Entenda ideias maiores/mais complicadas ao entender e combinar peças individuais.
- Componentes em uma máquina.
- Capítulos e subseções em um grande relatório.
- Funções servem o mesmo propósito em programas.
- Encapsular complexidade para que possamos a tratar como uma única “coisa”.
- Também permite o re-uso.
- Escreva uma vez, use muitas vezes.
Defina uma função usando def com um nome, parâmetros, e um bloco de código.
- Comece a definição de uma nova função com
def. - Seguido do nome da função.
- Deve obedecer as mesmas regras que nomes de variáveis.
- Coloque os parâmetros entre parênteses.
- Coloque parênteses em branco se a função não recebe nenhum input.
- Vamos discutir isso em detalhe em um momento.
- Coloque dois pontos.
- E então um bloco indentado de código.
def imprimir_saudacao():
print('Olá!')
Definir uma função não roda ela.
- Definir uma função não roda ela.
- É como assinalar um valor a uma variável.
- Precisamos chamar a função para executar o código que ela contém.
imprimir_saudacao()
Olá!
Argumentos em uma chamada correspondem aos parâmetros na definição.
- Funções são úteis quando elas podem operar em diferentes dados.
- Especifique parâmetros quando for definir uma função.
- Esses se tornam variáveis quando a função é executada.
- São assinaladas aos argumentos na chamada, isto é, os valores passados para a função.
- Se você não nomear os argumentos quando for usá-los na chamada, os argumentos vão ser correspondidos com os parâmetros na ordem quem os parâmetros são definidos na função.
def imprimir_data(ano, mes, dia)
data_formatada = str(ano) + '/' + str(mes) + '/' + str(dia)
print(data_formatada)
imprimir_data(2021, 3, 19)
2021/3/19
Ou, podemos nomear os argumentos quando chamamos a função, o que nos permite especificá-los em qualquer ordem:
imprimir_data(mes=3, dia=19, ano=2021)
2021/3/19
- É como se o
()contivesse os ingredientes para a função e o corpo contém a receita.
Funções podem retornar um resultado para quem está chamando usando return.
- Use
return ...para retornar um valor a chamada da função. - Pode ocorrer em qualquer lugar da função..
- Mas funções são mais fáceis de entender se
returnocorre:- No começo para lidar com casos especiais.
- Bem no fim da função, com um resultado final.
def calcular_media(valores):
if len(valores) == 0:
return None
return sum(valores) / len(valores)
a = calcular_media([1, 3, 4])
print('Média de valores reais:', a)
Média de valores reais: 2.6666666666666665
print('Média de uma lista vazia:', calcular_media([]))
Média de uma lista vazia: None
- Lembre-se: toda função retorna algo!.
- Uma função que não tem um valor retornado por
returnautomaticamente retornaNone.
resultado = imprimir_data(2021, 3, 19)
print('O resultado da chamada é:', resultado)
2021/3/19
O resultado da chamada é: None
Identificando erros de sintaxe
- Leia o código abaixo e tente identificar o que os erros são sem rodá-lo.
- Rode o código e leia a mensagem de erro. É do tipo
SyntaxErrorouIndentationError?- Conserte o erro.
- Repita os passos 2 e 3 até que consertar todos os erros.
def outra_funcao print("Erros de sintaxe são irritantes.") print("Mas pelo menos o Python nos avisa sobre eles!") print("Então não são muito difíceis de consertar.")Solução
def outra_funcao(): print("Erros de sintaxe são irritantes.") print("Mas pelo menos o Python nos avisa sobre eles!") print("Então não são muito difíceis de consertar.")
Definição e Uso
O que o programa a seguir imprime?
def relatorio(consumo): print('consumo é', consumo) print('chamando', relatorio, 22.5)Solução
chamando <function relatorio at 0x7fd128ff1bf8> 22.5Uma chamada de função sempre precisa de parênteses, caso contrário você recebe o endereço de memória do objeto função. Então, se queremos chamar a função chamada
relatorio, e dar o valor 22.5 para ser reportado, podemos fazer nossa chamada de função assim:print("chamando") relatorio(22.5)chamando consumo é 22.5
Ordem das Operações
O que há de errado nesse exemplo?
resultado = imprimir_tempo(11, 37, 59) def imprimir_tempo(hour, minute, second): time_string = str(hour) + ':' + str(minute) + ':' + str(second) print(time_string)After fixing the problem above, explain why running this example code:
resultado = imprimir_tempo(11, 37, 59) print('resultado of call is:', resultado)gives this output:
11:37:59 resultado of call is: NonePor que o resultado da chamada é
None?Solução
O problema no exemploe é que a função
imprimir_tempo()é definida após a chamada ser feita. O Python não sabe como resolver o nomeimprimir_tempojá que não foi definido e vai retornar um errorNameErrorcomoNameError: name 'imprimir_tempo' is not definedA primeira linha da saída
11:37:59é impressa pela primeira linha de código,resultado = imprimir_tempo(11, 37, 59)que assinala o valor retornado porimprimir_tempoa variavelresultado. A segunda linha linha de c´dogio é o resultado do segundo print, que imprime o conteúdo da variávelresultado.
imprimir_tempo()não retorna um valor explicitamente comreturn, então automaticamente retornaNone.
Encapsulação
Preencha os brancos para criar uma função que recebe um único nome de arquivo como argumento, carrega os dados do arquivo, e retorna o comprimento da maior linha.
def detectar_tamanho_linha(____): with open(____) as f: dados = f.readlines() comprimentos = [] for linha em dados: comprimentos.append(____) maior_comprimento = max(____) return maior_comprimentoSolução
def detectar_tamanho_linha(arquivo): with open(arquivo) as f: dados = f.readlines() comprimentos = [] for linha em dados: comprimentos.append(len(linha)) maior_comprimento = max(comprimentos) return maior_comprimento
Encontre o Primeiro
Preencha os brancos para criar uma função que receba uma lista de números como argumento e imprima o primeiro valor negativo na lista. O que a sua função faz se a lista estiver vazia? E se a lista não tiver números negativos?
def primeiro_negativo(valores): for v in ____: if ____: return ____Solução
def primeiro_negativo(valores): for v in valores: if v < 0: return vSe uma lista vazia ou uma lista só com valores positivos for passada para essa função, ela retorna
None:minha_lista = [] print(primeiro_negativo(minha_lista))None
Encapsulando um bloco If/Else
O código abaixo vai imprimir etiquetas para ovos de galinha. Uma balança digital vai reportar a massa de um ovo (em gramas) para o computador e o computador precisa imprimir uma etiqueta.
Por favor reescreva o código abaixo para que o bloco de if seja dobrado em uma função.
import random for i in range(10): # simulando a massa de um ovo de galinha # o valor (aleatório) será de 70 +/- 20 gramas massa = 70 + 20.0 * (2.0 * random.random() - 1.0) print(massa) # a maquinaria de pesos de ovos imprime um valor if massa >= 85: print("jumbo") elif massa >= 70: print("grande") elif massa < 70 and massa >= 55: print("médio") else: print("pequeno")O programa simplificado está a seguir. Que definição de função o tornará funcional?
# versão revisada import random for i in range(10): # simulando a massa de um ovo de galinha # o valor (aleatório) será de 70 +/- 20 gramas massa = 70 + 20.0 * (2.0 * random.random() - 1.0) print(massa, calcular_etiqueta(massa))
- Crie uma definição de função para
calcular_etiqueta()que vai funcionar com o programa revisado acima. Note que o valor de retorno da funçãocalcular_etiqueta()será importante. Um exemplo de saída desse programa seria71.23 grande.- Um ovo sujo pode ter uma massa de mais de 90 gramas, e um ovo podre ou quebrado provavelmente vai ter uma massa menor que 50 gramas. Modifique sua função
calcular_etiqueta()para levar em conta essas condições de erro. Uma saída de exemplo poderia ser25 muito leve, algo de errado.Solução
def calcular_etiqueta(massa): # egg sizing machinery prints a label etiqueta_ovo = "sem etiqueta" if massa >= 90: etiqueta_ovo = "aviso: o ovo pode estar sujo" elif massa >= 85: etiqueta_ovo = "jumbo" elif massa >= 70: etiqueta_ovo = "grande" elif massa < 70 and massa >= 55: etiqueta_ovo = "médio" elif massa < 50: etiqueta_ovo = "muito leve, algo de errado" else: etiqueta_ovo = "pequeno" return etiqueta_ovo
Pontos-chave
Organize programas em funções para que sejam mais fáceis de entender.
Defina uma função usado
defcom um nome, parâmetros, e um bloco de código.Definir uma função não roda ela.
Argumentos em uma chamada correspondem aos parâmetros na definição.
Funções podem retornar um resultado para quem está chamando usando
return.