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 acomiadar 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·lícules, etc. darrere 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
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 és 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 efectuar 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 és convertir els int
en float
i realitzar la divisió amb la unitat de floats de l’ALU.
I el resultat com és 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 és 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 precisió com un float
, però al revés en la majoria de casos no és possible.
El que fa Python, com és lògic i segur que ara estàs d’acord, és convertir e
en 2.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 int
s també es fan amb float
s: +
, -
, etc.
I que passa si vull convertir un float
en un int
?
Doncs tens tot el dret a fer-ho, només cal utilitzar l’operador int()
:
>>> int(1.34)
1
I si sumen dos int
, el resultat és un int
:
>>> 1 + int(2.0)
3
Variables
Una variable és un nom que ens permet guardar algun 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, si no é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 per què 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 Python - 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
.
>>> "Hello, World!"
'Hello, World!'
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 "
, si no 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)
Un string també es pot escriure amb cometes simples:
'La foscor desvetlla camins que ningú veu'
A python li és indiferent, és qüestió d’estil personal, encara que aquí preferim les cometes dobles perquè molts cops hem d’utilitzar '
en escriure text:
>>> "L'ombra s'estira d'amunt les pedres lentes"
"L'ombra s'estira d'amunt les pedres lentes"
Si intento el mateix amb cometes simples no funciona:
>>> 'L'ombra s'estira d'amunt les pedres lentes'
File "<python-input-22>", line 1
'L'ombra s'estira d'amunt les pedres lentes'
^
SyntaxError: unterminated string literal (detected at line 1)
Com que has començat l’string amb '
Python espera que l’acabis amb '
🤨
I que passa si vull escriure un poema amb moltes línies?
Doncs per això Python permet utilitzar """
:
>>> """Un
... dos
... tres"""
'Un\ndos\ntres'
\n
és un caràcter especial que significa newline
.
f-string
Un f-string (formatted string literal) és una string de Python prefixat amb la lletra f
que permet incrustar expressions de Python dins del string mitjançant claus {}
.
>>> z = 23
>>> f"Fa {z} anys que va caure un llamp a ..."
'Fa 23 anys que va caure un llamp a ...'
Pots interpolar tantes variables com vulguis:
>>> nom = "Laia"
>>> edat = 21
>>> f"Em dic {nom} i tinc {edat} anys."
'Em dic Laia i tinc 21 anys.'
I les variables podem ser de tipus str
:
>>> nom = "Laura"
>>> f"Hola {nom}!"
'Hola Laura!'
El que hi ha dins de les claus {}
és una expressió, el que vol dir que pots fer operacions matemàtiques dins de les claus {}
:
>>> f"Anem a sumar { 4 + 8 + 12 }"
'Anem a sumar 24'
Encara que és més interessant si dius el que estas sumant 😊:
>>> f"El resultat de sumar 4 + 8 és { 4 + 8 }"
'El resultat de sumar 4 + 8 és 12'
I podem millorar l’exemple amb un que té més sentit:
>>> a = 4
>>> b = 8
>>> f"El resultat de sumar {a} + {b} és { a + b }"
'El resultat de sumar 4 + 8 és 12'
Format
Els f-strings tenen moltes més opcions que pots consultar a Internet.
Per exemple si divideixo 2 entre 3, el resultat és un nombre infinit que Python arrodoneix una mica en mostrar en pantalla:
>>> a = 2/3
>>> a
0.6666666666666666
Si vols pots donar format al número tu mateix:
>>> f"El valor de a es {a:.2f}"
'El valor de a es 0.67'
Si vols pots llegir aquest article: How to Format Floats Within F-Strings in Python
Activitats
Escriu aquesta sentència de manera que es puguin entendre fàcilment:
+4++6-+6+-10
+4 + +6 - +6 + -10
Mostra el següent text
L'usuari Miquel té 125.60 MB d'espai lliure
Usant la tècnica de l’f-string i les següents variables:
usuari = "Miquel"
espai = 125.5999
>>> f"L'usuari {usuari} té {espai:.2f} MB d'espai lliure"
L'usuari Miquel té 125.60 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.
>>> 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
>>> 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
>>> 4/(2+2+-4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero