Algoritme

Un algoritme és un conjunt de sentències en què alguns blocs s'executen de manera seqüencial, selectiva o repetitiva.

Sentència

Un bloc és un conjunt de sentències que s’executen una després de l’altre.

Comença una nova sessió amb l’intèrpret de Python:

uv run python

Una sentència és el que escrius en l’intèrpret interactiu de Python abans de prémer .

A continuació tens l’execució de tres sentències:

>>> x = 45
>>> x += 90
>>> x
135
>>

A continuació tens un graf que representa l’execució de les tres sentències:

x = 45

x += 90

x

Si vols, en lloc d’utilitzar l’intèrpret interactiu de Python, pots escriure les sentències en un fitxer i dir a l’intèrpret de Python que llegeixi el fitxer i que executi les sentències que estan escrites en el fitxer.

Surt de l’interpret interactiu de Python.

Crea el fitxer hello.py amb l’editor “notepad”:

$ notepad hello.py

Escriu les tres sentències, una sota de l’altre:

x = 45
x += 90
x

A continuació executa l’intèrpret de Python amb el fitxer hello.py:

uv run hello.py

I no passa res 😳.

Sí que passa, però no apareix res en pantalla.

A diferència del que passa amb l’intèrpret interactiu de Python …

Si vols mostrar coses per pantalla has d’utilitzar la funció print().

Modifica la tercera sentència del fitxer hello.py fer un “print” de la variable x:

x = 45
x += 90
print(x)

Torna a executar el fitxer hello.py:

> uv run hello.py
135

Ara sí que apareix per pantalla el valor de la variable x.

En Python cada línia del fitxer, que no està buida, és una sentència.

Si escrius un programa amb mil línies que no estan buides, tens un programa de mil sentències que s’executen una a continuació de l’altre llevat que utilitzis una condició o una iteració com veurem més endavant.

Programa

Un exemple de programa senzill és un conjunt d’instruccions que, dona’t uns valors inicials, torna un resultat.

Crearem el nostre primer programa que calcula l’àrea d’un cercle.

notepad circle_area.py

El valor de l’àrea d’un cercle es calcula a partir del radi:

radius = 5

PI = 3.141592653
area = PI * (radius ** 2)

print(area)

Si demanem a l’intèrpret de Python, el fitxer s’executarà de manera seqüencial:

radius = 5

PI = 3.141592653

area = PI * (radius ** 2)

print(area)

I el resultat serà l’esperat:

> uv run circle_area.py
78.539816325

Ara si volem conèixer l’àrea d’un cercle de radi 15, podem editar l’script circle_area.py i modificar el valor de la variable radius:

radius = 16

PI = 3.141592653
area = PI * (radius ** 2)

print(area)

Podem executar l’script i verificar que funciona:

> uv run circle_area.py
804.247719168

Però en lloc d’haver de modificar l’script cada cop que hem de calcular un cercle amb radi diferent …

Si puc imprimir coses per pantalla amb la funció print(), també haig de poder llegir coses per pantalla…

Per això està la funció input():

radius = int(input())

PI = 3.141592653
area = PI * (radius ** 2)

print(area)

Fixa’t que hem de convertir l’input en un int amb la funció int().

Si executem l’script sembla aquest es queda aturat esperant l‘“input”.

> uv run circle_area.py
16
804.247719168

Has d’escriure el valor del radi i apretar enter.

I aquí tens el teu primer programa!

Només falta que el programa sigui “usable”, que l’usuari sàpiga que està passant.

Modifica de nou el fitxer circle_area.py:

radius = int(input("Which radius: "))

PI = 3.141592653
area = PI * (radius ** 2)

print(area)

Ara el programa imprimeix per pantalla l’string “Wich radius:” mentre espera l‘“input”:

> uv run circle_area.py
Which radius: 33
3421.194399117

Condició

Una condició és un requisit per procedir amb alguna cosa.

Per exemple, una condició per poder comprar una cosa és que tinguis bastants diners per poder comprar aquesta cosa.

Per exemple, tens 100 € i vols comprar un iPhone de 600 €.

Per comprar has d’utilitzar el programa shop.py:

money = int(input("Euros: "))

print("You have a new iPhone!")

Aquest programa no funciona gaire bé perquè li dones 100 € i et ven un iPhone:

$ uv run shop.py
Euros: 100
You have a new iPhone!

I li dones 0 € i també et dona un iPhone!

$ uv run shop.py
Euros: 0
You have a new iPhone!

El programa ha de verificar que es compleixi una condició: que els diners que li dones siguin igual o superior al preu de l’iPhone!

