Il 0% ha trovato utile questo documento (0 voti)
1 visualizzazioni20 pagine

py

Il capitolo descrive Python come un linguaggio di programmazione semplice e versatile, con una sintassi chiara e una vasta gamma di librerie. Viene spiegato il funzionamento di Python come linguaggio interpretato, la gestione della memoria, e la differenza tra variabili mutabili e immutabili. Inoltre, il capitolo illustra variabili, liste, dizionari, cicli e funzioni, evidenziando le peculiarità della sintassi di Python rispetto ad altri linguaggi.

Caricato da

lucio.ferrari829
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Il 0% ha trovato utile questo documento (0 voti)
1 visualizzazioni20 pagine

py

Il capitolo descrive Python come un linguaggio di programmazione semplice e versatile, con una sintassi chiara e una vasta gamma di librerie. Viene spiegato il funzionamento di Python come linguaggio interpretato, la gestione della memoria, e la differenza tra variabili mutabili e immutabili. Inoltre, il capitolo illustra variabili, liste, dizionari, cicli e funzioni, evidenziando le peculiarità della sintassi di Python rispetto ad altri linguaggi.

Caricato da

lucio.ferrari829
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Sei sulla pagina 1/ 20

Capitolo 6

Python

• Python è un linguaggio di programmazione semplice, infatti la sintassi di Python è chiara


e leggibile, simile al linguaggio naturale.

• È un linguaggio versatile, infatti supporta molti paradigmi di programmazione, come la


programmazione procedurale, orientata agli oggetti e funzionale.

• Possiede una vasta gamma di librerie da cui attingere: NumPy, Pandas, TensorFlow,
Django, Flask, e molte altre.

• È OpenSource (al contrario di Matlab).

6.1 Come Funziona Python?

Python è un linguaggio interpretato, il che significa che il codice viene eseguito riga per riga da
un interprete. Non è necessario compilare il codice prima di eseguirlo.

1 print ("Ciao , mondo !")

Quando scrivi ed esegui questo codice, Python lo interpreta e stampa il messaggio "Ciao,
mondo!" sulla console. Ovvero, che al contrario dei linguaggi compilati (che hanno bisogno di
essere compilati) il codice sorgente (il file .py in Python) non viene tradotto in un programma
binario (eseguibile) prima dell’esecuzione invece succede appunto che un interprete legge,
analizza e traduce il codice una riga alla volta mentre il programma è in esecuzione. Lo
svantaggio principale è che la velocità è nettamente inferiore rispetto ai linguaggi compilati,
perché il codice viene interpretato durante l’esecuzione.

39
40 CAPITOLO 6. PYTHON

6.2 Dynamic Typing, String Typing

Dove: >>> è il prompt interattivo di Py-


1 >>> a = 4 thon, le vedi quando utilizzi l’interprete in-
2 >>> type(a) terattivo di Python (es. nella shell Python),
3 <type "int"> chiaramente serve per indicare che puoi di-
4
gitare comandi. La funzione type() resti-
5 >>> c = 2.1 tuisce il tipo di dato di una variabile o valo-
6 >>> type(c) re, infatti in Python, ogni dato appartiene a
7 <type "float "> un tipo specifico (es. intero, float, stringa,
8
ecc.). A riga "3" possiamo infatti vedere che
9 >>> s = "abc" l’output della shell ci dice che a è un tipo di
10 >>> type(s) variabile int (intera). Il resto del codice è
11 <type "str"> facilmente intuibile di conseguenza, da no-
12
tare da riga "13" a riga "15", noi dichiariamo
13 >>> test = c>a un variabile test = c > a , la printiamo ed
14 >>> print (test) otteniamo come output un valore booleano
15 False che può essere: True (1) oppure False (0).
In questo caso False poiché c < a.

6.3 Liste
Python fornisce molti diversi contenitori. Una lista è una collezione non ordinata del tipo:
1 >>> l = [1, 2, 3, 4, 5]
2 >>> type(l)
3 <type "list">
4

5 >>> l[2]
6 3
7

8 >>> l [2:4] # Sintassi dello slicing : l[start:end] (end no incluso )


9 [3, 4]
10

11 >>>l. append (3.1) # Aggiungi un elemento alla lista


12 >>>print (l)
13 [1, 2, 3, 4, 5 ,3.1]

6.4 Stringhe

1 >>> a = "hello"
2 >>> a[0]
3 "h"
4

5 >>> a[1]
6 "e"
6.5. VARIABILI MUTABILI ED IMMUTABILI 41

8 >>> a[-1]
9 "o"

Esattamente come in C/C++

6.5 Variabili Mutabili ed Immutabili


