Exercicios De Funções - Exercicios De Funçoes Do 1 Grau - FDPLEARN
Exercicios De Funçoes Do 1 Grau - FDPLEARN

Por onde começar com exercícios de funções

A maioria dos cursos empilha exercícios de funções no primeiro mês e espera que o aluno simplesmente decore a sintaxe enquanto resolve. Isso funciona até você se deparar com uma função que precisa retornar múltiplos valores ou com escopo de variável que não se comporta como você imagina. Na prática, o problema não é escrever o código. É entender o fluxo de dados.

exercícios de funções: o básico que todo mundo explica de forma confusa

Uma função é um bloco de código que recebe entradas, processa e devolve algo. Definição de livro didático. O que os materiais pouco dizem é que a maior armadilha dos iniciantes é confundir passagem por valor com passagem por referência, especialmente quando se lida com listas e dicionários em Python. Você passa uma lista, a função modifica o conteúdo original e não entende por quê. O segredo prático é saber distinguir mutáveis de imutáveis. Inteiros, strings e tuplas são imutáveis. Se você passar um inteiro para uma função e ela "alterar" esse valor, ela só modificou uma cópia local. Listas e dicionários são mutáveis. Alterações dentro da função refletem no objeto original. Eu levantei isso quando precisei debugar um sistema de cache que perdera dados aleatoriamente entre chamadas de função. A causa era exatamente essa: eu passava um dicionário e a função de processamento escrevia nele sem eu perceber, comprometendo o estado do cache em requisições subsequentes.

A solução foi clara. Em vez de deixar a função modificar o dicionário diretamente, eu forcei a criação de uma cópia com dict(origem) antes de processar. Isso isolou o estado e eliminou os efeitos colaterais invisíveis que estavam corrompendo dados em produção.

Como estruturar exercícios progressivos

Se você está montando sua própria trilha de exercícios de funções ou ensinando alguém, organize por complexidade crescente, não por assunto aleatório. O caminho natural é: Fase 1: funções puras sem side effects. Recebe um valor, calcula, retorna. Sem imprimir nada, sem escrever em arquivo, sem modificar variáveis globais. Exemplo simples: uma função que converte Celsius para Fahrenheit.

Fase 2: funções com parâmetros opcionais e *args, kwargs. Aqui o aluno aprende flexibilidade na assinatura. Um exercício realista seria criar uma função de cálculo de média que aceite número arbitrário de notas e um peso opcional para cada uma. Fase 3: funções recursivas. Recursão é o ponto onde a maioria trava. Comece com fatorial, depois Fibonacci, e só então problemas mais sofisticados como percorrer árvores de diretórios. O erro mais comum é esquecer a condição de parada ou criar uma recursão infinita silenciosa que estoura a pilha.

Fase 4: closures e funções de alta ordem. Funções que retornam outras funções. Isso parece complicado até você ver um exemplo prático como um decorador simples que mede o tempo de execução de qualquer função.

Erros comuns que eu vejo todo dia

O primeiro erro gritante é criar variáveis globas dentro de funções quando o correto seria passar tudo como parâmetro. Variáveis globais tornam o código impossível de testar de forma isolada. Se uma função depende de uma variável externa, você não consegue chamar ela sozinha num teste unitário sem montar um cenário artificial. O segundo erro é confundir return com print. Um exercício bem feito exige que a função retorne o valor e o código de chamada é quem decide exibir. Quando o aluno coloca print dentro da função, ele prende a lógica à saída em tela e quebra a reusabilidade.

O terceiro erro, e esse é sutil, é não validar entradas. Uma função que recebe uma string e tenta calcular seu comprimento usando um índice negativo sem verificar o tipo pode falhar silenciosamente ou levantar exceções feias. Colocar validação no início é trabalho extra, mas poupa horas de debug.

👉 Clique no botão abaixo para saber mais sobre o assunto!

Um caso prático que ninguém ensina direito