Per això fas servir l’expressió if <condició> :.

Modifica el codi tal com es mostra a continuació, i molt important, “sagna” el primer print:

money = int(input("Euros: "))

if money > 599 :
    print("You have a new iPhone!")

print("Bye!")

La condició és money > 599.

Si executes el codi de nou pots veure que ara no et venen un iPhone per 100 €:

$ uv run shop.py
Euros: 100
Bye!

Però si te’l venen per 600 € o més:

$ uv run shop.py
Euros: 900
You have a new iPhone!
Bye!

El codi funciona, encara que no és gaire informatiu per l’usuari.

Booleà

Una condició és compleix o no es compleix, en el mon de Python no hi ha termes mitjos.

Com que un una condició només pot tenir dos valors sempre es fa servir una expressió de tipus bool (un booleà), alguna cosa que retorna True o False, per executar o no executar un conjunt de codi.

Si sumo dos números el resultat és un número:

>>> 100 + 599
699
>>> type (100 + 599)
<class 'int'>

Però si comparo dos números, el resultat és True o False (un valor de la classe bool)

>>> 100 > 599
False
>>> type(100 > 599)
<class 'bool'>
>>> type(False)
<class 'bool'>
>>> False
False

En Python tenim 6 operadors per comparar números:

x == y     # x és igual a y
x != y     # x no és igual a y
x > y      # x és major que y
x < y      # x és menor que y
x >= y     # x és major o igual que y
x <= y     # x és menor o igual que y

En matemàtiques fem servir = per comparar números o definir equacions, però en Python = es fa servir per assignar valors a les variables.

És un error bastant comú tal com pots provar a continuació:

>>> 3 = 3
  File "<stdin>", line 1
    3 = 3
    ^
SyntaxError: cannot assign to literal here. Maybe you meant '==' instead of '='?

Python ja et diu que: "Maybe you meant '==' instead of '='?"

Un altre error és enlloc d’escriure >= o <=, escriure => o =<:

>>> 3 => 3
  File "<stdin>", line 1
    3 => 3
    ^
SyntaxError: cannot assign to literal

Execució condicional

A continuació modifiquem el codi:

money = int(input("Euros: "))

iphone = 600

if money >= iphone :
    print("You have a new iPhone!")

print("Bye!")

Pots veure que hem introduït dos millores:

  • En lloc de comparar directament money amb 600, guardem el valor de l’iPhone en la variable iphone i comparem money amb iphone.

  • Utilitzem el comparador >= enlloc d’abaixar el preu 1 € i comparar amb >.

I per quin motiu no hem escrit directament aquest codi?

Perquè per aprendre a programar s’ha d’anar pas a pas, i si et saltes un pas, deixes d’entendre coses i al final et perds.

I ara podem explicar que és l’execució condicional.

Com ja saps de Computació les sentències no poden tenir espais en blanc al principi, llevat que formin part d’un altre bloc d’execució.

Fina ara només has treballat amb un únic bloc d’execució, el principal, però if afegeix un bloc d’execució condicional.

True

False

money = int(input("Euros: "))

iphone = 600

if money >= iphone :

print("Bye!")

print("You have a new iPhone!")

El bloc d’execució condicional s’executa si es compleix la condició.

Python sap quines són les sentències que formen part d’aquest bloc perquè estan sagnades amb el mateix nombre d’espais en blanc:

A vegades si la condició és True s’ha d’executar un bloc de codi, però si la condició és False també s’ha d’executar un altre bloc de codi.

En aquests casos tenim l’estructura de control if-else.

Per exemple, si money és menor que el que costa l’iPhone podem informar a l’usuari del preu que ha de pagar.

money = int(input("Euros: "))

iphone = 600

if money >= iphone :

    print("You have a new iPhone!")

else:

    print(f"iPhone cost {iphone} euros!")

print("Bye!")

Ara si volem comprar l’iPhone per menys diners del que costa ens avisa de que no pot ser perquè l’iPhone val 600€.

$ uv run shop.py
Euros: 34
iPhone cost 600 euros!
Bye!

Pots veure que ara tenim dos blocs d’execució secundaris:

I aquí tens la representació del graf d’execució:

True

False

money = int(input("Euros: "))

iphone = 600

if money >= iphone :

else :

print("Bye!")

print("You have a new iPhone!")

print(f"iPhone cost {iphone} euros!")

Però el nostre script té el problema que si ens donen més diners del que val l’iPhone no tornem el canvi, i a la llarga això portarà molts problemes amb els compradors.