In molti linguaggi (in C/C++ ad es.) una variabile indica una locazione di memoria la cui
posizione è fissa ma il contenuto variabile. La caratteristica di Python è che: “Ogni cosa è un
oggetto”. È quindi in Python fondamentale distinguere tra oggetti:

• Immutabili (integer, float, complex, boolean, string)

• Mutabili (list)

Da notare il fatto che la di↵erenza tra variabili mutabili e immutabili non riguarda la ca-
pacità di modificare la variabile stessa, ma piuttosto se è possibile modificare il valore interno
dell’oggetto a cui la variabile fa riferimento.

6.5.1 Immutabili

1 >>> a=2 #Dico che "a" e’ 2


2 >>> a=a+1 #Creo ora un nuovo oggetto "a" che vale 2 ( valore
precedente )+1=3
3 >>> b=2

Gli int in Python sono immutabili: non puoi modificare direttamente un int esistente.
Ogni volta che "modifichi" un int , in realtà stai ne creando uno nuovo. Allora quello che ho
fatto è non modificare il numero intero originale bensì creare un nuovo int ed il riferimento
della variabile a viene aggiornato per puntare il nuovo numero. Lo stesso vale per str , float
e gli altri.

6.5.2 Mutabili
Le liste in Python sono mutabili: puoi cambiare il contenuto della lista senza creare una nuova
lista.
1 >>> thing =[49 ,52] #Ho una lista composta da due elementi -> 49 ,52
2 >>> thing. append ("cat") # Aggiungo infondo -> [49 , 52, "cat "]
3 >>> thing [1]="dog" # Sostituisco nella posizione [1] , "dog" -> [49 , "
dog", "cat "]

infatti la lista originale è stata modificata ed il riferimento in memoria è rimasto lo stesso.

6.6 Gestione della Memoria


Al contrario del C++ Python gestisce autonomamente la memoria. Alcuni oggetti vengono
creati automaticamente da Python altri invece vengono creati quando si assegna un “nome” (o
42 CAPITOLO 6. PYTHON

una referenza) ad essi o quando vengono passati ad una funzione. In Python infatti tutte le
variabili sono passate per referenza all’oggetto. Una volta che un oggetto non ha più nomi viene
cancellato dalla memoria automaticamente

6.7 Tuple
Simile a list ma non mutabile:
1 >>> t = 12345 , 54321 , " hello!"
2 >>> t[0]
3 12345
4

5 >>> t
6 (12345 , 54321 , "hello!")
7

8 >>> u = (0, 2)

6.8 Dictonary
Un dictionary è un’efficiente tabella chiave-valore (mutabile).
1 >>> tel = {"laure": 5752 , "paul": 5578}
2 >>> tel[" francis "] = 5915
3

4 >>> tel
5 {"paul": 5578 , " francis ": 5915 , "laure ": 5752}
6

7 >>> tel["paul"]
8 5578
9

10 >>> " francis " in tel


11 True

Molto simile a map nelle STL del C++.

6.9 Mutability Matters


Ma è così importante il concetto di mutabilità? Si e va capito per ottimizzare le prestazioni!
L’obiettivo è concatenare (unire) più stringhe contenute in un oggetto iterabile (come una
lista o un altro contenitore) in un’unica stringa finale. Per farlo abbiamo 2 metodi:

• Metodo 1:
1 s = "" # Si inizia con una stringa vuota "s"
2 for data in container : # Questo pezzo significa che per ogni
elemento "data" nel contenitore " container " avviene la cosa
successiva
6.10. IF, THEN, ELSE 43

3 s += data # Ovvero che si crea una nuova stringa in memoria


aggiornata con il nuovo elemento

In questo caso abbiamo usato un ciclo for per concatenare le stringhe.


• Metodo 2:
1 s = "".join( container )

In questo caso invece abbiamo usato il metodo str.join() sempre per concatenare le strin-
ghe. Tale metodo prende una lista (o qualsiasi iterabile, contenitore) di stringhe come input
e combina tutti gli elementi della lista in un’unica stringa, aggiungendo eventualmente un
separatore (in questo caso, una stringa vuota " ").

Il primo approccio so↵re del fatto che, siccome le stringhe sono immutabili, ogni volta viene
allocato lo spazio per un nuovo oggetto il cui nome è s . Nel secondo esempio l’allocazione in
memoria avviene una volta sola per la stringa finale.

6.10 if, then, else


In Python, i blocchi di codice sono delimitati dall’indentazione, ossia dallo spazio o tabulazione
all’inizio delle righe. Questo significa che il livello di indentazione determina quali istruzio-
ni appartengono a un determinato blocco logico. È una caratteristica unica rispetto ad altri
linguaggi come C++ o Java, che usano le parentesi gra↵e {} per delimitare i blocchi.
1 a = 10
2 if a == 1:
3 print (1) #Primo blocco
4 elif a == 2:
5 print (2) # Secondo blocco
6 else:
7 print ("Altro numero ") #Terzo blocco

6.11 for, range


Il costrutto for in Python permette di iterare su una sequenza di elementi. Quando utilizzi
range() , stai iterando su una sequenza di numeri generata automaticamente.
Prima di tutto vediamo la sintassi di range in Python:
1 range (start , end , step)

dove:

• start ) (opzionale) Il valore iniziale della sequenza (incluso). Di default è 0 .


• end ) Il valore finale (esclusivo, non incluso nella sequenza).
• step ) (opzionale) L’incremento tra un numero e il successivo. Di default è 1 .

allora posso combinare il ciclo con il metodo appena visto ed ottengo per esempio:
44 CAPITOLO 6. PYTHON

1 for i in range (0, 4, 1): #range (0, 4, 1) genera i numeri da 0 a 3


2 print (i)

così il ciclo for assegna ogni numero generato da range() alla variabile i e lo stampa: 0, 1,
2, 3. In quest caso start e step potevano essere omessi e si sarebbe ottenuto lo stesso risultato:
1 for i in range (4): #range (4) genera i numeri da 0 a 3
2 print (i)

Si può fare anche sulle stringhe:


1 for word in ("cool", " powerful ", " readable "): #Dove quest ’ultima e’
una tupla , il "for" scorre ogni elemento della tupla
2 print (" Python is %s" % word) #%s e’ un segnaposto che indica che
verra ’ inserita una stringa e % word specifica il valore (
stringa ) da sostituire al segnaposto %s.

allora verrà stampato:


Python is cool
Python is powerful
Python is readable

Quella del segnaposto %s è una vecchia sintassi oggi sostituita per lo più da: .format() ,
ovvero:
1 for word in ("cool", " powerful ", " readable "):
2 print (" Python is {}" . format (word)) #il segna posto ora e’ "{}"

in questo modo è un po’ più leggibile.

6.12 while/break/continue
Nel caso di while con break si ha:
1 z = 1+1j # Definisco il numero complesso z
2 while abs(z) < 100: # Continua finche ’ il modulo di z e’ minore di
100
3 if z.imag == 0: # Se la parte immaginaria e’ 0
4 break # Esce dal ciclo
5 z = z**2 + 1 # Aggiorna z elevandolo al quadrato e sommando 1

vediamo un esempio di evoluzione di z :


p p
• Inizialmente z = 1 + 1 j, allora vale che | z | = 12 + 12 = 2 < 100 entra allora nel ciclo

• La parte immaginaria è diversa da zero allora il ciclo non si interrompe e z viene aggiornato
2
z = z2 + 1 = 1 + 1j + 1 = 1 + 2 j

• A questo punto si ricontrolla il modulo e si continua


6.13. FUNZIONI 45

• Successive iterazioni aggiorneranno z finché | z | 100 o la parte immaginaria di z diventa


0.
Nel caso invece di continue :
1 a = [1, 0, 2, 4] # Lista di numeri
2 for element in a: # Itera su ogni elemento della lista
3 if element == 0: # Se l’elemento e’ 0
4 continue # Salta il resto del ciclo per questa iterazione
5 print (1. / element ) # Stampa l’inverso dell ’elemento
allora mi stampa: 1, 0.5, 0.25, poiché salta lo zero ma non interrompe il ciclo.

6.13 Funzioni
Funzione simile alla void in C++: (senza valore di ritorno)
1 def test (): # indica che stai definendo una funzione chiamata test
2 print ("in test function ")
3 test () # Quando scrivi test (), stai chiamando la funzione . Python
eseguira ’ il corpo della funzione , che in questo caso stampa il
messaggio .
In questo caso non c’è valore di ritorno (come in una funzione void in C++). Python utilizza
la parola chiave None per indicare un valore di ritorno "vuoto".
Funzione con valore di ritorno:
1 def area disco(r): # indica che stai definendo una funzione chiamata
area_disco che accetta un parametro r
2 return 3.14*r*r
3 area disco (1.5) # Quando scrivi area_disco (1.5) , stai chiamando la
funzione e passando il valore 1.5 come parametro
mi ritorna allora il valore: 7.064999999. Inoltre se assegni il risultato ad una variabile, puoi
usarlo successivamente:
1 def area disco(r):
2 return 3.14*r*r
3

4 area = area_disco (1.5)


5

6 print (area) # Output : 7.065

6.14 Funzioni con Parametri Default


1 def square (x=2): # Impongo parametro di default x==2
2 return x*x
3 square () # Output -> 4
4 square (3) # Output -> 9. Posso infatti successivamente cambiare il
parametro di default in questo modo
46 CAPITOLO 6. PYTHON

6.15 Funzioni con Parametri Indirizzati per Nome

1 def square (x=2,y=3,z=4):


2 return x+y+z
3 square () # Output -> 2+3+4 = 9, tutti i parametri sono predefiniti
4 square (1) # Output -> 1+3+4=8 , il primo parametro e’ stato cambiato
5 square (1, 2) # Cambiano i primi due parametri ma rimane il terzo
predefinito
6 square (1, z=2) # Qui sto chiamando il primo argomento in modo
posizionale mentre il secondo per nome , output -> 1+3+2 = 6
7 square (x=1, y=3, 4) # invalido !

Infatti i parametri “posizionali” devono precedere quelli “named”, significa che una volta
specificati parametri con nome non ne possono più essere passati come posizionali.

6.16 Funzioni con Parametri Multipli

1 def multiply (* args): # *args e’ una convenzione per indicare che la


funzione accetta un numero variabile di argomenti posizionali (non
nominati ).
2 z=1
3 for num in args:
4 z *= num
5 print (z)
6

7 multiply (1 ,2 ,3) # In questo caso , args = (1, 2, 3). output -> 6


8 multiply (1 ,2) # Output -> 2

6.17 Funzioni con Più Valori di Ritorno

1 def yfunc(t, v0): # Definizione della funzione yfunc che calcola la


posizione e la velocita ’
2 g = 9.81
3 y = v0*t - 0.5*g*t**2 # formula del moto rettilineo
uniformemente accelerato
4 dydt = v0 - g*t # velocita ’ del corpo al tempo t
5 return y, dydt
6 position , velocity = yfunc (0.6 , 3)
7 print (position , velocity )

6.18 Duck Typing


“If it walks like a duck, and quacks like a duck, it’s a duck”
I tipi delle variabili vengono definiti solo all’assegnazione dei riferimenti, per cui una funzione,
6.19. VARIABILI GLOBALI E LOCALI 47

a priori, non sa quali sono i tipi degli argomenti ed eventuali inconsistenze producono errori
solo quando la funzione viene eseguita. In questo modo Python implementa naturalmente il
polimorfismo, cioè una stessa funzione può essere usata per dati di tipo diverso.
Facciamo un esempio:
1 def sum_of (* items):
2 result = items [0] # Prende il primo elemento della tupla items e
lo assegna a result
3 for item in items [1:]: # Itera sugli elementi di items a partire
dal secondo
4 result = result + item # Somma ogni elemento al risultato
5 print ( result )

in particolare:

• item_of(2, 3, 5) ) 10

• item_of("2", "3", "5") ) ”235”

• item_of[ [2], [3, 5] ] ) [2, 3, 5]

• item_of[2, b] ) Error

6.19 Variabili globali e locali


Regola generale: quando ci sono più variabili con lo stesso nome, python prima cerca variabili
locali, poi quelle globali poi le funzioni/variabili di sistema.
1 numbers = [2.5 , 3, 4, -5]
2 print (sum( numbers )) # built - in Python func
3 sum = 500 # sum e’ int ( globale )
4 print (sum)
5 def myfunc (n):
6 sum = n + 1
7 print (sum) # sum e’ int locale
8 return sum
9 sum = myfunc (2) + 1 # update var . globale sum
10 print (sum)

in ogni caso si può forzare l’uso di variabili globali con la keyword global per esempio in
questo modo:
1 a = 2; b = 1 # globali
2

3 def f1(x):
4 return a*x + b
5

6 def f2(x):
7 global a
8 a=3
9 return a*x + b
48 CAPITOLO 6. PYTHON

10

11 f1 (2); print (a) # stampa 2


12 f2 (2); print (a) # stampa 3

6.20 Classi
Come in C++ consentono di creare oggetti che combinano dati (proprietà o attributi) e funzio-
nalità (metodi).
Una classe è una "struttura" che definisce come un oggetto dovrebbe comportarsi e quali dati
dovrebbe contenere. Mentre un oggetto è un’istanza della classe, ovvero una versione concreta
e specifica di quella struttura.
La forma più semplice di definizione di una classe è del tipo:

1 class NomeClasse :
2 <istruzione -1>
3 ...
4 <istruzione -N>

L’operazione di instanziazione (la “creazione” di un oggetto classe) crea un oggetto vuoto.


