El propòsit inicial dels computadors era computar números.
Introducció
Des de fa més de 400 anys una computadora era una persona que calculava números:
Una part de la teva infància ha estat aprenent a fer càlculs amb números, i molts cops t’has preguntat que perquè has d’aprendre aquestes coses si el teu mòbil té una calculadora que ho fa molt millor que tu.
El mateix van pensar les empreses, els governs i els enginyers, i per això van crear els primers computadors mecànics.
A continuació tens la imatge de l’ENIAC dels anys 40, molt gran, però molt menys potent que el teu mòbil:
A principis de 1960 ja existien les primeres calculadores comercials.
A continuació tens la imatge del IBM 608:
Aquestes màquines mai s’equivoquen, no es posen malaltes, no protesten, etc.
I el que passa sempre, ja pots despedir a molta gent que no necessites i que s’ha de pagar bé perqué preparar una calculadora “humana” porta molt de temps.
Una professió centenària va desaparèixer 😔.
Doncs comencem des del principi, i recorda ..
Encara que pensis que una computadora és per jugar, veure películes, etc. radera d’aquests programes hi ha moltes operacions matemàtiques!
Entorn de treball
Instal·la uv
tal com s’explica a UV
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
A continuació inicia l’intèrpret de Python en mode interactiu:
uv run python
Per sortir de l’interpret de Python escriu exit()
o Ctrl-D
:
>>> exit()
Números
Python és un llenguatge que fan servir els enginyers, científics i empreses.
Ells necessiten treballar amb números de manera fàcil i precisa sense haver d’estar sempre pendent de com funcionen en realitat els números en un computador.
Perquè si no treballes correctament amb els nombres d’un computador pots tenir un resultat erroni, i a tu et pot semblar que tampoc hi ha per tant, sobretot quan no estàs conforme amb el resultat d’una avaluació.
Però pots estar completament segur que a un enginyer o a un científic no pensarà el mateix.
Com que el tu també programes amb Python, també pots estar tranquil al respecte, però pensa que en altres llenguatges de programació la cosa no és tan fàcil.
El que fa funcionar un computador és la CPU, que té una ALU, i l’ALU té un circuit per processar operacions amb nombres enters (int
) i reals (float
).
Enters
Els enters són tots aquells números que no tenen decimals.
Per exemple:
- Un
2
és unint
- Un
2.0
és unfloat
.
Tots dos representen el mateix número, però no són el mateix:
>>> type(2)
<class 'int'>
>>> type(2.0)
<class 'float'>
Amb type
pots preguntar a Python que es cada cosa i ja veus que et diu que són de classe (class
) diferent.
Segur que endevines com es distingeix un int
d’un float
…
… el float
sempre té un .
al final i potser alguns números a continuació.
Així de fàcil, Python és un llenguatge pragmàtic:
>>> type(2.)
<class 'float'>
Si pots, és millor treballar amb enters (int
) perquè …
… les operacions amb nombres enters (int
) són més ràpides i els números mai tenen problemes de precisió.
Com hem explicat al principi del propòsit original d’un computador és fer operacions matemàtiques.
Els operadors +
, -
i *
s’utilitzen per realitzar operacions aritmètiques simples amb enters.
A continuació tens uns exemples:
>>> 2 + 2
4
>>> 3 - 6
-3
>>> 3 * 4
12
Si et fixes falta la divisió.
El motiu és que la majoria de les vegades el resultat de la divisió d’un nombre enter per un nombre enter no es pot representar amb un nombre enter si vols conservar la part dels decimals.
Per exemple, 5 / 2
és igual a 2.5
, i és un float
(un decimal) perquè té el punt.
La unitat d’enters de l’ALU no té implementat la divisió d’enters per aquest motiu tan obvi: només pot treballar i representar nombres enters.
El que fa Python en aquest cas es convertir els int
en float
i realitzar la divisió amb la unitat de floats de l’ALU.
I el resultat com es obvi sempre serà un float
tal com pots veure a continuació:
>>> 2 / 2
2.0
Potser pots pensar que:
-
És una mica absurd escriure un 2 com 2.0: Python afegeix el 2.0 perquè tinguis clar que el resultat és un
float
no unint
. -
Python podria ser més “intel·ligent” i tornar com a resultat un 2 (per tant, un
int
) en aquest cas concret: és una solució més fàcil, elegant, ràpida i predictible tornar sempre unfloat
.
Si només vols la part sencera d’una divisió pots utilitzar l’expressió //
i si vols la resta l’expressió %
:
>>> 8 // 6
1
>>> 8 % 6
2
Pots veure que el resultat sempre es un enter (int
).
Per calcular potències utilitza l’operador **
:
>>> 2 ** 2
4
>>> 2 ** 4
16
Amb l’ús de parèntesis ()
pots agrupar operacions per especificar un ordre explícit per resoldre-les:
>>> 2 + 3 * 4
14
>>> (2 + 3) * 4
20
Reals
Com ja deus saber els nombres enters són útils fins a cert punt.
Per això van inventar els nombres racionals, que segur no t’agraden massa, i els reals (o decimals) que t’agraden més perquè tu no fas les operacions sinó una calculadora.
Els nombres reals (float
) tenen problemes de precisió, però poden representar números amb decimals 🤔.
En qualsevol mena d’operació, si hi ha un float
pel mig, el resultat sempre és un float
!.
>>> 2 + 2.0
4.0
I l’operació s’executa en el circuit de floats de l’ALU.
El motiu és que un int
es pot representar amb més o menys precició com un float
, però al revés en la majoria de casos no és possible.
Per exemple, tens una préstec de 5000 euros al 5% d’interés.
Al final d’any quan m’has de pagar?
>>> 5000 * 0.05
250.0
Has de pagar 250 euros, o 250.0 euros en llenguatge d’ordinador, però si utilitzes llenguatge d’ordinador amb persones a la vida real pensaran que potser ets una mica …
Si decideixo representar 0.05 com un enter que escullo un 0 o un 1?
>>> 5000 * 0
0
>>> 5000 * 1
5000
Segur que tu prefereixes representar el 0.05 com un 0 i el banc com un 1.
El que fa Python, com és lògic i segur que ara estàs d’acord, és convertir 5000
en 5000.0
(un float
) i tornar el resultat com un float
.
I això ho fa sempre tal com demostra aquest exemple:
>>> 1 + 2.0
3.0
Per cert, per si de cas …
Totes les operacions que es fan amb enters també es fan amb reals: +
, -
, etc.
Variables
Una variable és un nom que ens permet guardar algún valor.
>>> x = 4 + 2
>>>
On està el resultat de l’operació que abans apareixia a continuació?
Doncs en lloc d’imprimir el resultat en pantalla, s’ha guardat a la variable x
:
>>> x
4
>>> x
4
I com sap Python que x
és una variable i no un número?
Doncs perquè Python no permet que el nom d’una variable comenci per un número:
>>> 3x = 3
File "<stdin>", line 1
3x = 3
^
SyntaxError: invalid decimal literal
>>>
I t’ho explica bé, però en anglès.
Si no entens el que posa, utilitza un traductor per traduir les explicacions de Python.
Però a part d’això, el nom de la variable pot tenir números:
>>> x3 = 3
>>> x3
3
Lògica de Python. Si la primera lletra és un número, doncs és un número, sinó és una variable.
>>> x3 + 2
5
>>> 3x + 2
File "<stdin>", line 1
3x + 2 ^
SyntaxError: invalid decimal literal
>>>
Segur que per tu 3x
no és un número, però per Python és un número mal escrit.
La gent pensa que els ordinadors són ximples quan fan coses com aquestes, en lloc de donar la raó a Python.
Com has vist en l’exemple d’abans una variable és pot utilitzar en operacions aritmètiques, i es fa servir el valor de la variable no pas el nom de la variable.
Ep! Això ja ho saps de matemàtiques.
>>> a = 3
>>> b = 5
>>> a + b + 4
12
I perquè li diem variable?
Doncs perquè el seu contingut no és fix, sinó que el pots modificar quan vulguis.
>>> x = 8
>>> x +2
10
>>> x = 20
>>> x + 2
22
>>> x = -4.0
>>> x + 2
-2.0
I quin ús tenen les variables?
Molts. Ara en veurem alguns.
Acumulador
Una variable va molt bé per anar acumulant els resultats de diverses operacions.
Per exemple, per saber la mitja de les notes dels alumnes.
Ja sé que les pots sumar totes de cop amb Python perquè caben perfectament a la pantalla de l’ordinador, i pots revisar que no t’has equivocat, però amb la calculadora del Windows no passa el mateix, per posar un exemple.
Com que ara ja has descobert que és més fàcil utilitzar Python que la calculadora …
>>> notes = 4.56 + 3.45 + 9.54 + 3.45 + 6.89 + 5.67
>>> notes
33.559999999999995
>>> notes = notes + 2.45 + 7.78 + 8.65 + 5.33 + 4.55
>>> notes
62.31999999999999
>>> notes = notes / 10
>>> notes
6.231999999999999
>>>
Tenim 10 alumnes, i la mitja de les notes de la classe és 6.232.
Però Python diu que la mitja és 6.231999999999999 no pas 6.232, i abans havies dit que Python no s’equivoca!
També et vaig dir que si podem és millor utilitzar int
s que float
s perquè els float
s tenen un lleuger problema de precisió com pots veure en aquest exemple.
A continuació repetirem el mateix exemple, però afegint una nota una a una:
>>> notes = 4.56
>>> notes = notes + 3.45
>>> notes = notes + 9.54
>>> notes
17.549999999999997
Però això és molt pesat d’escriure! Tens raó.
Com que és una operació molt habitual anar fent operacions amb una variable i guardar el resultat en la mateixa variable, enlloc de +
pots utilitzar l’operador +=
.
>>> notes += 6.89
>>> notes += 5.67
>>> notes /= 5
>>> notes
6.022
També hi ha l’operador =-
, =*
, etc.
A més de ser una sintaxi més curta expressa millor el que s’està fent.
Aquestes dues sentències fan el mateix, però la primera expressa millor el que s’està fent.
>>> x *= 3
>>> x = x * 3
Constant
Per calcular l’àrea d’un cercle has d’utilitzar la fòrmula πr²
, on r
és el radi del cercle i π
és el número Pi.
L’àrea d’un cercle de diàmetre 5 és …
>>> 3.141592653 * (5 ** 2)
78.539816325
Segur que recordes de memòria el número Pi i no t’importa escriure’l tantes vegades com sigui necessari.
Si hem de calcular moltes vegades l’àrea d’un cercle és millor guardar el nombre Pi en una variable, i utilitzar la variable en lloc del número.
>>> PI = 3.141592653
>>> PI * ( 2 ** 2)
12.566370612
>>> PI * ( 8 ** 2)
201.061929792 >>> PI * ( 13 ** 2)
530.929158357
D’aquesta manera és més fàcil i queda clar que PI
és un número amb un significat especial!
Si et fixes PI
està escrit en majúscules.
Els programadors de Python escriuen en majúscules aquelles variables que guarden coses que tenen valor per elles mateixes i que no s’han de modificar: les constants.
Per cert, Python distingeix entre majúscules i mínúscules.
Per tant, PI
i pi
no són el mateix:
>>> PI
3.141592653
>>> pi
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'pi' is not defined. Did you mean: 'PI'?
>>>
Llegibilitat
Quan escrius codi és normal posar espais perquè el codi sigui més llegible:
>>> 2 + 4
6
>>> x = 80
>>> x
80
Però a Python els espais tant li fa, els ignora!
Per ell totes aquestes sentències són el mateix:
>>> 2 + 4 + - 5
1
>>> 2+4+-5
1
>>> 2 + 4 + -5
1
Però per nosaltres l’última sentència és la més fàcil d’entendre.
Però hi ha una excepció!
Una sentència no pots començar amb espais en blanc:
>>> 3 + 3
File "<stdin>", line 1
3 + 3
IndentationError: unexpected indent
Ha Algoritme explicarem el motiu.
La llegibilitat és important entre altres coses perquè Python, igual que les matemàtiques, fa servir el mateix símbol per l’operació de resta que per indicar un nombre negatiu, el -
(igual passa amb +
).
String
A més de int
i float
, en Python també tenim el tipus str
.
str
és una seqüència de caràcters (lletres, números, espais en blanc, etc.) que no tenen cap significat per al programa i que es tracten com un bloc.
Quan Python troba un "
sap que el que ve a continuació no són instruccions, i quan troba el "
de tancament sap que ha acabat el text i ho guarda com un str
.
A continuació tens exemples de diferents str
s:
>>> type("hola")
<class 'str'>
>>> type("33")
<class 'str'>
>>> type("x")
<class 'str'>
>>> type("")
<class 'str'>
>>> type("En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga antigua, ...")
<class 'str'>
>>> type("こんにちは世界")
<class 'str'>
I l’str
ha d’acabar sempre amb "
, sinó Python diu que no, encara que per nosaltres sigui un string:
>>> type("barcelona
File "<stdin>", line 1
type("barcelona
^
SyntaxError: unterminated string literal (detected at line 1)
print f-string.
Amb la instrucció print, podem mostrar textos literals
:
print("Hola a tothom!")
I també els valors de variables
o constants
:
curs = "2024/2025"
LLICENCIA = "CC-BY-SA-4.O"
print("Hola 😊!")
print(curs)
print(LLICENCIA)
Resultat:
Hola 😊!
2024/2025
CC-BY-SA-4.0
Aquesta forma de mostrar els resultats és bona, però si volem mostrar literals i variables o constants en una sola línia, Python proporciona una tècnica més potent, els F-String (Format String).
Amb f-string
podem combinar literals i variables d’aquesta manera:
curs = "2024/2025"
nom = "Adriana"
print(f"Hola 😊! Benvinguda al curs {curs}, {nom}.")
Hola 😊! Benvinguda al curs 2024/2025, Adriana.
Quan posem print(f")
ja avisem a l’intèrpret que a part d’imprimir únicament literals o variables, formatarem la sortida per mostrar-ho tot en una mateixa sentència.
f-string també ens permet efectuar operacions numèriques, conversions de tipus, arrodoniments…
## Operacio amb f-string
print(f"2**10={2**10}")
## Conversió
memoriaGB = "12.7"
print(f"{float(memoriaGB)*1024} MB")
Resultat:
2**10=1024
13004.8 MB
Amb la funció float()
hem convertit el string
a nombre decimal.
Això és molt útil, ja que en moltes ocasions podem rebre les dades amb tipus string
encara que siguin float
i cal convertir-les si volem operar-les.
## Arrodoniment amb f-string
PI=3.141592653
print(f"{round(PI,4)}")
print(f"{PI:.4f}")
Resultat:
2**10=1024
13004.8 MB
Fixa’t que la instrucció print(f"{PI:.4f}")
fa el mateix que print(f"{round(PI,4)}")
.
Activitats
1.- Escriu aquesta sentència de manera que es puguin entendre fàcilment:
+4++6-+6+-10
+4 + +6 - +6 + -10
2.- Mostra el següent text, usant la tècnica de l’f-string i les següents variables:
Variables
usuari="usuari1"
espai=125.5999
Text: “L’usuari alumne1 té 125.60 MB d’espai lliure”
usuari="alumne1"
espai=125.5999
print(f"L'usuari {usuari} té {espai:.2f} MB d'espai lliure")
Errors
Quan estàs aprenent és molt important cometre errors de forma deliberada perqué d’aquesta manera t’ajuda a recordar el que estàs aprenent i, potser més important encara, aprens a entendre els missatges d’error. És millor cometre ara errors de manera deliberada que més tard sense voler.
També és molt important que entenguis els missatges d’error en anglés. Si tens problemes pots utilitzar el traductor de Google.
1.- NameError
>>> 2 * z
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'z' is not defined
La variable z
no existeix.
Si vols utilitzar la variable z
en una expressió, primer l’has de definir:
>>> z = 5
>>> 2 * z
10
2.- SyntaxError
>>> 03 + 4
File "<stdin>", line 1
03 + 4
^
SyntaxError: leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers
3.- ZeroDivisionError
>>> 4/(2+2+-4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero