Funções Recursivas, Funções Anônimas e Integradas, Módulos e Pacotes, Padrões de Desenvolvimento

Recursão e Busca Binária

1. Recursão

Uma função recursiva é aquela que chama a si mesma durante sua execução. Este mecanismo é útil para resolver problemas que podem ser divididos em subproblemas semelhantes.

# Chamada recursiva direta
def mostrar_mensagem():
    print('Olá do mundo recursivo')
    mostrar_mensagem()  # Chamada a si mesma

# Chamada recursiva indireta
def operacao_a():
    print('Operação A chamada')
    operacao_b()

def operacao_b():
    print('Operação B chamada')

# Para evitar loop infinito, deve-se ter uma condição de parada clara.
# A eficiência da recursão em Python é limitada; outras linguagens possuem otimizações como recursão de cauda.

Características e Cuidados com a Recursão:

1. É obrigatório ter uma condição de parada bem definida.
2. A cada chamada recursiva, o tamanho do problema deve diminuir.
3. Recursão profunda pode causar estouro de pilha (stack overflow), pois cada chamada adiciona um quadro à pilha.
# Python define um limite de profundidade recursiva. É possível verificar e ajustar este limite:
import sys
print(sys.getrecursionlimit())  # Profundidade padrão, ex: 1000
sys.setrecursionlimit(500)      # Altera a profundidade máxima

2. Busca Binária

A busca binária é um algoritmo eficeinte para localizar um elemento em uma lista ordenada, dividindo repetidamente o intervalo de busca pela metade.

lista_ordenada = [2, 5, 8, 12, 16, 23, 38, 45, 67, 89]
alvo = 23

def busca_binaria(dados, valor):
    if len(dados) == 0:
        return False
    
    meio = len(dados) // 2
    
    if dados[meio] == valor:
        return True
    elif valor < dados[meio]:
        return busca_binaria(dados[:meio], valor)
    else:
        return busca_binaria(dados[meio+1:], valor)

encontrado = busca_binaria(lista_ordenada, alvo)
print(f"Elemento {alvo} encontrado: {encontrado}")

Funções Anônimas (Lambda)

Funções aônimas, ou lambdas, são pequenas funções definidas sem um nome. Elas são frequentemente usadas para operações curtas e pontuais.

# Função anônima simples
dobrar = lambda x: x * 2
print(dobrar(5))  # Saída: 10

# Aplicações comuns com funções integradas:
pontuacoes = {'Ana': 85, 'Carlos': 92, 'Beatriz': 78, 'Daniel': 95}

# Encontrar a chave com o maior valor
melhor_aluno = max(pontuacoes, key=lambda chave: pontuacoes[chave])
print(f"Melhor aluno: {melhor_aluno}")

# Ordenar dicionário por valores
ordenado_por_nota = sorted(pontuacoes.items(), key=lambda item: item[1], reverse=True)
print("Ranking:", ordenado_por_nota)

# Transformar elementos de uma lista
frutas = ['maçã', 'banana', 'cereja']
frutas_com_preco = list(map(lambda fruta: f"{fruta}: R${len(fruta)*1.5:.2f}", frutas))
print(frutas_com_preco)

# Reduzir uma sequência a um único valor
from functools import reduce
numeros = [10, 20, 30, 40]
soma_total = reduce(lambda acumulador, x: acumulador + x, numeros, 0)
print(f"Soma total: {soma_total}")

# Filtrar elementos
notas = [65, 90, 45, 78, 88, 32, 95]
aprovados = list(filter(lambda nota: nota >= 70, notas))
print("Aprovados:", aprovados)

Funções Integradas (Built-in) do Python

Python possui um conjunto de funções integradas disponíveis globalmente, sem necessidade de importação.

# Funções matemáticas e de conversão:
print(abs(-15))          # Valor absoluto: 15
print(round(3.14159, 2)) # Arredondamento: 3.14
print(pow(2, 10))        # Potência: 1024
print(divmod(17, 5))     # Quociente e resto: (3, 2)