In molti casi si preferisce che vengano creati oggetti con uno stato iniziale noto. Perciò una
classe può definire un metodo speciale chiamato init() , come in questo caso:

1 def __init__ (self):


2 self.data = []

Tutti i metodi devono avere come primo argomento l’istanza stessa (che alla chiamata non
viene passata)

1 def func(self ,arg):


2 self. variabile = arg

6.20.1 Esempio

1 class vector :
2 def __init__ (self ,x,y):
3 self.x = x
4 self.y = y
5 def __add__ (self ,b):
6 return vector (self.x + b.x, self.y + b.y)
7 def __str__ (self):
8 return "(" + str(self.x) + "," + str(self.y) + ")"
9 a = vector (2, 2)
10 b = vector (3, 3)
11 c = a + b
12 print (c)
6.21. MODULI 49

6.20.2 Ereditarietà
Anche in Python si può ereditare una classe derivata da una classe base. La sintassi è:
1 class ClasseDerivata ( ClasseBase ):

Per esempio:
1 class vector :
2 def __init__ (self ,x,y):
3 self.x = x
4 self.y = y
5 def __add__ (self ,b):
6 return vector (self.x + b.x, self.y + b.y)
7 def __str__ (self):
8 return str(self.x) + "," + str(self.y)
9

10 class complex ( vector ):


11 def cong(self):
12 return complex (self.x, -self.y)
13 c = complex (1 ,2)
14 d = c.cong ()
15 print (d)

6.21 Moduli
I moduli sono le librerie di Python ed hanno il grosso vantaggio di essere portabili su vari SO
(no compilazione). In particolare file contenenti codice Python che possono includere funzioni,
classi, e variabili, o anche eseguire codice direttamente. I moduli permettono di organizzare e
riutilizzare il codice, semplificando lo sviluppo di programmi grandi e complessi.
Utilità:

• Consentono di separare il codice in file più piccoli e modulari.


• Possono essere utilizzati per raggruppare funzionalità correlate.

Python ha una vasta gamma di moduli integrati come: sys , os , math . Si possono poi
installare anche moduli (librerie) da terze parti tramite pip come: numpy , pandas .
Vediamo degli esempi di importazione di un modulo:

• Importazione base di un modulo:


1 import sys

• Importazione con cambio nome:


1 import sys as system

• Importazione di una sola parte del modulo:


1 from functools import lru_cache
50 CAPITOLO 6. PYTHON

• Importazione di tutto (senza bisogno di specificare il nome del modulo)


1 from os import *

Attenzione! Se definite una funzione con lo stesso nome di una presente nel modulo
“sovrascrivete” quella del modulo (perché viene usato senza utilizzarne il nome).

6.21.1 Sys
Il modulo sys fornisce funzionalità legate all’interprete Python. Chiamo il seguente file:
test.py

1 import sys
2 print (sys.argv) # Accede alla funzione "argv" del modulo "sys" e
stampa gli argomenti passati allo script

infatti per accedere alle funzioni di sys , è necessario usare il nome del modulo come prefisso.
allora in output:
> ./ test.py test arguments
[" file.py", "test", " arguments "]

6.21.2 Os
Il modulo os fornisce funzioni per interagire con il sistema operativo. Chiamo il seguente file:
test.py

1 import os
2 os. listdir (".") # Lista dei file nella directory corrente
3 print (files )

allora:
[ " inherit4 .jpg", " introduzione .aux", " introduzione .log", ...]

6.21.3 Numpy
Numpy è uno dei modulo più importanti, si tratta di un modulo per la gestione degli array
N-dimensionali (simile a list ma con calcolo vettoriale (e più efficiente)). Di fatto è un container
“mutabile” ed è una librearia fondamentale per il calcolo numerico.
1 import numpy as np;
2

3 a = np.array ([1 , 2, 3]) # Crea un array unidimensionale


4 print (type(a)) # Prints "<type "numpy. ndarray ">"
5 print (a) # Prints "[1 ,2 ,3]"
6 a[0] = 5 # Change an element of the array
7 print (a) # Prints "[5 , 2, 3]"

Varie opzioni:
6.21. MODULI 51

• È possibile specificare il tipo di dato di un array con l’argomento dtype :


1 a = np.array ([1 , 2, 3], dtype=" float64 ")
2 print (a) # Output : [1. 2. 3.]

• Si possono creare array n-dim:


1 mat = np.array ( [[ 1, 2, 3], [ 4, 2, 5]] )

