Capítulo 5 — Funções
Até agora, seus programas cresceram bastante: trabalham com variáveis, tomam decisões com if e repetindo tarefas com for e while. Mas, conforme os programas ficam mais longos, começamos a notar um problema incômodo: código repetido. Você escreve a mesma sequência de comandos várias vezes. E toda vez que quer mudar algo naquele pedaço de código, precisa mudar em todos os lugares.
As funções existem para resolver exatamente esse problema. Uma função é como uma receita: você define uma vez, "para fazer um bolo, misture farinha, ovo, leite...", e depois, toda vez que quer um bolo, você chama a receita em vez de repetir todos os passos. E se a receita mudar — "a gente vai usar chocolate agora" — você muda uma vez, e a mudança vale para todos os bolos que você fizer daqui em diante.
Neste capítulo, vamos aprender a criar nossas próprias funções e a usá-las para deixar nossos programas mais organizados, mais fáceis de manter e bem mais profissionais.
1. Por que criar funções?
O problema: repetição de código
Imagine que você quer desenhar vários quadrados com o Turtle em posições diferentes. Sem funções, seu código fica assim:
import turtle
t = turtle.Turtle()
# Desenha quadrado 1
t.forward(100)
t.left(90)
t.forward(100)
t.left(90)
t.forward(100)
t.left(90)
t.forward(100)
t.left(90)
# Desenha quadrado 2 (aqui está o mesmo código de novo!)
t.forward(100)
t.left(90)
t.forward(100)
t.left(90)
t.forward(100)
t.left(90)
t.forward(100)
t.left(90)
# Desenha quadrado 3 (e de novo!)
t.forward(100)
t.left(90)
t.forward(100)
t.left(90)
t.forward(100)
t.left(90)
t.forward(100)
t.left(90)
turtle.done()
Que desperdício! O mesmo código se repete. Se você quisesse mudar o tamanho para 80 pixels, teria que mudar em três lugares. Se tivesse 100 quadrados, ficaria incontrolável.
A analogia: função como receita
Uma receita de bolo é perfeita como analogia:
- Receita: você escreve uma vez como fazer um bolo
- Ingredientes são como parâmetros — você pode fazer um bolo de chocolate, outro de baunilha, e a receita se adapta
- Resultado (um bolo pronto) é como o retorno — você faz algo e fica com algo em troca
- Usar a receita é como chamar a função — quantas vezes quiser, sem reescrever tudo
Funções que já usamos
Na verdade, você já está usando funções o tempo todo! print(), input(), len(), range() — tudo isso são funções. O Python fornece essas funções prontas. Agora vamos aprender a criar as nossas.
# Todas essas são funções que já conhecemos:
print("Olá!") # função print()
nome = input("Seu nome: ") # função input()
tamanho = len("Python") # função len()
for i in range(5): # função range()
print(i)
A diferença agora é que vamos escrever nossas próprias funções, feitas especialmente para o que a gente precisa.
2. Definindo funções com def
A palavra-chave def ("definir") é como você diz ao Python: "quero definir uma função". Vamos ver a sintaxe:
Sintaxe básica
def nome_da_funcao():
# código que executa quando a função é chamada
# precisa estar indentado (4 espaços)
Três coisas importantes:
- A palavra
defcomeça a definição nome_da_funcaoé o nome que você escolhe — pode ser qualquer coisa (mas tem regras: sem espaços, sem caracteres especiais)- Os dois-pontos (
:) marcam o início do bloco da função - O código dentro da função precisa estar indentado (com 4 espaços)
Seu primeiro programa com função
def saudacao():
print("Olá, bem-vindo!")
print("Como vai?")
# Aqui a função foi DEFINIDA, mas ainda não foi EXECUTADA
# Para executar, você precisa chamar:
saudacao() # primeira chamada
saudacao() # segunda chamada — executa tudo de novo!
saudacao() # terceira — mesmo resultado
Quando você escreve saudacao() com os parênteses, está chamando a função. O Python vai para dentro da função, executa tudo que está indentado, e volta.
A saída será:
Olá, bem-vindo!
Como vai?
Olá, bem-vindo!
Como vai?
Olá, bem-vindo!
Como vai?
Diferença entre definir e chamar
Observe bem a indentação:
def desenhaquadrado():
t.forward(100) # ← dentro da função (indentado)
t.left(90) # ← dentro da função
t.forward(100) # ← dentro da função
t.left(90) # ← dentro da função
t.forward(100) # ← dentro da função
t.left(90) # ← dentro da função
t.forward(100) # ← dentro da função
t.left(90) # ← dentro da função
desenhaquadrado() # ← fora da função, chamando ela
desenhaquadrado() # ← chama de novo
Linhas indentadas dentro da definição são parte da função. Linhas sem indentação estão fora — são o programa principal.
Um exemplo com Turtle
import turtle
t = turtle.Turtle()
def desenha_quadrado():
t.forward(100)
t.left(90)
t.forward(100)
t.left(90)
t.forward(100)
t.left(90)
t.forward(100)
t.left(90)
# Agora em vez de copiar-colar, você chama a função:
desenha_quadrado() # Desenha um quadrado
t.forward(50) # Anda um pouco
desenha_quadrado() # Desenha outro quadrado
t.forward(50) # Anda de novo
desenha_quadrado() # Desenha mais um
turtle.done()
Muito melhor! E se você quiser mudar o tamanho do quadrado, muda uma vez dentro da função, e todos os três ficam com o novo tamanho.
3. Parâmetros e argumentos
O que é um parâmetro?
Até agora, nossas funções fazem sempre a mesma coisa. Mas e se quisermos que uma função faça coisas diferentes dependendo da situação? Para isso, usamos parâmetros.
Um parâmetro é uma variável que você declara na definição da função. Um argumento é o valor que você passa quando chama a função. A diferença é pequena, mas importante:
- Parâmetro: está na definição (o "design" da receita)
- Argumento: está na chamada (o valor que você passa quando usa a receita)
Função com um parâmetro
def saudacao(nome): # 'nome' é o parâmetro
print(f"Olá, {nome}!")
print(f"Bem-vindo, {nome}!")
# Quando chama, passa um argumento:
saudacao("Ana") # "Ana" é o argumento
saudacao("Bruno") # "Bruno" é o argumento
saudacao("Carlos") # "Carlos" é o argumento
A saída será:
Olá, Ana!
Bem-vindo, Ana!
Olá, Bruno!
Bem-vindo, Bruno!
Olá, Carlos!
Bem-vindo, Carlos!
O valor que você passa ("Ana", "Bruno", etc.) é automaticamente armazenado na variável nome enquanto a função executa. Depois a função termina, e a variável desaparece (veremos mais sobre isso quando falarmos de escopo).
Função com múltiplos parâmetros
Você pode ter quantos parâmetros quiser:
def saudacao_completa(nome, idade, cidade):
print(f"Olá, {nome}!")
print(f"Você tem {idade} anos e mora em {cidade}.")
saudacao_completa("Ana", 16, "São Paulo")
saudacao_completa("Bruno", 15, "Rio de Janeiro")
Saída:
Olá, Ana!
Você tem 16 anos e mora em São Paulo.
Olá, Bruno!
Você tem 15 anos e mora em Rio de Janeiro.
Atenção: a ordem importa! O primeiro argumento vai para o primeiro parâmetro, o segundo para o segundo, e assim por diante. Se você chamar saudacao_completa("São Paulo", "Ana", 16), os valores ficariam completamente bagunçados.
Exemplo prático: Turtle com parâmetros
import turtle
t = turtle.Turtle()
def desenha_quadrado(tamanho):
# Desenha um quadrado de qualquer tamanho
for i in range(4):
t.forward(tamanho)
t.left(90)
# Agora você pode desenhar quadrados de diferentes tamanhos:
desenha_quadrado(100)
t.forward(50)
desenha_quadrado(80)
t.forward(50)
desenha_quadrado(50)
turtle.done()
Repare que usamos um for dentro da função — isso é perfeitamente normal! E o tamanho é uma variável normal dentro da função, serve exatamente como qualquer outra.
Valores padrão (default)
Às vezes você quer que um parâmetro tenha um valor "padrão" — se o usuário não passar nada, usa aquele valor. Por exemplo:
def saudacao(nome, palavra="Olá"):
print(f"{palavra}, {nome}!")
saudacao("Ana") # Usa "Olá" como padrão
saudacao("Bruno", "Oi") # Muda para "Oi"
saudacao("Carlos", "Bom dia") # Muda para "Bom dia"
Saída:
Olá, Ana!
Oi, Bruno!
Bom dia, Carlos!
O parâmetro com valor padrão é marcado com =. Se você passa um argumento, ele sobrescreve o padrão. Se não passa, usa o valor padrão.
Regra importante: parâmetros com valores padrão sempre vêm por último na lista de parâmetros. Você não pode ter um parâmetro obrigatório depois de um opcional:
# ERRADO — sintaxe inválida
def algo(a=10, b):
print(a + b)
# CORRETO — opcional vem por último
def algo(b, a=10):
print(a + b)
4. Retornando valores com return
Funções que retornam vs. funções que executam
Até agora, nossas funções executam algo (como imprimir ou desenhar), mas não nos devolvem nada. Tem funções do Python que fazem isso — por exemplo, len() não só executa, ela também retorna um valor que você pode guardar:
comprimento = len("Python") # len() retorna um número que você guarda em 'comprimento'
print(comprimento) # 6
Você pode fazer isso com suas próprias funções usando return.
Sintaxe e exemplo
def dobra(numero):
resultado = numero * 2
return resultado
resposta = dobra(5) # dobra() executa, calcula, e RETORNA 10
print(resposta) # 10
return é a palavra que diz: "função, sua tarefa acabou, aqui está o resultado que você deveria retornar". Quando uma função encontra return, ela para de executar e devolve o valor.
Exemplo prático: conversor de temperatura
def celsius_para_fahrenheit(celsius):
fahrenheit = (celsius * 9/5) + 32
return fahrenheit
# Usa o valor retornado:
temp_f = celsius_para_fahrenheit(25)
print(f"25°C = {temp_f}°F") # 25°C = 77.0°F
temp_f_negativa = celsius_para_fahrenheit(-40)
print(f"-40°C = {temp_f_negativa}°F") # -40°C = -40.0°F
Retornando múltiplos valores (tuplas)
Python permite que você retorne mais de um valor ao mesmo tempo usando uma tupla (vamos estudar tuplas e listas no capítulo 6, mas aqui é só uma introdução):
def dividi_nome(nome_completo):
partes = nome_completo.split(" ") # separa pelo espaço
primeiro_nome = partes[0]
ultimo_nome = partes[-1]
return primeiro_nome, ultimo_nome
nome1, nome2 = dividi_nome("Ana Silva")
print(f"Primeiro: {nome1}, Último: {nome2}") # Primeiro: Ana, Último: Silva
Quando você escreve return a, b, o Python retorna os dois valores juntos como uma tupla. E quando você recebe com x, y = funcao(), está "desempacotando" a tupla.
5. Escopo de variáveis (introdução)
Variáveis locais vs. globais
Uma coisa importante de entender é que as variáveis dentro de uma função pertencem àquela função. Quando a função termina, essas variáveis "desaparecem". Chamamos isso de variável local — local quer dizer "pertence apenas a este lugar".
def calcula_imposto(preco):
imposto = preco * 0.1 # 'imposto' é uma variável LOCAL
return imposto
resultado = calcula_imposto(100)
print(resultado) # 10.0 — funciona!
print(imposto) # ERRO! 'imposto' não existe fora da função
Se você tentar acessar imposto fora da função, o Python dará um erro dizendo que a variável não existe. Isso é na verdade uma coisa boa, porque evita confusão.
Compare com variáveis globais — variáveis que você define fora de qualquer função:
taxa = 0.1 # Variável GLOBAL — existe em todo o programa
def calcula_imposto(preco):
return preco * taxa # Pode acessar 'taxa' porque é global
print(calcula_imposto(100)) # 10.0
Aqui taxa é global, então a função consegue acessá-la.
Por que evitar variáveis globais
Parece fácil usar variáveis globais, mas é uma péssima prática. Imagine um programa grande:
# PROBLEMA — evite assim!
contador = 0
def incrementa():
contador = contador + 1 # Quer usar 'contador' global
return contador
print(incrementa()) # Erro!
Isso dá erro! Quando você escreve contador = contador + 1 dentro da função, Python entende que contador é uma variável local, não global. Mas então você tenta ler contador antes dela existir — erro!
A forma correta de fazer isso seria:
# CORRETO — passar como parâmetro e retornar
def incrementa(contador):
contador = contador + 1
return contador
valor = 0
valor = incrementa(valor)
print(valor) # 1
valor = incrementa(valor)
print(valor) # 2
Ou guardar o valor em uma variável e atualizar:
contador = 0
def incrementa():
return contador + 1
contador = incrementa()
print(contador) # 1
Regra prática: funções recebem dados através de parâmetros e devolvem resultados através de return. Evite usar variáveis globais. Deixa o código mais limpo, mais seguro e mais fácil de entender.
6. Prática com Turtle e funções
Agora vamos combinar funções com Turtle para criar desenhos bem legais!
6.1. Função desenha_quadrado com parâmetros
import turtle
t = turtle.Turtle()
t.speed(5)
def desenha_quadrado(tamanho, cor):
t.color(cor)
for i in range(4):
t.forward(tamanho)
t.left(90)
# Desenha vários quadrados de tamanhos e cores diferentes
desenha_quadrado(100, "red")
t.forward(120)
desenha_quadrado(80, "blue")
t.forward(100)
desenha_quadrado(60, "green")
turtle.done()
6.2. Função desenha_triangulo
import turtle
t = turtle.Turtle()
t.speed(5)
def desenha_triangulo(tamanho, cor):
t.color(cor)
for i in range(3):
t.forward(tamanho)
t.left(120) # ângulo externo do triângulo é 120°
desenha_triangulo(100, "purple")
t.forward(120)
desenha_triangulo(80, "orange")
turtle.done()
6.3. Função desenha_casa (combinando outras funções)
import turtle
t = turtle.Turtle()
t.speed(5)
def desenha_quadrado(tamanho, cor):
t.color(cor)
for i in range(4):
t.forward(tamanho)
t.left(90)
def desenha_triangulo(tamanho, cor):
t.color(cor)
for i in range(3):
t.forward(tamanho)
t.left(120)
def desenha_casa(tamanho_base, cor_parede, cor_telhado):
# Paredes (quadrado)
desenha_quadrado(tamanho_base, cor_parede)
# Repositiona para desenhar o telhado
t.penup()
t.goto(t.xcor(), t.ycor() + tamanho_base)
t.pendown()
# Telhado (triângulo)
desenha_triangulo(tamanho_base, cor_telhado)
# Desenha uma casa
desenha_casa(100, "brown", "red")
turtle.done()
6.4. Criando uma vila com a função
import turtle
t = turtle.Turtle()
t.speed(5)
def desenha_quadrado(tamanho, cor):
t.color(cor)
for i in range(4):
t.forward(tamanho)
t.left(90)
def desenha_triangulo(tamanho, cor):
t.color(cor)
for i in range(3):
t.forward(tamanho)
t.left(120)
def desenha_casa(tamanho_base, cor_parede, cor_telhado):
desenha_quadrado(tamanho_base, cor_parede)
t.penup()
t.goto(t.xcor(), t.ycor() + tamanho_base)
t.pendown()
desenha_triangulo(tamanho_base, cor_telhado)
# Desenha várias casas em posições diferentes
for i in range(3):
desenha_casa(60, "brown", "red")
t.penup()
t.forward(100)
t.pendown()
turtle.done()
6.5. Função desenha_flor com pétalas
import turtle
t = turtle.Turtle()
t.speed(5)
def desenha_circulo(raio, cor):
t.color(cor)
t.begin_fill()
t.circle(raio)
t.end_fill()
def desenha_flor(raio_petal, numero_petalas, cor_petal, cor_centro):
# Desenha as pétalas em volta
angulo_entre_petalas = 360 / numero_petalas
for i in range(numero_petalas):
desenha_circulo(raio_petal, cor_petal)
t.penup()
t.goto(0, 0) # volta ao centro
t.pendown()
t.left(angulo_entre_petalas) # rotaciona para a próxima pétala
# Desenha o centro
desenha_circulo(raio_petal // 2, cor_centro)
# Desenha uma flor com 6 pétalas
desenha_flor(30, 6, "pink", "yellow")
turtle.done()
7. Exercícios
a) Escreva uma função saudacao(nome) que recebe o nome de uma pessoa e retorna (com return) uma string de boas-vindas, tipo "Bem-vindo, Ana!". Teste chamando a função e imprimindo o resultado.
b) Crie duas funções:
- area_retangulo(largura, altura) — retorna a área
- perimetro_retangulo(largura, altura) — retorna o perímetro
Teste com um retângulo de 5 por 10 e exiba ambos os resultados.
c) Escreva uma função eh_par(numero) que retorna True se o número for par, False caso contrário. Teste com números de 1 a 20 e exiba quantos são pares.
d) Com o Turtle, crie uma função desenha_poligono(lados, tamanho, cor) que desenha um polígono regular de quantos lados você quiser. Dica: o ângulo externo é 360 / lados. Teste com triângulo, quadrado, pentágono e hexágono.
e) Escreva as funções celsius_para_fahrenheit(celsius) e fahrenheit_para_celsius(fahrenheit). Teste convertendo 0°C, 100°C e 32°F.
f) Crie uma função conta_vogais(texto) que recebe uma string e retorna quantas vogais (a, e, i, o, u) tem. Ignore maiúsculas/minúsculas. Teste com frases diferentes.
g) Com o Turtle, crie uma função desenha_estrela(pontas, tamanho, cor) que desenha uma estrela com o número de pontas que você quiser. Uma estrela de 5 pontas tem ângulo de 144° entre os vértices. Teste desenhando uma estrela de 5 e outra de 8 pontas.
h) Escreva uma função valida_senha(senha) que retorna True se a senha tem no mínimo 8 caracteres e contém pelo menos um número. Caso contrário, retorna False. Teste com várias senhas.
i) Com o Turtle, crie:
- desenha_arvore(altura) — desenha uma árvore simples (tronco + copa)
- desenha_sol() — desenha um sol amarelo
Depois crie uma paisagem chamando essas funções em posições diferentes.
j) Escreva uma função maior_de_tres(a, b, c) que retorna o maior dos três números sem usar a função max(). Teste com vários trios de números.
8. Desafio de capítulo: Gerador de senhas aleatórias
Crie um programa que gera senhas aleatórias conforme o usuário pedir. O programa deve:
- Definir uma função
gera_senha(tamanho, usar_numeros=True, usar_simbolos=False)que: - Retorna uma senha aleatória do tamanho desejado
- Se
usar_numerosforTrue, inclui números (0-9) - Se
usar_simbolosforTrue, inclui símbolos (!@#$%&*) - Sempre inclui letras (maiúsculas e minúsculas)
-
Usa
import randompara escolher caracteres aleatoriamente -
Pedir ao usuário:
- O tamanho desejado da senha
- Se quer números (s/n)
-
Se quer símbolos (s/n)
-
Gerar 3 opções de senha conforme pedido
-
Deixar o usuário copiar a que gostar mais
Exemplo de saída:
=== Gerador de Senhas ===
Qual tamanho? 12
Incluir números? (s/n) s
Incluir símbolos? (s/n) n
Opção 1: aBcD3efG9hIj
Opção 2: XyZ7mNoPq2Rs
Opção 3: tUvW5wxYz1Ab
Copie a senha que você gostou!
Dicas:
- Crie uma string com todos os caracteres possíveis (letras + números + símbolos)
- Use random.choice(string_de_caracteres) para escolher um caractere aleatório
- Use um for para gerar tamanho caracteres e montar a senha
- Teste gerando senhas com várias combinações de opções
Resumo do capítulo
Você aprendeu que:
- Funções eliminam repetição de código
- Parâmetros deixam funções flexíveis e reutilizáveis
- Return faz uma função devolver um valor para o programa principal
- Variáveis locais são seguras e deixam o código mais organizado
- Combinar funções com Turtle cria desenhos incríveis e reutilizáveis
No próximo capítulo (Estruturas de dados: Listas e Strings), você vai aprender a trabalhar com coleções de dados — múltiplos valores guardados em um único lugar. Isso vai deixar seus programas ainda mais poderosos!