Python è un linguaggio di programmazione "inventato" dall'olandese Guido Van Rossum nel 1989, per correggere i difetti degli altri linguaggi di programmazione.
Caratteristiche di python:
10*13
a=1.25
b=3.14
a*b
import smtplib
host = smtplib.SMTP( "mb.fis.unical.it" )
ret = host.sendmail( "lprimavera@fis.unical.it", "leonardo.primavera@unical.it", "Ciao Leo!" )
host.quit()
import math
type(math.pi)
Python è un linguaggio in evoluzione. Nel passaggio dalla versione 2.7 alla versione 3 sono stati effettuati vari cambiamenti che rendono molti scripts scritti per la versione 2.7 incompatibili con la versione 3. Le differenze fondamentali riguardano l'introduzione delle stringhe Unicode per consentire codifiche avanzate rispetto a quella ASCII semplice, le istruzioni di input/output e i files. In queste lezioni utilizzaremo la versione 3 di python, tuttavia cercheremo di sottolineare le differenze con la versione 2.7 dove possibile. Quale delle due versioni utilizzare dipende dalle varie necessità: non tutte le librerie di python sono state portate dalla versione 2.7.x alla versione 3.x. Tuttavia, probabilmente, la versione 2.7 scomparirà prima o poi, anche se sul sito di python si possono tuttora scaricare entrambe!
Nei linguaggi di programmazione si utilizzano variabili per contenere dati numerici di vario tipo, caratteri, sequenze di caratteri (stringhe), ecc.
Le variabili possono essere di vario tipo: interi, reali (singola e doppia precisione), caratteri, stringhe.
Nei linguaggi compilati, il tipo di dato contenuto nelle variabili deve essere dichiarato prima di utilizzare la variabile e non può essere cambiato in seguito! In python una variabile non deve essere dichiarata, basta inizializzarla, e può essere re-inizializzata dovunque, cambiandole così il tipo!
Esempio:
a=100
type(a)
b=18.25
type(b)
s="Ciao!"
type(s)
2**10000
10.0**0.5
a=1.0+2.0j
a**0.5
x=10
a=x>5
a
Esempi:
a=12.2
s=str(a)
s
s="3.1415926"
float(s)
s='12345'
int(s)
In tutti i linguaggi di programmazione si definiscono i cosiddetti vettori, cioé variabili indicizzate in sequenza che contengono dati tutti dello stesso tipo (esempio: un insieme di numeri di cui calcolare la media, ecc.).
In python la stessa funzione è svolta dalle liste che però, a differenza dei vettori negli altri linguaggi di programmazione, possono contenere elementi eterogenei (cioé non dello stesso tipo!).
Esempi:
elenco=[1.2,3.45,7.36,8.55]
elenco
elenco=[1,2,3,"stella"]
elenco
I singoli elementi di una lista sono indicizzati tramite la loro posizione all'interno della lista con un indice che varia tra 0 ed il numero di elementi nella lista - 1, racchiuso tra parentesi quadre:
elenco=[1,3,5,7,9]
elenco[3]
Ogni elemento di una lista può essere modificato:
elenco[2]=101
elenco
Lo slicing di una lista è una operazione che permette di estrarre una parte della lista (nota che vengono restituiti gli elementi dal primo indice al secondo - 1!):
elenco[0:3]
Un indice negativo indica l'elemento della lista a partire dall'ultimo:
elenco[0:-2]
Se il primo o l'ultimo elemento non sono indicati, si assumono lo 0 e l'ultimo elemento:
Esempio (stampa gli ultimi 2 elementi):
elenco[-2:]
elenco[:2]
Per eliminare una serie di elementi da una lista, basta porli uguali alla lista vuota:
elenco[2:4]=[]
elenco
Lo slicing può contenere un terzo indice, che estrae gli elementi dal primo indice all'ultimo meno 1, a passi del terzo indice.
Esempio:
elenco=[1,2,3,4,5,6,7,8,9,10]
elenco[2:10:2]
Esempi:
elenco=[1,2,3,4,5]
elenco
elenco.append(10)
elenco
elenco.insert(1,11)
elenco
elenco.extend([20,30,40,50])
elenco
elenco.remove(20)
elenco
elenco.pop()
elenco
elenco.append(1)
elenco.count(1)
elenco
elenco.index(1)
elenco.pop(0)
elenco.index(1)
elenco.reverse()
elenco
elenco.sort()
elenco
elenco.sort(reverse=True)
elenco
L'operatore "in" restituisce True o False a seconda che il termine a sinistra esista o no nella lista!
Esempio:
ll=[1,3,5,7,9,11]
3 in ll
4 in ll
La funzione len(list) restituisce la lunghezza (il numero di elementi) in una lista.
Esempio:
ll=[10,20,30,40,50]
print(len(ll))
In quasi tutti i linguaggi esistono variabili con 2 indici, equivalenti alle matrici in matematica. In python si possono creare variabili con due (o più!) indici, come liste di liste.
Esempio:
arr=[[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
arr
arr[1]
arr[1][2]
Le stringhe in python sono sequenze di caratteri delimitati da singoli o doppi apici.
Due stringhe si possono concatenare con l'operatore "+":
s1="Ciao"
s2="mondo!"
s1 + ' ' + s2
Le stringhe possono ripetersi utilizzando l'operatore "*":
s1="Python e' "
s2="bello, "
s1 + s2 * 10 + "bello!"
Le stringhe possono contenere caratteri speciali (sequenze di escape) come "ritorno a capo", "tabulatori", "codici ascii" (in esadecimale!), ecc.
s1="Ricordati di mandare una email a:\n"
s2="\t"
s3="lprimavera\x40fis.unical.it"
print(s1 + s2 + s3)
Le stringhe possono estendersi su più righe inserendole tra tripli apici o virgolette:
s="""
Questo e' un esempio di una stringa molto lunga...
davvero molto lunga...
"""
print(s)
Le stringhe si comportano come liste, per cui si può effettuare lo slicing:
s="abcdefghilmnopqrstuvz"
s[1:-1]
s[::4]
Nota, peró, che a differenza delle liste, le stringhe sono immutabili, quindi non possono essere cambiate!
Esempio:
s="aeiou"
s[2]="c"
Esempi:
s=' abcde '
s.find("c")
s.strip()
s.replace(" ","<<")
s="Questa stringa contiene alcune virgole, che servono a migliorarne la lettura, ma a volte e' bene separare le varie frasi"
s.split(",")
'/'.join(["12","10","1492"])
Ulteriori metodi per le stringhe possono ottenersi con i comandi: dir(s) o help(s):
dir(s)
Le tuple sono simili alle liste, ma sono immutabili come le stringhe, quindi non possono essere modificate!
Vengono utilizzate spesso per creare arrays di una data dimensione in numpy.
Per definire una tupla, si debbono usare le parentesi tonde (le quadre sono riservate alle liste!).
Esempio:
a=(1,2,3,4,'mha!')
a[1:-1]
a[1]
a[1]=18
Un dizionario in python è un array associativo, cioé funziona come una lista, ma invece di fare riferimento al valore dei singoli elementi in base ad un numero progressivo, ci si riferisce ad essi tramite una chiave.
Per creare un dizionario occorre inizializzarlo con il costrutto "dict()", quindi aggiungervi le coppie chiave-valore.
Esempio:
dieta=dict()
dieta["Pasta"]=125
dieta["Carne"]=300
dieta["Frutta"]=150
dieta
Un dizionario può anche essere inizializzato con le parentesi graffe, seguite dalle chiavi e dai valori.
Esempio:
dd={"Carne": 300, "Frutta": 150, "Pasta": 125}
dd
Ogni valore può essere ricavato dalla rispettiva chiave.
Esempio:
print(dd["Carne"])
Nuovi elementi possono essere aggiunti al dizionario semplicemente aggiungendo una nuova chiave ed un nuovo valore. Analogamente, ogni coppia chiave-valore può essere rimossa con l'istruzione "del".
Esempio:
dieta["Insalata"]="A piacimento"
dieta
del dieta["Carne"]
dieta
Esempi:
dieta.keys()
dieta.values()
dieta.items()
dieta.has_key("Carne")
dieta.has_key("Frutta")
dieta.clear()
dieta
if cond1: ... elif cond2: ... else: ...Nota che:
Esempio:
if 1==2:
print("Falso")
elif 1==3:
print("Falso")
else:
print("Vero!")
for var in sequenza: ...
for var in "aeiou":
print(var)
Molto utile con il costrutto for è la funzione range(start,stop,jump), che restituisce una lista di interi che inizia da "start" fino a "stop"-1, a salti di "jump".
Esempio: calcola e stampa la somma dei primi 20 numeri pari...
somma=0
for i in range(2,21,2):
somma=somma+i
print(somma)
Notevole è la capacità di python di ciclare su due o più liste di numeri contemporaneamente prendendo i numeri a coppie (o triplette, ecc.) tramite la funzione zip(lista1, lista2, ecc.), che prende gli elementi delle varie liste uno ad uno e le restituisce come tuple.
Esempio:
for a,b in zip([1,2,3],['a','b','c']):
print(a, b)
Lo stesso effetto lo possiamo produrre ricordandoci che il metodo items di un dizionario produce una tupla chiave-valore.
Esempio:
dieta={"Pasta": 350, "Carne": 200, "Uova": 80, "Frutta": 250}
for tipo, calorie in dieta.items():
print("100 gr di ", tipo, "contengono ", calorie, " calorie")
while (condizione): ...
Esempio: somma i primi numeri dispari tra 1 e 21...
x=1
somma=0
while ( x <= 21 ):
somma=somma+x
x=x+2
print(somma)
Algoritmo semplice di ordinamento di una lista di numeri: si cerca il minimo della lista e si mette al primo posto, quindi si cerca il minimo degli elementi successivi e si mette al secondo e così via...
Esempio:
lista=[0.5, 0.8, 0.3, 1.2, 0.2, 0.1]
print("Lista iniziale: ", lista)
lungh=len(lista) # Calcola la lunghezza della lista
num_elem=0
while ( num_elem < lungh ):
# Cerca il minimo tra gli elementi restanti della lista
xmin=lista[num_elem]
xpos=num_elem
for i in range(num_elem,lungh):
if ( lista[i] < xmin ):
xmin=lista[i]
xpos=i
print("Minimo fra gli elementi della lista fra ", num_elem, " e ", lungh - 1, ": ", xmin, " nella posizione: ", xpos)
# Scambia il valore corrente nella lista con il minimo
if ( num_elem != xpos ):
temp=lista[num_elem]
lista[num_elem]=xmin
lista[xpos]=temp
# Stampa la lista parzialmente ordinata
print("Ordinamento parziale della lista: ", lista)
num_elem=num_elem+1
print("Lista finale ordinata: ", lista)
print(elem1, elem2, elem3, ecc., sep=" ", end="\n")
stampa quindi un insieme di valori separati da virgole, dopo averli convertiti in stringhe. I parametri sep e end sono opzionali e indicano il separatore da utilizzare quando si hanno più variabili da stampare (default: uno spazio!) e come terminare la linea (default: new-line!).
Nota python 2.7. In python 2.7.x print() NON è una funzione ma una istruzione. I dati da stampare NON devono perciò essere scritti tra parentesi!
Esempio: (nota come, se anche non ci sono spazi tra "per", a, "di" gli spazi vengono inseriti per il valore di default di "sep", cioé lo spazio bianco!)
a=100
print("Auguri per", a, "di questi giorni...")
L'istruzione print ritorna sempre accapo, a meno che si specifichi il flag: end=" ", per cui le stampe successive vengono accodate, separate da uno spazio, oppure un qualche altro valore.
Nota python 2.7.x: in python 2.7 per evitare che l'istruzione print vada daccapo, occorre utilizzare la virgola: ,, come in: print "Ora non vado daccapo...", che scrive sulla stessa linea, separato con uno spazio, una successiva istruzione print.
Esempio: stampa della tabellina...
for i in range(1,11):
for j in range(1,11):
print(i * j,end=" ")
print()
L'operatore % serve a costruire una stringa in maniera da sostituire opportune sequenze di formato con i valori delle variabili.
Esempio:
stringa="Ho mangiato %d uova e %d grammi di pasta..." % (3, 100)
print(stringa)
Si possono utilizzare dei campi numerici fra il simbolo "%" ed il formato ("f", "d", ecc.) per delimitare l'ampiezza del campo di stampa!
Esempio:
var=100
print("Facciamo stare larghi i numeri: %10d" % var)
Un numero negativo allinea a sinistra, invece che a destra.
Esempio: la tabellina di sopra, un po' più carina...
for i in range(1,11):
for j in range(1,11):
print("%-4d" % (i * j),end=" ")
print()
for i in range(1,11): for j in range(1,11): print "%-4d" % (i ∗ j), printUn simbolo
*
tra il "%" ed il formato indica una larghezza variabile che deve essere specificata tra le variabili.
Esempio:
largh=10
stringa1=">>>"
stringa2="<<<"
print("Ci troviamo a %*squesto%-*s punto!" % (largh, stringa1, largh, stringa2))
La funzione input serve per immettere un input da tastiera. Nota che la variabile immessa è sempre una stringa, quindi deve essere opportunamente convertita se si vuole un numero.
Nota python 2.7.x: l'analoga funzione in python 2.7.x è: s = raw_input(stringa).
Esempio: soluzione di una equazione di secondo grado...
print("Soluzione dell'equazione: a*x^2 + b*x + c = 0")
a = input("Inserisci a: ")
b = input("Inserisci b: ")
c = input("Inserisci c: ")
aa=float(a)
bb=float(b)
cc=float(c)
print("Soluzioni:")
print("x1 = ", (-bb+((bb*bb-4*aa*cc)**0.5))/(2*aa))
print("x2 = ", (-bb-((bb*bb-4*aa*cc)**0.5))/(2*aa))
oggetto = open( nome_file, metodo_di_accesso )dove:
Ultimate le operazioni di lettura/scrittura, il file può essere chiuso con il metodo close().
Nota python 2.7.x: l'analogo della funzione open() in python 2.7.x è: file(), con gli identici parametri.
Successivamente alla sua apertura, si possono leggere le righe da un file con il metodo readline(), che legge una intera stringa (incluso il newline!) dal file. Nota che se si arriva alla fine del file viene restituita la stringa vuota "".
Esempio:
f=open("prova.dat","r")
str=" "
while str != "":
str=f.readline()
print(str,end="")
f.close()
print(str,end="")
senza il quale verrebbero stampate delle linee vuote perché "str" contiene il newline letto dal file
Il metodo readlines() è più semplice in quanto produce una lista contenente tutte le linee del file.
Esempio:
f=open("prova.dat","r")
for linea in f.readlines():
print(linea,end="")
Il metodo write(stringa) scrive una stringa su un file (nota che non è possibile scrivere numeri!).
Esempio:
f=open("prova_out.dat","w")
for i in range(10):
f.write( "%d \t %f\n" % ( i+1, (i+1)**2.0 ) )
f.close()
Come leggere i dati appena scritti nel file?
Conviene leggere i dati come stringhe e convertirli in numeri tramite le funzioni di conversione. Questa è la maniera più flessibile di leggere dati da un file. Come vedremo, la libreria numpy ha delle funzioni di semplice utilizzo per leggere direttamente i dati contenuti in un file, ma non sempre questo è sufficiente e per letture da files che sono stati scritti in maniera complicata conviene sempre utilizzare la lettura con le stringhe e la conversione.
Esempio:
f=open("prova_out.dat","r")
for stringa in f.readlines():
vals=stringa.split("\t")
i=int(vals[0])
i2=float(vals[1])
i3=i*i
print(i, "\t", i2, "\t", i3)
f.close()
def nome_funzione( parametri ): ... return parametro
definisce una funzione con un nome, una lista di argomenti e che ritorna uno o più parametri.
Nota che non è obbligatorio ritornare un valore!
Esempio: definisce una funzione per calcolare il fattoriale di un numero...
def fact(n):
if n == 1:
return 1
else:
return n * fact(n-1)
print(fact(4))
print(fact(100))
E' possibile restituire più di un singolo valore, o anche nessun valore (nel qual caso la funzione esegue semplicemente delle operazioni in maniera ripetitiva per vari valori dei parametri.
Esempio:
# Funzione che stampa una stringa n volte; NON ritorna valori
def stampa_stringa(stringa,n):
print(stringa * n,end="")
print()
stampa_stringa("Ciao!", 10)
# Funzione che ritorna due liste, una con i numeri da 1 ad n, l'altra con i loro quadrati
def doppia_lista(n):
nums=range(n)
lista1=[]
lista2=[]
for i in nums:
lista1.append(i+1)
lista2.append((i+1)**2.0)
return lista1, lista2
l1, l2 = doppia_lista(10)
print(l1, l2)
E' possibile definire delle funzioni con dei parametri opzionali, cioé dei valori che, se non specificati, assumono dei valori predefiniti, altrimenti il valore specificato.
Esempio:
def stampa_stringa(stringa,n=1):
print(stringa * n,end="")
print()
stampa_stringa("ok!")
stampa_stringa("Ciao",10)
E' anche possibile cambiare l'ordine dei parametri, purché si specifichi il parametro, il segno "=" ed il valore nella chiamata.
Esempio:
stampa_stringa(n=5,stringa="Ok! ")