Inoltre con il modulo Numpy abbiamo tante opzioni di inizializzazioni diverse, per esempio:
1 import numpy as np
2 x1 = np. linspace (0 ,100 ,100) # Crea 100 valori equispaziati tra 0 e
100
3 x2 = np.zeros (100 , float ) # Crea un array di 100 elementi
inizializzati a 0
4 x3 = np.ones (100 , float ) # Crea un array di 100 elementi
inizializzati a 1
5 x4 = np.ones (100 , float )*5 # Crea un array di 100 elementi
inizializzati a 5

Questo codice utilizza il modulo numpy per creare array con diverse modalità di inizializ-
zazione. Vediamo nel dettaglio cosa fanno queste righe e come funzionano.

• np.linspace(0, 100, 100) ) la sintassi prevede che: np.linspace(start, stop, num)


che genera un array di num valori equispaziati compresi tra start e stop (incluso). È
utile per creare sequenze numeriche per analisi o grafici.

• np.zeros(100, float) ) la sintassi è: np.zeros(shape, dtype) crea un array di dimen-


sione shape riempito con zeri. Dove l’argomento dtype specifica il tipo di dati (in questo
caso float). Nel nostro caso specifico un array di 100 elementi, tutti inizializzati a 0.0
(numeri in virgola mobile).

• np.ones(100, float) ) la sintassi: np.ones(shape, dtype) crea un array di dimensione


shape riempito con 1.

6.21.4 Numpy: slicing e array dinamici


Slicing
Lo slicing consente di accedere ad una sotto-sequenza (o sotto-array) degli elementi di un array,
specificando gli indici di inizio, fine e passo.
La sintassi per lo slicing è:
1 [ start :end:step]

dove:

• start ) Indice da cui partire (incluso).

• end ) Indice a cui fermarsi (escluso).


52 CAPITOLO 6. PYTHON

• step ) Incremento tra un elemento e il successivo.


vediamo un esempio di slicing:
1 import numpy as np
2

3 arr = np.array ([1 , 2, 3, 4, 5, 6, 7])


4 print (arr [1:5]) # Prende gli elementi da indice 1 a 4 ( escluso 5) ->
output [2, 3, 4, 5]
inoltre:
• Se start non è specificato, si assume 0 (inizio dell’array).
• Se end non è specificato, si assume la lunghezza dell’array.
• Se step non è specificato, si assume 1.
si utilizza la seguente sintassi:
1 print (arr [:5]) # Da inizio a indice 4 -> [1 2 3 4 5]
2 print (arr [2:]) # Da indice 2 a fine -> [3 4 5 6 7]
3 print (arr [::2]) # Ogni secondo elemento -> [1 3 5 7]
4 print (arr [:: -1]) # Ordine inverso -> [7 6 5 4 3 2 1]

Slicing Multidimensionale
Con NumPy, puoi fare slicing anche sugli array multidimensionali.
1 mat = np.array ([[1 , 2, 3],
2 [4, 5, 6],
3 [7, 8, 9]])
4

5 print (mat [:2 , :2]) # Prendi le prime due righe e le prime due colonne
l’output sarà:
1 [[1 2]
2 [4 5]]

Array Dinamici
NumPy non supporta nativamente array dinamici, perché gli array NumPy hanno una dimen-
sione fissa e ottimizzata per l’efficienza. Tuttavia, puoi utilizzare il metodo np.append per
aggiungere elementi a un array, creando un nuovo array che include gli elementi aggiunti.
Vediamo allora un esempio:
1 import numpy as np
2

3 a = np.array ([]) # Array vuoto iniziale


4 for i in range (0, 10): # Itera da 0 a 9
5 a = np. append (a, i) # Aggiunge l’elemento "i" all ’array
6

7 print (a)
6.22. PYROOT 53

6.21.5 Numpy: modifica delle dimensioni, i/o (input/output) su file


• numpy.shape(arr) ) controlla la forma dell’array.

• numpy.reshape(arr, shape) ) modifica la forma dell’array (senza cambiarne il contenu-


to) la “shape” è espressa come (nrow, ncol).

• numpy.flatten() ) converte in una dimensione.

• numpy.loadtxt(filename) ) legge un file organizzato a righe e colonne e ritorna la matrice


(2 array).

• numpy.savetxt(filename,arr) ) scrive su file l’array arr .

• numpy.flags ) restituisce informazioni sull’organizzazione dei dati dell’array in memo-


ria.

6.21.6 Scipy
Libreria scientifica di algoritmi e strumenti matematici da usare con numpy.

6.22 PyROOT
Si tratta della interfaccia a ROOT attraverso Python (è ancora un modulo in Python, una libreria
in C++).

• Stesse classe, stessi metodi di ROOT/C++

• Accesso ai metodi solo con .