Exercícios de funções frequentemente ignoram o cenário real onde você precisa processar dados sujos. Imagine uma função que recebe uma lista de números separados por vírgula em strings, como "10,20,30" e "não é número", e precisa calcular a soma dos valores válidos. Se você simplesmente chamar int() em tudo, o programa quebra na primeira string inválida. O workaround que eu adotei foi criar uma função auxiliar parse_numero(valor) que tenta converter e retorna None em caso de falha. A função principal filtra os None antes de somar. Dessa forma, dados ruins não derrubam o processamento e você ainda consegue contar quantos registros foram ignorados, o que é informação útil para relatórios de qualidade de dados.

Recursos e onde encontrar mais exercícios

Para praticar exercícios de funções de forma consistente, o site HackerRank tem uma seção específica de Python functions que cobre desde níveis básicos até questões avançadas de map, filter e reduce. O LeetCode também oferece problemas classificados por dificuldade, muitos dos quais exigem implementação de funções recursivas ou com parâmetros variádicos. Se preferir material em português, o curso gratuito do Curso em Vídeo do Gustavo Guanabara tem uma playlist completa sobre funções em Python, com exemplos práticos e exercícios resolvidos passo a passo. É um conteúdo gratuito que você pode acessar diretamente pelo YouTube sem precisar pagar assinatura.

Para quem quer algo mais técnico, o livro "Fluent Python" do Luciano Ramalho traz capítulos inteiros sobre funções como cidadãos de primeira classe, abordando tópicos como *args, kwargs, closures, decorators e tipagem com mypy. Não é um livro de exercícios no sentido tradicional, mas os exemplos práticos são mais próximos do que você encontra no dia a dia de desenvolvimento profissional.

Quando exercícios de funções não são suficientes

Resolver apenas exercícios de funções isoladas cria uma visão distorcida. No mundo real, funções raramente vivem sozinhas. Elas compõem classes, são chamadas em pipelines assíncronos, sofrem versionamento e precisam de logs. Se seu único treino for escrever funções solitárias numa IDE local, você leva tempo para entender como elas se encaixam em projetos maiores. Uma alternativa recomendada é pegar um exercício simples e refatorá-lo três vezes. Primeira versão: função pura. Segunda versão: adicione logging e tratamento de exceções. Terceira versão: transforme em uma classe com métodos, se fizer sentido. Esse exercício de refatoração ensina mais do que cinquenta funções novas escritas do zero.

Também vale a pena implementar testes. Para cada função que você resolver, escreva três casos de teste: entrada normal, entrada borda e entrada inválida. Se a função não passar pelos três, ela ainda não está pronta. Testes automatizados com pytest são leves de configurar e te dão feedback imediato sobre regressões.

Dicas práticas de performance

Funções em Python têm um custo de call que pode somar em loops apertados. Se você está processando milhões de registros, uma função mal desenhada pode adicionar segundos desnecessários ao total. Uma otimização comum é usar functools.lru_cache para memoizar funções puras com entrada repetida. Isso transforma uma recursão ingênua de Fibonacci de complexidade exponencial em linear, sem mudar a lógica do algoritmo. Outro ponto é evitar chamadas de função dentro de loops internos quando o mesmo cálculo pode ser movido para fora. Uma função que determina se um número é primo chamada milhares de vezes dentro de uma lista compreensiva pode ser substituível por uma verificação direta ou por um pré-processamento em lote.

Se o exercício exige alta performance, considere também usar Numba ou Cython para JIT compilar funções críticas. Essas ferramentas são overkill para a maioria dos exercícios acadêmicos, mas fazem diferença real em pipelines de dados industriais onde o tempo de execução é métrica de negócio.

Resumo sem resumo

Exercícios de funções são fundamentais, mas o aprendizado real acontece quando você confronta edge cases, efeitos colaterais e a necessidade de escrever código testável. A prática constante com problemas progressivos, combinada com revisão de erros comuns e foco em qualidade desde o início, transforma quem está começando num desenvolvedor capaz de escrever funções que funcionam tanto num script local quanto num sistema de produção.