Un bloc d’execució secundari és igual que el bloc d’execució primari: també pot tenir if, else, etc.

money = int(input("Euros: "))

iphone = 600

if money >= iphone :
    print("You have a new iPhone!")

    if money > iphone :
        print(f"Your change is {money - iphone} euros")

    print("Great buy!")

else:
    print(f"The iPhone costs {iphone} euros!")

print("Bye!")

Si ara comprem un iPhone per més de 600 euros, el programa ens torna el canvi:

$ uv run shop.py
Euros: 800
You have a new iPhone!
Your change is 200 euros
Great buy!
Bye!

Els grafs de flux estan molt bé per exemple senzills i entendre conceptes.

Però el nostre graf comença a ser una mica complicat de seguir:

True

True

False

False

money = int(input("Euros: "))

iphone = 600

if money >= iphone :

else :

print("Bye!")

print("You have a new iPhone!")

if money > iphone :

print(f"Your change is {money - iphone} euros")

print("Great buy!")

print(f"iPhone cost {iphone} euros!")

En canvi, ara que ja comences a saber llegir Python, pots veure que el codi de Python és més fàcil d’entendre que la representació en graf:

Pots veure que hi ha quatre blocs d’execució, un de principal i els altres imbricats dins del principal o dins d’un altre.

Això s’anomena programació estructurada:

  • Un programa és una estructura de blocs uns dins dels altres, que s’executen de manera condicional.

  • Cada bloc és un conjunt de sentències que s’executa una després de l’altre.

Operadors lògics

Juntament amb altres operadors, serveixen per a contrastar dues o més condicions.

TODO. Revisar !

Per exemple; si volem un número entre 16 i 64; usaràs aquesta condició.

if (n>15) and (n<65)
   print ("pots treballar")

A diferència de Java, els operadors lògics s’escriuen amb lletres minúscules (and/or/xor/not)

n = int(input("Introdueix un número enter: "))
if (n>2) and (n<5):
    print ("esta entre 2 y 5")
elif (n>5) or (n<2):
   print("Fora de 2 y 5")
else:
    print("Es un altre cas")

Si executem aquest codi, obtenim:

Introdueix un número enter: -3
Fora de 2 y 5

Si necessites més condicions (la instrucció match) consulta aquest article:

Python switch case statment examples

Tingues en compte que no és habitual l’ús del match, ja que s’ha incorporat força recentment (Python 3.10)

Activitats

1.- Crea un programa que demani a l’usuari el preu de la seva compra.

Si és major a 100 euros s’aplica el 10%, si és major a 50 però menor de 100 un 5% de descompte, en altres casos no té descompte.

Al final del programa has de mostrar el % de descompte i el preu final.

Operador condicional ternari.

Com podreu descobrir aviat, als programadors els agraden tota mena de dreceres. Per a les expressions condicionals, també hi ha un truc: podeu escriure una declaració if-else en una línia. Això s’anomena operador ternari i té aquest aspecte:

print("It’s a day now!" if sun else "It’s a night for sure!")

O, de manera més general:

first_alternative if condition else second_alternative

Exemple:

es_bonic = True
estat = "es bonic" if es_bonic else "no es bonic"
print(f"El gat {estat}.")

Resultat:

El gat es bonic.

És una qüestió de comoditat, però recordeu que el codi que creeu encara hauria de ser llegible.

Repetició

En moltes ocasions, ens interessa executar una mateixa sentència moltes vegades. Per evitar repetir-la, que seria molt pesat i propens a errors 🤨, usem les estructures de repetició o bucles.

Bucle while

El bucle while repeteix un bloc de codi sempre que una condició es compleix. És com dir-li a Python: “Repeteix això mentre alguna cosa sigui veritat”.

while condició:
    # codi a repetir

Veiem-ho amb un exemple senzill: per exemple, mostrar els números de l’1 al 5.

i = 1
while i <= 5:
    print("El número és:", i)
    i += 1  # Això és el mateix que i = i + 1 o i++