• L’attivazione dell’editor grafico avviene tramite la chiamata a gApplication (oggetto


python pre-esistente, equivalente al puntatore gApplication in C++).

• Valida alternativa alle macro ROOT (non al ROOT compilato).

vediamo un esempio:
1 import math
2 from ROOT import *
3

4 fun1 = TF1("fun1", "sin(x)/x", -5* math.pi ,


5 5* math.pi )
6 fun1.Draw () # disegno la funzione fun1
7 gApplication .Run ()

nel dettaglio questo programma ha:

• import math ) Importa il modulo math di Python, che fornisce funzioni matematiche
come pi , sin , ecc.

• from ROOT import * ) Importa tutte le funzionalità della libreria ROOT.


54 CAPITOLO 6. PYTHON

• fun1 = TF1("fun1", "sin(x)/x", -5*math.pi, 5*math.pi ) ) definisco la funzione fun1


dove: TF1 è un oggetto di ROOT che rappresenta una funzione 1D in cui rispettivamente:
il primo parametro è il nome della funzione: "fun1" , il secondo parametro è la funzio-
ne matematica relativa, il terzo ed il quarto parametro invece dicono l’intervallo in cui
disegnare la funzione sull’asse delle x (dominio).
• gApplication ) È un oggetto ROOT responsabile della gestione dell’interfaccia grafica.

• Run() ) Avvia l’applicazione, mantenendo aperta la finestra grafica finché l’utente non
la chiude.
allora il codice fa:
• Crea una funzione sin (x)/x definita nell’intervallo [ 5⇡, 5⇡].
• Disegna la funzione utilizzando ROOT.
• Mantiene aperta la finestra grafica finché l’utente non decide di chiuderla.

6.23 Matplotlib
So che matplotlib è una libreria per creare grafici e visualizzazioni di dati in Python. Vediamo
un esempio:
1 import matplotlib . pyplot as plt # Importa il modulo pyplot della
libreria " Matplotlib " con l’alias "plt"
2 import numpy as np
3

4 x = np. linspace ( -5* np.pi , 5* np.pi , 100) # Dopo questa riga , l’array
"x" contiene 100 numeri tra -5pi e 5pi
5 y = np.sin(x)/x # NumPy esegue l’operazione di calcolare la funzione
su tutto l’array "x", anche se in 0 la funzione e’ indefinita np
gestisce bene e pone y=1
6 plt.plot(x, y) # Disegna il grafico con i valori di x sull ’asse
orizzontale e y sull ’asse verticale
7 plt.show () # Mostra il grafico in una finestra o nel tuo ambiente di
sviluppo

La sintassi generale di plot è la seguente:


1 plot(x, y, [fmt ])

dove x, y sono ascisse ed ordinate mentre [fmt] è la stringa per definire il formato della
linea e dei punti. Controlla colore, stile della linea e marker. Inoltre si può anche aggiungere
un altra variabile per argomenti opzionali per personalizzare il grafico (es. etichette, spessore
linea, titolo, ecc.). Per quanto riguarda [fmt] possiamo sostituirlo per esempio con i seguenti
parametri:

Caratteristica Simbolo
Colore "r" (rosso), "g" (verde), "b" (blu), "k" (nero)
Stile della linea "-" (continua), " " (tratteggiata), ":" (puntinata), "-." (trattini e punti)
Marker (punti) "o" (cerchio), "s" (quadrato), "⇤" (stella)
6.23. MATPLOTLIB 55

un esempio di applicativo è:
1 y1 = np.sin(x)
2 y2 = np.cos(x)
3

4 plt.plot(x, y1 , "r-", label="sin(x)")


5 plt.plot(x, y2 , "b--", label="cos(x)")
6 plt. legend () # Mostra la legenda
7 plt.show ()

Altri comandi per Matplotib sono:

6.23.1 figure
Crea una nuova finestra o area di disegno per un grafico. Esempio:
1 import matplotlib . pyplot as plt
2

3 plt. figure ( figsize =(8 , 6)) # Crea una figura con dimensioni
specificate
4 plt.plot ([1 , 2, 3], [4, 5, 6])
5 plt.show ()

dove in particolare figsize=(larghezza, altezza) è una tuple che specifica le dimensioni


della figura. All’interno si mette la definizione della figura in punti per pollice

6.23.2 subplots
Crea più grafici (sottoplot) all’interno di una singola figura. Per esempio:
1 import matplotlib . pyplot as plt
2 import numpy as np
3

4 x = np. linspace (0, 10, 100)


5 y1 = np.sin(x)
6 y2 = np.cos(x)
7

