Per què funcions?
Una funció és un bloc de codi amb nom, que pots cridar des de diversos llocs del programa sense repetir-lo. Ajuda a organitzar el codi en trossos petits, cadascun amb una sola responsabilitat.
Definició i crida
Sintaxi
def nom_funcio(paràmetres):
# cos de la funció
Exemple
def saluda():
print("Hola des de la funció!")
saluda()
Definir una funció no l'executa: el seu cos només corre quan algú la crida, escrivint el seu nom seguit de parèntesis. Fixa't que, a diferència de C, no cal dir el tipus de res: ni dels paràmetres ni del que retorna.
Paràmetres amb valor per defecte
def saluda(nom="desconegut"):
print(f"Hola, {nom}!")
saluda() # Hola, desconegut!
saluda("Jordi") # Hola, Jordi!
Si no li passes aquest paràmetre, saluda fa servir el valor per defecte ("desconegut"). És una comoditat que C no té: allà, tots els paràmetres són sempre obligatoris.
Paràmetres: la funció rep el valor, no la variable
Quan passes una variable a una funció, dins la funció tens un nom nou (el paràmetre) amb aquell valor. Reassignar el paràmetre no toca la variable original.
Exemple
def incrementa(n):
n = n + 1
print(f"Dins de la funció: {n}")
x = 5
incrementa(x)
print(f"Fora de la funció: {x}")
La sortida és Dins de la funció: 6 i després Fora de la funció: 5 — exactament com en C. incrementa rep el valor de x (5) i el guarda en un nom propi, n; reassignar n no toca x per a res. Per intercanviar valors entre variables del cridant de debò (l'equivalent del que en C es fa amb apuntadors) caldrà una altra tècnica, que veurem més endavant.
return
Una funció pot retornar un valor amb return. return també talla l'execució de la funció a l'instant, encara que hi hagi més codi després.
Exemple
def quadrat(n):
return n * n
resultat = quadrat(6)
print(f"El quadrat de 6 és {resultat}")
Si una funció no té cap return, o en té un sense valor (return tot sol), en realitat retorna None — l'equivalent Python d'una funció void de C.
Funcions que en criden d'altres
Una funció pot cridar qualsevol altra funció ja definida, incloent-hi funcions que tu mateix has escrit.
def quadrat(n):
return n * n
def cub(n):
return quadrat(n) * n
cub no recalcula n * n: reaprofita quadrat. Quan una funció en crida una altra, l'execució "puja" a la nova funció i, quan aquesta acaba, torna exactament al punt on l'havies cridat.
Tuples
Una tupla és una seqüència de valors fixa: un cop creada, no se'n poden afegir, treure ni canviar elements (és immutable).
Exemple
punt = (3, 7) print(punt) x, y = punt print(x, y)
Pots desempaquetar-la directament en variables separades, com x, y = punt. De moment només la fem servir com a tipus de dada dins de l'script: no la passarem com a paràmetre ni la retornarem d'una funció — això té més sentit quan comparem amb els apuntadors de C.
Llistes
Una llista s'assembla a una tupla però és mutable: hi pots afegir, treure o canviar elements després de crear-la.
Exemple
notes = [7, 5, 9, 6]
suma = 0
for n in notes:
suma = suma + n
print(f"Mitjana: {suma / len(notes):.2f}")
len(notes) dona el nombre d'elements. notes.append(valor) n'afegeix un al final. Igual que amb les tuples, de moment treballarem les llistes sempre dins del mateix script, sense passar-les mai com a paràmetre d'una funció.
Aleatorietat
El mòdul random genera nombres pseudoaleatoris.
Exemple: simular un dau
import random
dau = random.randint(1, 6)
print(f"Has tret un {dau}")
random.randint(a, b) retorna un enter entre a i b, tots dos inclosos. També existeix random.choice(llista), que n'escull un element a l'atzar.
Un avantatge sobre C
A diferència del rand() de C, el mòdul random de Python fa servir sempre el mateix algorisme (Mersenne Twister) a qualsevol sistema operatiu: el resultat no depèn de si estàs a Linux o a Windows. Això sí, com que és aleatori de debò, als exercicis només et demanarem comprovar propietats (per exemple, que surti entre 1 i 6), mai un número concret.
Mira el programa executar-se pas a pas
Fixa't sobretot en com l'execució "salta" a la funció quan es crida, i "torna" exactament al punt de la crida quan s'acaba.
Funcions
Tuples i llistes
Aleatorietat
Codi
Variables
| Nom | Valor |
|---|
Terminal
Problemes per resoldre
Sense solució ni comprovació automàtica: escriu el programa, executa'l (python3 programa.py) i prova'l amb els exemples. Les funcions reben i retornen només valors simples; les llistes i tuples es queden sempre dins de l'script. Les pistes són plegades perquè les obris només si les necessites.
1. És parell?
Escriu una funció es_parell(n) que retorni True si n és parell i False si és senar. Demana un enter i mostra si és parell o senar fent servir aquesta funció.
Nombre: 7
És senar
Pistes
El cos pot ser una sola línia: return n % 2 == 0 — una comparació ja val True o False.
Crida la funció dins la condició d'un if: if es_parell(n):.
2. Any de traspàs
Escriu una funció es_traspas(any) que retorni True si l'any és de traspàs (divisible entre 4 però no entre 100, o bé divisible entre 400) i False si no. Prova-la amb diversos anys.
Any: 2024 És de traspàs Any: 1900 No és de traspàs
Pistes
És la mateixa condició que potser ja vas escriure al capítol de condicionals — ara la poses dins d'una funció que la retorna.
return (any % 4 == 0 and any % 100 != 0) or any % 400 == 0
3. Àrea d'un cercle
Escriu una funció area_cercle(radi) que retorni l'àrea d'un cercle d'aquest radi (àrea = π · radi²). Demana el radi i mostra el resultat amb 2 decimals.
Radi: 3
Àrea: 28.27
Pistes
Pots fer servir math.pi (amb import math) en lloc d'escriure el valor de π a mà.
No t'oblidis de convertir el que llegeixis amb input() a float.
4. Compta sisos
Escriu una funció tira_dau() que retorni un valor a l'atzar entre 1 i 6. Tira el dau 20 vegades i compta (amb una variable comptador, sense desar res més) quantes vegades ha sortit un 6.
Sisos en 20 tirades: 4
Pistes
tira_dau pot ser una sola línia: return random.randint(1, 6).
Només et cal una variable comptador que comenci a 0 i s'incrementi cada cop que tira_dau() == 6. Com que el resultat és aleatori, no hi ha un número "correcte": qualsevol valor entre 0 i 20 és un resultat vàlid.
5. La nota més alta
Demana 5 notes a l'usuari (una per una) i desa-les en una llista amb append(). Un cop tens les 5, mostra la nota més alta — sense fer servir la funció max().
Nota 1: 6 Nota 2: 9 Nota 3: 4 Nota 4: 9 Nota 5: 7 La nota més alta és: 9
Pistes
Comença amb una llista buida (notes = []) i afegeix-hi cada nota llegida amb notes.append(nota).
Per trobar el màxim a mà: guarda la primera nota com a candidata (alta = notes[0]) i recorre la resta de la llista amb un for, actualitzant alta cada cop que trobis una nota més gran.
Exercicis d'autoavaluació
Aquests sí que es generen amb valors nous a l'atzar i tenen solució comprovable (no fan servir random, perquè aquest mai dona un valor fix per comprovar).
Quina serà la sortida per terminal d'aquest programa?