Python: Numeri¶
Numeri: Tipi Fondamentali¶
Ci sono tre tipi numerici fondamentali:
| Tipo | Significato |
|---|---|
int |
Rappresenta numeri interi (!) |
float |
Rappresenta numeri razionali a virgola mobile (float ing-point) |
bool |
Rappresenta condizioni, puo’ essere True o False |
Note
I razionali float hanno precisione limitata: la maggior parte dei
razionali puo’ essere rappresentata solo approssimatamente con un
float.
Ai fini di questo corso, i dettagli non sono importanti.
Esempio. Creo tre variabili, una per tipo, poi le stampo a schermo con
print:
n = 10
x = 3.14
cond = False
# Stampo le tre variabili
print(n, x, cond)
# Idem, inframezzando testo
print("n =", n, "x =", x, "e la condizione cond vale", cond)
Questa sintassi di print vale per tutti i tipi di variabili, non solo
quelli numerici.
Numeri: Aritmetica¶
Tutti i tipi numerici mettono a disposizione le stesse operazioni aritmetiche:
| Operazione | Significato |
|---|---|
a + b |
somma |
a - b |
differenza |
a * b |
prodotto |
a / b |
divisione |
a // b |
divisione intera |
a % b |
resto della divisione (o modulo) |
a ** b |
elevamento a potenza |
Il tipo del risultato di n operazione m e’ automaticamente il tipo
piu’ “complesso” tra i tipi di n e m – per questo si parla di
conversione automatica.
La scala di complessita’ dei tipi numerici e’:
bool < int < float
Esempio. Ad esempio, se sommo un int ed un float, otterro’ un
float:
risultato = 1.2 + 1 # float * int
print(risultato) # 1.2
print(type(risultato)) # float
Questo perche’ e’ necessario un float per rappresentare il valore 1.2:
un int non basterebbe!
Warning
Per evitare errori, e’ necessario scegliere il tipo delle variabili in modo che il tipo del risultato sia sufficientemente “complesso” da riuscire a rappresentarne il valore.
Numeri: Confronti¶
Tutti i tipi numerici (e in generale tutto i tipi Python che vedremo durante il corso) supportano le operazioni di comparazione:
| Operazione | Significato |
|---|---|
a == b |
uguale |
a != b |
diverso |
a < b |
minore |
a <= b |
minore o uguale |
a > b |
maggiore |
a >= b |
maggiore o uguale |
Il risultato di un’espressione di confronto e’ sempre un bool: vale
True se la condizione e’ soddisfatta, e False altrimenti.
Esempio. Aritmetica e confronti possono essere combinati per verificare condizioni “complesse”, come questa:
na, nc, ng, nt = 2, 6, 50, 4
risultato = (na + nt) > (nc + ng)
print(risultato)
print(type(risultato))
I valori Booleani bool (es. i risultati delle operazioni di confronto)
possono essere combinati attraverso le operazioni logiche:
| Operazione | Significato |
|---|---|
a and b |
congiunzione: True se e solo se a e b sono True |
a or b |
disgiunzione: True se almeno una tra a e b e’ True |
not a |
negazione: True se a e’ False e viceversa |
Qui sia a che b sono dei bool.
Warning
In generale, fare aritmetica (es. somme) con valori Booleani e costruire espressioni logiche con valori interi o razionali e’ sconsigliato.
In questi casi, Python si comporta in modo (deterministico e spiegabile, ma decisamente) bizzarro.
Esempio. x > 12 e x < 34 danno come risultato dei bool, quindi
le posso combinare per ottenere:
# int int
# | |
print((x > 12) and (x < 34))
# \______/ \______/
# bool bool
# \___________________/
# bool
oppure:
# int int
# | |
print((not (x > 12)) or (x < 34))
# \______/
# bool
# \____________/ \______/
# bool bool
# \________________________/
# bool
Esempi¶
Esempio. Calcolo gli zeri dell’equazione quadratica x^2 - 1 = 0:
a, b, c = 1.0, 0.0, -1.0
delta = b**2 - 4*a*c
zero1 = (-b + delta**0.5) / (2 * a)
zero2 = (-b - delta**0.5) / (2 * a)
print(zero1, zero2)
Qui uso x**0.5 per calcolare la radice quadrata: \sqrt{x} = x^\frac{1}{2}.
Esempio. Voglio calcolare il GC-content di un gene. So che il gene:
- E’ lungo 1521 basi.
- Contiene 316 citosine.
- Contiene 235 guanine.
Simbolicamente, il GC-content e’ definito come (g + c) / n. Per calcolarlo posso scrivere:
n, c, g = 1521, 316, 235
gc_content = (c + g) / n
print(gc_content)
Esempio. Per controllare che x (il cui valore e’ “fuori dal mio
controllo”, ma nell’esempio sotto fisso per convenienza) cada nell’intervallo A
= [10,50] scrivo:
x = 17 # ad esempio
minimo_a, massimo_a, x = 10, 50
dentro_a = (minimo_a <= x <= massimo_a)
print(dentro_a)
oppure:
dentro_a = ((x >= minimo_a) and (x <= massimo_a))
Assumendo che dentro_a, dentro_b e dentro_c indichino che x e’
nell’intervallo A, B o C, rispettivamente, posso comporre condizioni piu’
complesse:
# x e' in almeno uno dei tre intervalli
dentro_almeno_uno = dentro_a or dentro_b or dentro_c
# x e' sia in A e B, ma non in C
dentro_a_e_b_ma_non_c = dentro_a and dentro_b and (not dentro_c)
Esercizi¶
Creare alcune variabili, controllando ad ogni passaggio che valore e tipo siano corretti (usando
printetype):aebcon valore12e23come interi.xeycon valore21e14come razionali.
Usando
print(una sola volta), stampare:- Tutte le variabili di cui sopra sulla stessa riga.
- Tutte le variabili di cui sopra, separate da
;, sulla stessa riga. - Il testo “il prodotto di
aebe’a * b”, sostituendo ada,bea * bi valori delle variabili.
Determinare valore e tipo di:
- Il prodotto di
aeb. - Il quoziente di
xey. - Il quoziente intero di
aeb. - Il quoziente intero di
xey. - Il prodotto di
bey. 2elevato a0.2elevato a1.2.2elevato a-2.- La radice quadrata di
4. - La radice quadrata di
2.
- Il prodotto di
Che differenza c’e’ tra:
10 / 1210 / 12.010 // 1210 // 12.0
Che differenza c’e’ tra:
10 % 310 % 3.0
Usando
pi = 3.141592e dator = 2.5, calcolare:- La circonferenza di raggio
r: 2 \pi r. - L’area di un cerchio di raggio
r: \pi r^2. - Il volume di una sfera di raggio
r: \frac{4}{3} \pi r^3.
- La circonferenza di raggio
Creare due variabili
a = 100eb = True. Usando un numero opportuno di variabili ausiliarie (chiamatele come volete!), fate in modo che il valore diafinisca inbe che quello dibfinisca ina.(Scrivere
a = Trueeb = 100non vale!)Si puo’ fare con una sola variabile ausiliaria?
Sullo stesso strand di DNA si trovano due geni. Il primo include i nucelotidi dalla posizione 10 alla posizione 20, il secondo quelli dalla posizione 30 alla posizione 40. Scriviamo queste informazioni cosi’:
gene1_inizio, gene1_fine = 10, 20 gene2_inizio, gene2_fine = 30, 40
Data una variabile
posche rappresenta una posizione arbitraria sullo strand, scrivere dei confronti per verificare se:possi trova nel primo gene.possi trova nel secondo gene.possi trova tra l’inizio del primo gene e la fine del secondo.possi trova tra l’inizio del primo gene e la fine del secondo, ma in nessuno dei due geni.possi trova prima dell’inizio del primo gene o dopo la fine del secondo.poscade in uno dei due geni.posnon dista piu’ di 10 dall’inizio del primo gene.
Date le tre variabili Booleane
t,u, ev, scrivere delle espressioni che valgonoTruese e solo se:t,u,vtutte e tre vere.te’ vera oppureue’ vera, ma non entrambe.- Esattamente una delle tre variabili e’ falsa.
- Esattamente una delle tre variabili e’ vera.
Soluzioni¶
Soluzioni:
a = 12 b = 23 print(a, b) print(type(a), type(b)) # int, int x = 21.0 y = 14. print(x, y) print(type(x), type(y)) # float, float
Soluzioni:
print(a, b, x, y) print(a, ";", b, ";", x, ";", ...)
Soluzioni:
# casi semplici: prodotto = a * b # int * int print(prodotto) print(type(prodotto)) # int # divisione e divisione intera tra vari # tipi di numeri: quoziente = x / y # float / float print(quoziente) print(type(quoziente)) # float risultato = a // b # int // int print(risultato) print(type(risultato)) # int risultato = x // y # float // float print(risultato) print(type(risultato)) # float risultato = b * y # int * float print(risultato) print(type(risultato)) # float # qui il tipo e' determinato automaticamente # in base alla magnitudine del risultato: risultato = 2**0 # int**int print(risultato) print(type(risultato)) # int risultato = 2**1.2 # int*float print(risultato) print(type(risultato)) # float risultato = 2**-2 # int*int print(risultato) print(type(risultato)) # *** float!!! *** risultato = 4**0.5 # int*float print(risultato) print(type(risultato)) # float risultato = 2**0.5 # int*float print(risultato) print(type(risultato)) # float
Soluzioni:
>>> print(10 / 12) 0.8333333333333334 >>> print(10 / 12.0) 0.8333333333333334 >>> print(10 // 12) 0 >>> print(10 // 12.0) 0.0
Come si vede la divisione intera si comporta normalmente rispetto ai tipi: quando la applico ai due float il risultato e’ quello della divisione normale, ma troncato all’intero
0.Soluzioni:
>>> 10 % 3 1 >>> 10 % 3.0 1.0
Come si puo’ vedere,
%ritorna il resto di10 / 3:10 = 3*3 + 1 # ^ # il resto
Il tipo degli operandi non influenza il valore del risultato, solo il suo tipo.
Soluzione:
pi = 3.141592 r = 2.5 circonferenza = 2 * pi * r print(circonferenza) area = 2 * pi * r**2 print(area) area = 2 * pi * r * r print(area) volume = (4.0 / 3.0) * pi * r**3 print(volume)
Soluzione:
a, b = 100, True a2 = a b2 = b b = a2 a = b2 print(a, b)
oppure:
a, b = 100, True x = a a = b b = x print(a, b)
Soluzione:
gene1_inizio, gene1_fine = 10, 20 gene2_inizio, gene2_fine = 30, 40 # disegnino: # # 5' 3' # ~~~~~xxxxxxxx~~~~~xxxxxxx~~~~~> # 10 20 30 40 # \______/ \_____/ # gene_1 gene_2 # due alternative condizione_1 = (10 <= pos <= 20) condizione_1 = (pos >= 10 and pos <= 20) condizione_2 = (30 <= pos <= 40) condizione_3 = (10 <= pos <= 40) # due alternative condizione_4 = condizione_3 and not (condizione_1 or condizione_2) condizione_4 = (20 <= pos <= 40) condizione_5 = pos < 10 or pos > 40 # occhio che: # # pos < 10 and pos > 40 # # non ha senso: e' sempre False! condizione_6 = condizione_1 or condizione_2 condizione_7 = (0 <= pos <= 20)
Il codice va testato con diversi valori di
posizione, in modo da controllare che le condizioni si comportino come vogliamo: che sianoTruequando la posizione soddisfa i requisiti della domanda, eFalsealtrimenti.Soluzione:
tutte_e_tre = t and u and v t_oppure_u_ma_non_tutte_e_due = (t or u) and not (t and u) # NOTA: qui i backslash alla fine delle righe servono # per andare "a capo", potete ignorarli. una_delle_tre_falsa = \ (t and u and not v) or \ (t and not u and v) or \ (not t and u and v) una_delle_tre_vera = \ (t and not u and not v) or \ (not t and u and not v) or \ (not t and not u and v)
Di nuovo, il codice va testato usando diversi valori per
t,uev. Ci sono 8 combinazioni in tutto:t, u, v = False, False, False t, u, v = False, False, True t, u, v = False, True, False t, u, v = False, True, True # ...