Laboratório de Programação — Ciência da Computação • UFPI
Blocos reutilizáveis de código — definição, parâmetros, retorno, recursão, escopo e passagem de argumentos — com syntax highlighting
def saudacao(nome):
print("Olá,", nome + "!")
saudacao("Maria") # Saída: Olá, Maria!
def soma(a, b):
return a + b
resultado = soma(3, 5) # posicionais
resultado = soma(a=3, b=5) # nomeados (keyword)
def area_retangulo(largura, altura=1):
return largura * altura
area_retangulo(5) # 5 (altura usa padrão 1)
area_retangulo(5, altura=2) # 10
def dividir(a, b):
if b == 0:
return None
return a / b
q = dividir(10, 2) # 5.0
def estatisticas(valores):
return min(valores), max(valores), sum(valores)/len(valores)
mn, mx, media = estatisticas([6.5, 7.0, 8.3])
param=valordef soma_tudo(*args):
return sum(args)
def imprimir_config(**kwargs):
for k, v in kwargs.items():
print(k, "=", v)
soma_tudo(1,2,3) # 6
imprimir_config(tema="claro", idioma="pt-BR")
def power(base, exp, /, modulo=None, *, arredonda=False):
# '/' marca parâmetros somente posicionais;
# '*' marca parâmetros somente nomeados.
r = base ** exp
if modulo is not None:
r %= modulo
return round(r) if arredonda else r
power(2, 3, 5) # ok (posicionais + opcional)
power(2, 3, modulo=5) # ok (nomeado)
# power(base=2, exp=3) # ERRO: base/exp são somente posicionais
# power(2, 3, True) # ERRO: 'modulo' é somente nomeado
dobro = lambda x: x * 2
print(dobro(4)) # 8
Úteis para operações simples (ex.: key= em sorted, map, filter).
def fatorial(n):
'''Calcula o fatorial de n (n!).'''
if n == 0:
return 1
return n * fatorial(n-1)
print(fatorial.__doc__) # exibe a docstring
Uma função que chama a si mesma para resolver subproblemas.
def fatorial(n):
if n == 0: # caso base
return 1
return n * fatorial(n-1) # caso recursivo
print(fatorial(5)) # 120
def fibonacci(n):
if n == 0 or n == 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(5)) # 5
Observação: esta versão é exponencial; prefira memoization ou iteração.
from functools import lru_cache
@lru_cache(maxsize=None)
def fib_memo(n):
if n < 2:
return n
return fib_memo(n-1) + fib_memo(n-2)
len, print…)x = 20 # global
def minha_funcao():
y = 10 # local
print(y, x)
minha_funcao() # 10 20
# print(y) # NameError: y não existe aqui
x = 10
def altera():
global x
x = 20
altera()
print(x) # 20
def outer():
msg = "outer"
def inner():
nonlocal msg
msg = "inner"
inner()
return msg
print(outer()) # "inner"
x = "global"
def outer():
x = "outer"
def inner():
x = "inner"
print(x) # inner
inner()
print(x) # outer
outer()
print(x) # global
Modelo do Python: passagem por objeto (também chamado de pass-by-assignment).
def dobrar_numero(x):
x = x * 2
print("Dentro:", x)
n = 5
dobrar_numero(n)
print("Fora:", n) # 5
def adicionar_elemento(lst):
lst.append(4)
val = [1, 2, 3]
adicionar_elemento(val)
print(val) # [1, 2, 3, 4]
def acumular(item, colecao=[]): # NÃO recomendado
colecao.append(item)
return colecao
print(acumular(1)) # [1]
print(acumular(2)) # [1, 2] (surpresa!)
# Forma correta
def acumular_ok(item, colecao=None):
if colecao is None:
colecao = []
colecao.append(item)
return colecao
global; passe dados por parâmetros e retornos.# Definir: def nome(params): ...; return valor
# Chamar: nome(args); nome(param=valor)
# Padrão: def f(a, b=0): ...
# *args/**kwargs: coletores de argumentos
# Docstring: def f(): \"\"\"Descrição.\"\"\"
# Recursão: ter caso base + caso recursivo
# Escopo: LEGB; use global/nonlocal com parcimônia
# Passagem: por objeto; imutáveis vs mutáveis
def normalizar(nomes):
return [n.strip().title() for n in nomes]
def filtrar(nomes, minimo=3):
return [n for n in nomes if len(n) >= minimo]
def pipeline(nomes):
return filtrar(normalizar(nomes), minimo=4)
dados = [" ana", "rui ", " mariana", "jo"]
print(pipeline(dados)) # ['Ana', 'Rui', 'Mariana']