# Conversão de tipos:
texto_numero = "123"
numero = int(texto_numero)
print(type(numero))

# Operações em sequências:
lista = [5, 2, 8, 1, 9]
print(f"Máximo: {max(lista)}, Mínimo: {min(lista)}, Soma: {sum(lista)}")

# Verificação de tipos e booleanos:
print(isinstance(10, int))  # True
print(bool(0))              # False
print(all([True, 1, 'ok'])) # True
print(any([None, 0, '', []])) # False

# Manipulação de nomes e atributos:
class Exemplo:
    atributo = 42

obj = Exemplo()
print(hasattr(obj, 'atributo'))  # True
setattr(obj, 'novo_atributo', 100)
print(getattr(obj, 'novo_atributo')) # 100

Módulos e Pacotes

1. Módulos

Um módulo é um arquivo Python (extensão .py) que contém definições e instruções. A modularização ajuda a organizar o código e reutilizar funcionalidades.

# Conteúdo do arquivo 'calculadora.py'
def adicionar(a, b):
    return a + b

def subtrair(a, b):
    return a - b

# Utilizando o módulo em outro arquivo:
import calculadora

resultado = calculadora.adicionar(10, 5)
print(f"Resultado da adição: {resultado}")

# Importação seletiva com apelido:
from calculadora import adicionar as soma
print(f"Soma: {soma(7, 3)}")

# Importação de todos os nomes (usar com cautela):
from calculadora import *

2. Pacotes

Um pacote é um diretório que contém um arquivo especial __init__.py (opcional no Python 3, mas recomendado) e outros módulos ou subpacotes. Ele permite uma estrutura hierárquica.

# Estrutura de exemplo:
# meu_projeto/
# ├── __init__.py
# ├── modulo1.py
# └── subpacote/
#     ├── __init__.py
#     └── modulo2.py

# Dentro de modulo2.py:
def func_util():
    return "Função do subpacote"

# Para importar:
# importação absoluta
from meu_projeto.subpacote.modulo2 import func_util

# importação relativa (dentro do mesmo pacote)
# No arquivo modulo1.py, dentro de meu_projeto:
# from .subpacote.modulo2 import func_util

3. Caminhos de Busca

O Python procura módulos em: 1) Diretório atual, 2) Variável de ambiente PYTHONPATH, 3) Diretórios padrão de instalação.

import sys
# Visualizar e modificar o caminho de busca
print(sys.path)
sys.path.insert(0, '/caminho/para/meus/modulos')

Padrões de Desenvolvimento

Adotar uma estrutura de diretórios consistente melhora a manutenibilidade e colaboração em projetos.

# Estrutura de projeto típica:
meu_projeto/
│
├── bin/            # Scripts executáveis
│   └── iniciar.py
│
├── core/           # Lógica principal do aplicativo
│   ├── __init__.py
│   └── processos.py
│
├── conf/           # Arquivos de configuração
│   ├── settings.py
│   └── logging.ini
│
├── lib/            # Bibliotecas e utilitários auxiliares
│   ├── __init__.py
│   └── funcoes_aux.py
│
├── testes/         # Testes automatizados
│   └── test_processos.py
│
├── docs/           # Documentação
│   └── readme.md
│
└── db/             # Dados persistentes (se aplicável)

# Exemplo simplificado de inicialização (bin/iniciar.py):
import sys
import os

# Adiciona a raiz do projeto ao caminho
raiz_projeto = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, raiz_projeto)

from core.processos import main as executar_app
from conf import settings

if __name__ == '__main__':
    print(f"Iniciando com configuração: {settings.AMBIENTE}")
    executar_app()

Esta abordagem organiza o código em responsabilidades claras, facilitando testes, configuração e distribuição.

Tags: recursão função lambda módulos Python pacotes Python Algoritmos

Publicado em 6-13 21:51 por Thomas