print("Adeu!)

Resultat:

El número és: 1
El número és: 2
El número és: 3
El número és: 4
El número és: 5
Adeu!

A nivell d’esquema, es pot representar de la següent forma:

True

False

i=1

while i <=5:

Adeu!

Print 'El numero és:' i

i+=1

O, per exemple, mostrar la taula de multiplicar d’un número:

num = 8
i = 1
print(f"Taula del {num}")
while i <= 10:
    print(f"{num} * {i} = {num*i}")
    i += 1

Resultat:

Taula del 8
8 * 1 = 8
8 * 2 = 16
...
8 * 9 = 72
8 * 10 = 80

Podem usar els bucles per fer un programa que demani a l’usuari números fins que introdueixi un 0. Llavors el programa calcularà i mostrarà la suma de tots els números i acabarà.

suma = 0
numero = None

while numero != 0:
    numero = int(input("Introdueix un número enter (0 per acabar): "))
    # Afegir el número a la suma si no és 0
    if numero != 0:
        suma += numero

print("La suma total és:", suma)

Resultat.

Introdueix un número (0 per acabar): 12
Introdueix un número (0 per acabar): -4
Introdueix un número (0 per acabar): 10
Introdueix un número (0 per acabar): 0
La suma total és: 18

Com en el cas dels condicionals, separem els blocs de codi per intendacions (per 1 tabulador o 4 espais) i el salt de línia (tecla ENTER) per tancar cada bloc.

Esquema:

Un altre cas habitual on usar bucles és la creació d’una aplicació del terminal que doni la opció de calcular àrea de diversos polígons a l’usuari (1 pel rectangle, 2 pel triangle… ), fins que l’usuari indiqui la opció de sortir de la aplicació.

import math

opcio = -1

while opcio:
    print("\nOpcions:")
    print("1. Calcular l'àrea d'un quadrat")
    print("2. Calcular l'àrea d'un cercle")
    print("3. Calcular l'àrea d'un triangle")
    print("0. Sortir")

    opcio = int(input("Tria una opció (0-3): "))

    if opcio == 1:
        costat = float(input("Introdueix la longitud del costat del quadrat: "))
        resultat = costat * costat
        print(f"L'àrea del quadrat és: {resultat}")

    elif opcio == 2:
        radi = float(input("Introdueix el radi del cercle: "))
        resultat = math.pi * radi * radi
        print(f"L'àrea del cercle és: {resultat}")

    elif opcio == 3:
        base = float(input("Introdueix la base del triangle: "))
        altura = float(input("Introdueix l'altura del triangle: "))
        resultat = 0.5 * base * altura
        print(f"L'àrea del triangle és: {resultat}")

    elif opcio == 0:
        print("Sortint de l'aplicació. Adéu!")
        break

    else:
        print("Opció no vàlida. Si us plau, tria una opció entre 0 i 3.")

Resultat:

Opcions:
1. Calcular l'àrea d'un quadrat
2. Calcular l'àrea d'un cercle
3. Calcular l'àrea d'un triangle
0. Sortir
Tria una opció (0-3): 1
Introdueix la longitud del costat del quadrat: 2
L'àrea del quadrat és: 4.0

Opcions:
1. Calcular l'àrea d'un quadrat
2. Calcular l'àrea d'un cercle
3. Calcular l'àrea d'un triangle
0. Sortir
Tria una opció (0-3): 0
Sortint de l'aplicació. Adéu!

Bucle for

Per algunes de les operacions repetitives que volem fer és més senzill usar el bucle for.

A Python no existeix el bucle que hi ha a Java:

for (int i=0; i<10; i++)

Però n’hi ha un altre de més potent, que altres llenguatges l’han incorporat més tard (Java, C# …). És un for que recorre seqüències com string (l’string és una seqüència de caràcters un a un) o bé una llista (la veurem una mica més endavant).

Per exemple, aquest exemple utilitza un bucle for per iterar sobre cada lletra d’una paraula i comptar les aparicions d’una lletra específica.

paraula = input("Introdueix una paraula: ")
lletra_a_comptar = input("Introdueix la lletra que vols comptar: ")

comptador = 0
for lletra in paraula:
    if lletra == lletra_a_comptar:
        comptador += 1

print(f"La lletra '{lletra_a_comptar}' apareix {comptador} vegades a la paraula.")

Resultat:

Introdueix una paraula: Biopython
Introdueix la lletra que vols comptar: o
La lletra 'o' apareix 2 vegades a la paraula.

Activitat.

2.- Crea un programa que mostri per pantalla un triangle d’asteriscs en funció del número que posi l’usuari.

Per exemple, si posa el número 4, el resultat ha de ser:

*
**
***
****

Pista: Recorda que usant una instrucció com aquesta, pots generar n cops un asterisc, depèn del valor de la variable n: print("*" * n). Si n=3 llavors el resultat és ***

3.- Crea un programa que demani a l’usuari una seqüència de nucleòtids (per exemple “ACGTAC”) i calculi el número de bases ‘G’ i ‘C’ i calculi el percentatge GC.


Script

TODO

#!/bin/python3
...