Upload
avak
View
94
Download
4
Embed Size (px)
DESCRIPTION
Python : Introduzione al linguaggio ed esercizi. Marco Di Felice Sistemi Operativi , AA 2010-2011 Dipartimento di Scienze dell’Informazione Universita ’ degli Studi di Bologna. … Da dove iniziare. - PowerPoint PPT Presentation
Citation preview
Python: Introduzione al linguaggio ed esercizi
Marco Di Felice
Sistemi Operativi, AA 2010-2011
Dipartimento di Scienze dell’InformazioneUniversita’ degli Studi di Bologna
… Da dove iniziare
Qualche testo consigliato (e reperibile ON-LINE) per iniziare a programmare in Python:
How to think like a Computer Scientist. Learning with Python – A.Downey, J. Elkner, C. Meyers (GNU)
Dave into Python – Mark Pilgrim-
Il linguaggio PyhtonIdeato negli anni ‘80 da G. van Rossum
Versione attuale del linguaggio: 2.6
Prevalentemente object-oriented, ma multi-paradigma (object-oriented, procedurale, funzionale, etc)
Utilizza un interprete per l’esecuzione (non compilato)
Dispone di librerie molto vaste per: parsing (HTML/XML), networking, GUI, accesso a database, Web scripting, etc
Eseguire programmi Pyhton
Due possibili modalita’ di esecuzione:
1. Modalita’ interattiva$$ python >> a=3+5
2. Modalita’ con Program Files $$ vim myprogram.py $$ python myprogram.py
Variabili, Tipi, Espressioni In un programma Python non e’ necessario dichiarare
le variabili ed il loro tipo. Il tipaggio avviene dinamicamente a run-time.
Assegnamento di valori a a variabili.message=“Hello world”a=5x=2.34
>>type(message)<type ‘str’>
Espressioni Operatori matematici: + - / * // ** %Operatori logici: and or notOperatori di confronto: >, <, >=, <= Assegnamento: =Costanti Booleane: True False
Python <versione 2.2.1 Non esiste il tipo di dato booleano. FALSO: 0, stringa vuota “ “, lista vuota [], dizionario vuoto {}
Costrutti di selezioneCostrutti di selezione: if-else / if-elif- … - else
IF CONDIZIONE:
SEQUENZA DI COMANDI RAMO IF
ELSE
SEQUENZA DI COMANDI RAMO ELSE
if x==y:
print x, “ and “,y,” are equal “
else
print x, “ and “,y,” are different “
Costrutti di iterazioneCostrutti di iterazione: while
WHILE CONDIZIONE:
SEQUENZA DI COMANDI DEL CICLO
X=1.0
while x<10.0:
print x,” “,math.log(x)
x=x + 1.0
Indentazione e BlocchiPython utilizza l’indentazione (e non le parentesi
graffe) per distinguere l’inizio e la fine di un blocco (es. Il codice da eseguire all’interno di un ciclo).
Per questo motivo, indentare bene il codice e’ fondamentale!
while n>0: while n>0:n=n-1 n=n-1 print n print n
DIVERSO!!
Dichiarazione di FunzioniKeyword def per identificare l’inizio di una funzione
DEF nomeFUNZIONE (argomenti):CORPO della FUNZIONERETURN valore (opzionale)
Per richiamare una funzione:nomeFUNZIONE (argomenti)
Funzioni LambdaPython consente di definire al volo piccole
funzioni in una sola riga (lambda-funzioni).>> g= lamdba x: x**2>> g(4)
>> 16
• Le funzioni lambda non possono contenere comandi e non possono contenere piu’ di un’espressione
Dichiarazione di Funzioni(ES1): Scrivere il codice della funzione fattoriale:
Dichiarazione di Funzioni (ES1): Scrivere il codice della funzione fattoriale:
# Factorial functiondef factorial(n):if (n==0):return 1elsereturn n*factorial(n-1)
>> print factorial(4)>> 24
Parametri e FunzioniPython consente di definire funzioni con parametri
opzionali; se la funzione e’ chiamata senza argomento, l’argomento prende il valore predefinito (indicato nella signature della funzione).
def power(a,b=2):
return a**b
>> power(4,3)
>> power(4)
Operazioni su Stringhe In Python, una stringa e’ una lista di caratteri.
message=“Hello world”
La funzione len restituisce la lunghezza>> len(message)>> 11
L’operatore [] consente di accedere ai singoli caratteri che compongono la stringa:>> print message[0]>> ‘H’
Operazioni su Stringhe >> message=“Hello world”
>> print message [0]>> ‘H’>> print message [2:3]>> ‘l’ (Seleziona una sottostringa)>> print message [2:]>> ‘llo World’ (Seleziona una sottostringa)>> print message [-1]>> ‘d’
Operazioni su StringheLe stringhe sono liste IMMUTABILI.
message[0]=‘G’ NON SI PUO’ FARE!!
Libreria di funzioni su stringheimport string
Liste predefinite della classe string:string.lowercasestring.uppercaseString.digits
Operazioni su StringheL’operatore for … in consente di ciclare su tutti
gli elementi di una listafor c in str:
print c
L’operatore in verifica la presenza di un carattere in una stringa.
if c in str:print “Found!”
Operazioni su Stringhe(ES2): Scrivere una funzione check_string(str)
che riceve in input una stringa, e ritorna 0 se la stringa str e ben formata, 1 altrimenti.
Assumiamo che una stringa sia ben formata se contiene solo caratteri minuscoli.
Operazioni su Stringheimport stringdef check_string(str):for c in str:if not(c in string.lowercase):return 0return 1
>> print check_string(“hello), “ “, check_string(“Hello”)>> 1 0
Liste di ElementiIn Python, una lista e’ un insieme ordinato di valori,
in cui ciascun valore e’ identificato da un indice.[] LISTA VUOTA[1,2,3,4,5][“Hello”, “World”, “Python”]
Gli elementi possono essere eterogenei:
[“Hello”,1,3.4,5]
[“Hello”, [1,2], 4, 10, [1,2,3]]
Liste di ElementiCome con le stringhe:
[] per accedere ad un elemento della lista
in verifica la presenza di un elemento in una lista
len restituisce la lunghezza della lista
+ concatena due liste
* ripete una lista un dato numero di volte
Liste di ElementiA differenza delle stringhe, le liste sono MUTABILI
a=[1,2,3,4], a[0]=-1
del per rimuovere un elemento della listadel a[0]
append aggiunge un elemento alla lista (in fondo)
insert aggiunge un elemento in una posizione specificaa.append(6) a.insert(0,6)
Liste di ElementiLe liste sono passate per riferimento e non per
valore.
a=[1,2,3]
b=a
a a
b b[1,2,3] [1,2,3]
[1,2,3]
• … E se invece b=a[:] ??
Liste di Elementi(ES3) Data la lista seguente:
a=[[1,2],3,4,5,6]
Definire quali delle operazioni sono valide e quali no. a[0][0]=5
print a[0][-3]
print a[0][-1]
a[5]=‘b’
a[2:4]=[2]
Liste di Elementi (ES4) Determinare l’output del programma
seguente:a=[‘a’,’b’,[‘b’,’c’],1,2,3]del a[0]a[1][0]=‘a’c=a[2:4]d=a[1]e=c+dprint e
Liste di Elementi (ES5) Determinare l’output del programma
seguente:def fun(a):return a[2:]a=[1,2,3,4,5]b=ab[3]=6c=fun(a)c[2]=3print c
Liste di Elementi(ES6) Scrivere un programma che legge
input 5 numeri interi da tastiera. Ogni numero letto viene inserito in una lista solo se non e’ un duplicato di un numero gia’ letto. Se e’ un duplicato, il programma continua la lettura da tastiera finche’ un numero non duplicato viene digitato. Dopo aver letto i 5 valori, il programma ne calcola la media e la stampa a video.
Liste di Elementi# Read an integer value from the keybord
def read_number():
message="Please insert an integer value "
read=input(message)
return read
# Returns a list of 5 non-replicated values
def read_list_values():
listread=[]
# Number of readings from the input
numread=0
while (numread <5):
val=read_number()
# Check if the reading is valid
if not (val in listread):
listread.append(val)
numread+=1
else:
print "This is a duplicated value ..."
return listread
Liste di Elementi
# Main programlistv=read_list_values()
# Initialize the average valueaverage=0.0
# Compute the average valuefor val in listv: average+=val
average=average / len(listv)
print " The average value is ...", average
Liste di ElementiList comprehension => Tecnica compatta per
mappare una lista in un’altra applicando una funzione a ciascuno degli elementi della lista.
>> li=[1,2,3,4,5]
>> li2=[elem * 4 for elem in li]
>> print li2
>> [4,8,12,16,20]
Liste di ElementiList comprehension + Filtri => E’ possibile
aggiungere dei filtri, in modo che alcuni elementi vengano mappati ed altri restino alterati.
>> li=[1,2,3,4,5]>> li2=[elem * 4 for elem in li if elem >2 ]
>> print li2
>> [12,16,20]
Liste di Elementi(ES7) Scrivere una funzione
check_sum_present(li, value) che prende in input una lista di interi (si assume senza elementi duplicati) ed un valore e verifica se nella lista ci sono due elementi a,b tali che a+b=value. La funzione deve restituire la lista di tutte le coppie [a,b] che soddisfano la condizione.
Liste di Elementidef check_sum_present(li, value): return [ [elem,value-elem] for elem in li if (((value-elem) in li) and (value-elem !=elem )) ]
li=[1,2,3,4,5,6,7,8]print check_sum_present(li,11)
Tupla di ElementiUna tupla di elementi e’ simile ad una lista, ma a
differenza delle liste e’ IMMUTABILE.tuple=1,2,3,4,5tuple=(‘a’,’b’,’c’,’d’,’e’)
Le tuple sono utili per fare swap di variabili o assegnamenti multipli:
y, x = x, y
a, b, c, d = 1, ‘Hello’, 4, 5.6
Tupla di ElementiA che servono le tuple?
Le tuple sono piu’ veloci delle liste => utilizzare le tuple nel caso in cui si debba solo iterare su un insieme di valori e non si debba modificarli.
Consentono di proteggere dalla scrittura i dati che non devono essere modificati.
Le tuple, a differenza delle liste, possono essere usate come chiavi di un dizionario.
DizionariUn dizionario e’ un insieme di coppie: <chiave,
valore>, in cui la chiave non deve essere necessariamente un intero (a differenza delle liste).
dict={}
dict[‘Mario’]=“0861343242”
dict[‘Monica’]=“086243434”
dict{‘Mario’:’0861343242’, ‘Monica’: …}
Dizionari Il metodo len restituisce il numero di elementi
Il metodo keys resistuisce la lista delle chiavi
Il metodo values restituisce la lista dei valori
Il metodo del elimina un elemento dalla lista
Il metodo clear cancella tutto il contenuto di un dizionario
>> print dict.keys()
>> print dict.values()
>> del dict[2]
Dizionari Il metodo get restituisce il valore associato ad una
certa chiave:>> print dict.get(“Mario”)>> print dict.get(“Mario”,”Nome non trovato”)
• Il metodo has_key ritorna 1 se la chiave appare nel dizionario, 0 altrimenti.
>> print dict.has_key(“Mario”)
>> True
DizionariNon possono esserci duplicazioni di chiavi in un
dizionario.
Gli elementi di un dizionario NON sono ordinati.
Valori e chiavi possono assumere qualsiasi tipo. Non necessariamente tutte le chiavi devono avere lo stesso tipo.
dict={“0”:120,”Marco”:32,”1.0”:[1,2,3]}
Dizionari(ES8) Scrivere un programma che calcola il
prodotto di due matrici (supponiamo entrambe le matrici abbiano dimensione NxN)
(ES9) Ottimizzare il programma precedente nel caso in cui le matrici siano sparse (cioe’ gran parte dei valori delle matrici siano settati a 0)
Dizionari (ES10) Indicare l’output del programma seguente.
str=“hello”
dict={‘h’:1,’e’:2,’l’:3}
val=0
for c in str:
val=val+dict.get(c,-1)
print val
Dizionari(ES11) Indicare l’output del programma
seguente.def fun(d,x):
if d.has_key(x):d[x]=3
dic={‘a’:1,’b’:2,’c’:4}dic2=dic.copy()dic3=dicdel dic[‘a’]fun(dic2,’a’)fun(dic3,’a’)dic2[‘b’]=dic2[‘a’]+dic3.get(‘a’,-2)print dic2[‘b’]
Classi ed OggettiPython e’ un linguaggio ad oggetti; l’astrazione
di classi ed oggetto ha molti punti in comune con altri linguaggi di programmazione (es. Java)
class Point:
def __init__(self,x=0,y=0):
self.x=x
self.y=y
Classi ed Oggetti Il metodo __init__ e’ Il costruttore della classe.
self e’ il riferimento all’oggetto corrente, tramite il quale si puo’ accedere ad i campi dell’oggetto corrente. E’ il primo parametro di ogni metodo della classe, ma non deve essere passato dal chiamante.
class Point:def distance(self, other):…p= Point(10,20)p1=Point(20,30)p.distance(p1) => NON: p.distance(p,p1)!!
Classi ed OggettiCome in altri linguaggi ad oggetti, e’ possibile fare
overloading di operatori built-in (es. addizione, moltiplicazione, sottrazione, etc)
def __add__(self, other):
return Point(self.x+other.x,self.y+other.y)
Point p1=new Point(x1,y1)
Point p2=new Point(x2,y2)
p3=p1 + p2
Classi ed OggettiCome in altri linguaggi ad oggetti, e’ possibile
creare gerarchie di classe tramite l’ereditarieta’.
Come C++, Python supporta l’ereditarieta’ multipla.
Per indicare che la classe Point3D e’ figlia della classe Point:
class Point3D(Point):
Classi ed OggettiEsistono alcuni metodi di classe “speciali”:
• __repr__ ritorna una rappresentazione di un oggetto sotto forma di una stringa
• __cmp__ e’ utilizzato quando si effettua il confronto tra classi (overloading dell’operatore ==)
• __len__ ritorna la lunghezza dell’oggetto
• __delitem__ richiamato da del istanza[chiave]
Classi ed OggettiE’ possibile definire metodi privati che non
possono essere referenziati all’esterno della classe.
La distinzione tra metodi pubblici e metodi privati si basa esclusivamente sul nome.
Se il nome di un metodo o attributo inizia con (man non finisce con) due underscore, e’ privato; ogni altra cosa e’ pubblica.def __myfunction():
Classi ed OggettiCome in Java/C++, Python consente la
manipolazione delle eccezioni tramite I blocchi try…except
Il comando raise viene usato per lanciare un’eccezione.
try:
fsock=open(“file.dat”,”r”)
except IOError:
Classi ed Oggetti(ES12) Indicare l’output del programma
seguente.import copyclass Obj: p=Obj()
pass p.a=5def fun(p): p.b=7
p2=copy.copy(p) p2=pif (p2.b==7): p2.b=5p2.b=10 p3=fun(p)else: print p3.a+p3.bp2.a=4return p2
Classi ed Oggetti(ES13) Implementare una classe
Stack con I metodi push, pop e is_empty.
Classi ed Oggetticlass Stack: # Class initializer def __init__(self): self.values=[] # Push a value on top of the stack def push(self,value): self.values.append(value) # Return the value on top def pop(self): if len(self.values) > 0: return self.values.pop() else: raise ValueError # Check if there are elements in the stack def is_empty(self): return (len(self.values) == 0)
IteratoriTutti I tipi di sequenza incorporati in Python
supportano gli iteratori tramite ciclo for.for value in sequence:DO SOMETHING
E’ possibile costruire degli iteratori su classi arbitrarie definendo I seguenti metodi:- __iter__(): restituisce l’oggetto iteratore- next(): restituisce l’elemento successivo
Iteratori(ES14) Implementare la classe
CircularQueue che consente di definire delle liste circolari in Python.
Iteratori# Implements a Circular Queueclass CircularQueue: def __init__(self,values): self.values=values
def __iter__self(self): return self
# Iterator function def next(self): if (len(self.values) > 0): self.values=self.values[1:] + [self.values[0]] return self.values[-1] else: raise ValError
Iteratori(ES15) Implementare la classe Tree
che consente di costruire degli alberi (generici). Definire un iteratore della classe che consente di fare visite in profondita’ dell’albero.
IteratoriUn iteratore puo’ essere utilizzato per generare
sequenze di valori. Un valore viene prodotto su richiesta quando
necessario.La sequenza di valori puo’ essere infinita.
(ES16) Definire tramite iteratori la classe Factorial che costruisce la sequenza dei fattoriali 1!, 2!, 3!, 4! … etc
Iteratoriclass Factorial: def __init__(self): self.fact=0 self.val=1
def __iter__(self): return self
def next(self):
(self.val,self.fact,oldval)=(self.val*(self.fact+1),self.fact+1,self.val) return oldval
for i in Factorial(): print i if i>30: break
GeneratoriUn generatore e’ un’entita che genera iteratori.
Un generatore e’ una funzione che si richiama ripetutamente: ogni volta che viene richiamata, l’esecuzione non ricomincia da capo, ma dal punto di codice in cui la precedente chiamata ha restituito un valore.
Il comando yeld specifica il punto in cui un generatore deve ritornare un valore.
Generatori(ES17) Indicare l’output del programma
seguente.def gen():
val=2while:
yeld valval=val*2
count=0for i in gen():
if (count >=10):break
else:print icount+=1
Generatori(ES18) Scrivere una funzione generatrice di
numeri primi (usando i generatori di Python).
Generatoridef prime_num(): n=2 prime=[] while True: if not[f for f in prime if n%f ==0]: yield n prime.append(n) n=n+1
# Print out all the prime numbers <100for i in prime_num(): if (i> 100): break print i
Generatori(ES19) Scrivere una funzione permutation(li)
che genera tutte le possibili permutazioni di una lista presa in input
>> permutation([1,2,3])
>> [[1,2,3],[1,3,2],[2,3,1][2,1,3],[3,1,2],[3,2,1]]
Generatoridef permutation(list): if len(list)<=1: yield list else: for i in range(0,len(list)): for tail in permutation(list[:i] + list[i+1:]): yield [list[i]] + tail
for i in permutation([1,2,3,4]):print i
Generatori(ES20) Scrivere una funzione powerset(li) che
prende in input una lista e stampa tutti i possibili sottoinsiemi della lista (insieme potenza).
>> power_set([1,2,3])
>> [[1],[2],[3],[1,2],[1,3],[2,3],[1,2,3]]
Generatoridef powerset(li): if len(li) <=1: yield li yield [] else: for item in powerset(l[1:]): yield [li[0]] + item yield item
for i in powerset([1,2,3]): print i
Moduli e LibrerieIl modulo os dispone di molte funzioni utili per
manipolare file e processi.
listdir(path) ritorna il contenuto di una directory (in una lista).
chdir(path) cambia la directory corrente a path
chmod, chown, mkdir, rmdir, getcwd(), mknod() …
getlogin(), getpid(), getuid(), getppid(), …
Moduli e LibrerieIl modulo os dispone di molte funzioni utili per
manipolare file e processi.
import os
print "Current directory is ",os.getcwd()
print "Current login is ",os.getlogin()
print "Current Process id is ",os.getpid()
Moduli e Librerie(ES21) Scrivere un programma che fa
scanning della rete, nel range di indirizzi da 192.168.100.60 a 192.168.100.70. A ciascuna macchina della rete devono essere inviati 2 pacchetti ping, ed in base all’esito del comando il programma deve visualizzare il messaggio: “No response” o “Alive”.
Moduli e Librerieimport osimport reimport timeimport syslifeline = re.compile(r"(\d) received")report = ("No response","Partial Response","Alive")print time.ctime()for host in range(60,70): ip = "192.168.100."+str(host) pingaling = os.popen("ping -q -c2 "+ip,"r") print "Testing ",ip, sys.stdout.flush() while 1: line = pingaling.readline() if not line: break igot = re.findall(lifeline,line) if igot: print report[int(igot[0])]print time.ctime()
Programmazione di ReteIl modulo socket implementa i costrutti
principali per la programmazione di rete tramite socket (C-like).
socket(family,type) crea un nuovo socketfamily: AF_UNIX, AF_INET, AF_INET6type: SOCK_STREAM (tcp),
SOCK_DGRAM(udp)
Programmazione di Retebind(host, port): collega il socket ad un
host name e ad una porta specificataaccept(): accetta connessioni da un
client. Restituisce: (nuovo socket per comunicare con il client, indirizzo del client)
send(), recv(): inviano/ricevono daticlose(): chiude il socket
Programmazione di Rete(ES22) Scrivere una semplice
applicazione di rete Client-Server. Il client resta in attesa di ricevere un messaggio da tastiera e lo spedisce al Server, che lo stampa a video.
Programmazione di Reteimport socket
class SocketClient: def __init__(self,host, port): size=1024 while True: message="Insert a message to send " read=raw_input(message) s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect((host, port)) s.send(read) s.close()
message="Insert Q to exit … " read=raw_input(message) if (read == "Q"): break
sc=SocketClient("localhost",5000)
Programmazione di Reteimport socket
class ServerSocket: def __init__(self): self.host="localhost" self.port=5000 self.size=1024 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.bind((self.host,self.port)) s.listen(5) while True: client, address = s.accept() data = client.recv(self.size)
print " [SERVER ECHO] Receiving data from ",address," Message: ",data client.close()
ss=ServerSocket()
Programmazione di Reteselect(input, output, exception, [timeout]): gli
argomenti sono liste di socket che attendono per input/output/eccezioni.
La chiamata della select e’ bloccante se timeout non e’ impostato
Ritorna una tupla di tre liste: sottoinsieme dei socket in input che hanno input/output/eccezioni.
Programmazione di Rete(ES23) Modificare la configurazione
del Server dell’esercizio ES21 in modo che sia in grado di gestire piu’ connessioni in ingresso dai Client tramite la select.
Programmazione di Reteclass ServerSocket: def __init__(self): self.host="localhost" self.port=5000 self.size=1024 server=socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind((self.host,self.port)) server.listen(5) input= [server] while True: inputready,outputready,exceptionready= select.select(input,[],[]) for c in inputread:
if (c==server): client, address = server.accept() input.append(client) else: data = c.recv(self.size)
c.close() input.remove(c)
Programmazione di Rete
TWISTED: framework per il networking che consente di sviluppare applicazioni di rete in Python
Consente di creare: protocolli di rete, SMTP, HTTP, SSH proxy, filtri di traffico, etc
http://twistedmatrix.com/
ThreadIl modulo threading offre una libreria di
funzioni per lavorare con i thread.Per creare un thread, occorre creare una
classe figlia di threading.Thread.Per avviare il thread, occorre eseguire il
metodo start.Il codice del thread e’ contenuto nel run.
ThreadThread diversi potrebbero avere
necessita’ di condividere strutture dati.METODO 1. => utilizzo del modulo
Queue
Implementa lock e metodi synchronized per l’accesso a strutture condivise.
Metodi: get, put, join, task_done, …
Thread(ES24) Modificare l’esercizio E20 in
modo da suddividere l’operazione di scansione della rete tra N thread.
Threadimport osimport reimport timeimport sysimport Queueimport threading
lifeline = re.compile(r"(\d) received")report = ("No response","Partial Response","Alive")print time.ctime()queue=Queue.Queue()
class ThreadScanner(threading.Thread): def __init__(self, queue): threading.Thread.__init__(self) self.queue = queue
Thread def run(self):
while True:
host = self.queue.get() ip = "192.168.100."+str(host) pingaling = os.popen("ping -q -c2 "+ip,"r") print "Testing ",ip, sys.stdout.flush() while 1: line = pingaling.readline() if not line: break igot = re.findall(lifeline,line) if igot: print report[int(igot[0])] self.queue.task_done()
Thread# List of Threadsfor i in range(0,5): t=ThreadScanner(queue) t.start()
for host in range(60,70): queue.put(host)
queue.join()
print time.ctime()
ThreadOltre al modulo Queue, Python mette a
disposizione i tradizionali meccanismi di sincronizzazione per l’accesso a strutture dati condivise:Lock: metodi acquire – releaseRe-Entrant Lock (RLocks)Semafori