8 fig , ax = plt. subplots (1, 2, figsize =(10 , 4)) # dove la sintassi e ’:


1 riga , 2 colonne di sottoplot e poi figsize
9

10 ax [0]. plot(x, y1)


11 ax [0]. set_title ("Seno")
12

13 ax [1]. plot(x, y2)


14 ax [1]. set_title (" Coseno ")
15

16 plt.show ()

in particolare ogni sottoplot occupa una cella della griglia creata.


56 CAPITOLO 6. PYTHON

6.23.3 legend
Visto prima in un esempio. Crea una legenda che spiega cosa rappresentano le linee o i punti in
un grafico.

6.23.4 title, xlabel , ylabel titoli e nomi degli assi


Aggiungono titoli e etichette agli assi del grafico.
1 import matplotlib . pyplot as plt
2 import numpy as np
3

4 x = np. linspace (0, 10, 100)


5 y = np.sin(x)
6

7 plt.plot(x, y)
8 plt.title (" Grafico della funzione seno") # Titolo del grafico
9 plt. xlabel ("Asse X") # Etichetta asse X
10 plt. ylabel ("Asse Y") # Etichetta asse Y
11 plt.grid(True) # Mostra la griglia
12 plt.show ()

6.24 Ottimizzazione del Codice Python


Python è un linguaggio interpretato come abbiamo già detto. Ripetere le tecniche imparate in
C++ può non essere ottimale. Spesso è meglio affidarsi a funzioni dei moduli (che si basano su
codici C/C++).
Se il codice è tanto grande per sapere il tempo di esecuzione basta digitare:
time python3 script .py

Un esempio di ottimizzazione riguarda i loop, per esempio diciamo che abbiamo il seguente
codice:
1 v = np.array ([0 1 2 3 4 5 6 7 8 9])
2 v2 = []
3 for i in range (10):
4 v2 = np. append (v2 ,v[i]*v[i])

considerando le dimensioni del loop non è un problema che sia lento ma rimane il fatto che
è velocizzabile, infatti come abbiamo detto, alla fine di ogni loop Python risalva in memoria il
dato occupando spazio, un primo modo è usare la comprehension list , per esempio:
1 v = np.array ([0 1 2 3 4 5 6 7 8 9])
2 v2 = [val*val for val in v]

la comprehension list passa tutto l’array ad una struttura C sottostante. E dunque è più
veloce, ma si può fare ancora di meglio con il generator
1 v = np.array ([0 1 2 3 4 5 6 7 8 9])
2 v2 = (val*val for val in v)
6.25. STAMPARE CON LE F-STRING 57

Il generator é simile ma non genera tutta la lista ma un valore alla volta (più efficiente).
Altri buoni consigli per velocizzare Python sono:

• Usare la funzione join per concatenare le stringhe, ovvero invece di:


1 output = " Programming " + "is" + "fun"

usare:
1 output = " ".join ([" Programming ", "is", "fun"])

• Importare solo i moduli che e↵ettivamente servono. Scrivere allora:


1 from math import sqrt
2 a = sqrt (5)

invece di:
1 import math as m
2 a = m.sqrt (5)

6.25 Stampare con le f-string


In Python puoi usare le f-string (introdotte in 3.6+) per costruire stringhe in cui inserire di-
rettamente variabili, risultati di funzioni ed espressioni. Ecco uno scheletro di esempio, con
commenti che spiegano ogni pezzo:
1 import math
2

3 # Una funzione di esempio


4 def area_cerchio ( raggio ):
5 """ Ritorna l’area di un cerchio di raggio ’raggio ’."""
6 return math.pi * raggio **2
7

8 # Una variabile di esempio


9 r = 5.0 # raggio in metri
10

11 # Calcolo l’area chiamando la funzione


12 A = area_cerchio (r)
13

14 # Stampiamo tutto usando un’f- string :


15 # - ogni {...} dentro la stringa viene valutato come espressione
Python
16 # - possiamo formattare numeri , ad es. :.2f per due cifre decimali
17 print ( # questa e’ la stampa principale
18 f" Calcolo area del cerchio :\n"
19 f" raggio = {r} m\n" # inserisce il valore di r
20 f" area = {A:.2f} m^2\n" # area formattata con 2 decimali
21 f" doppio = {2*A:.2f} m^2" # espressione (2*A) direttamente
in linea
58 CAPITOLO 6. PYTHON

22 )
23

24 # Possiamo anche richiamare la funzione dentro l’f- string senza


25 # memorizzarne prima il risultato :
26 print (f"L’area con r={r} calcolata inline e’ { area_cerchio (r):.2f} m
^2")

Potrebbero piacerti anche