Python - Dipartimento di Informatica

Download Report

Transcript Python - Dipartimento di Informatica

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

 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 Pyhton

 Ideato 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 1.

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=5 x=2.34

>>type(message)

Espressioni

 Operatori

matematici

: + - / * // ** %  Operatori

logici

: and or not  Operatori

di confronto

: >, <, >=, <= 

Assegnamento

: =  Costanti Booleane: True False  Python

Costrutti di selezione

 Costrutti 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 iterazione

 Costrutti 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 Blocchi

 Python utilizza l’

indentazione

graffe) per distinguere (e non le parentesi 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: n=n-1 print n

DIVERSO!!

while n>0: n=n-1 print n

Dichiarazione di Funzioni

 Keyword def per identificare l’inizio di una funzione

DEF

nomeFUNZIONE (argomenti): CORPO della FUNZIONE RETURN valore (opzionale)  Per richiamare una funzione: nomeFUNZIONE (argomenti)

Funzioni Lambda

 Python 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 function def factorial(n): if (n==0): return 1 else return n*factorial(n-1) >> print factorial(4) >> 24

Parametri e Funzioni

 Python 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 Stringhe

 Le stringhe sono liste

IMMUTABILI

.

message[0]=‘G’

NON SI PUO’ FARE!!

 Libreria di funzioni su stringhe import string Liste predefinite della classe string: string.lowercase

string.uppercase

String.digits

Operazioni su Stringhe

 L’operatore for … in consente di ciclare su tutti gli elementi di una lista for 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 Stringhe

import string def check_string(str): for c in str: if not(c in string.lowercase): return 0 return 1 >> print check_string (“hello), “ “, check_string(“Hello”) >> 1 0

Liste di Elementi

 In Python, una lista cui ciascun valore e’ un insieme ordinato di valori, in 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 Elementi

Come

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 Elementi

A differenza

delle stringhe, le liste sono

MUTABILI

a=[1,2,3,4], a[0]=-1  del per rimuovere un elemento della lista del a[0]  append aggiunge un elemento alla lista (in fondo)  insert aggiunge un elemento in una posizione specifica a.append(6) a.insert(0,6)

Liste di Elementi

 Le liste sono passate

per riferimento

e non per valore.

a=[1,2,3] b=a a a [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+d print e

Liste di Elementi

 (

ES5

) Determinare l’output del programma seguente: def fun(a): return a[2:] a=[1,2,3,4,5] b=a b[3]=6 c=fun(a) c[2]=3 print 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 program listv=read_list_values() # Initialize the average value average=0.0

# Compute the average value for val in listv: average+=val average=average / len(listv) print " The average value is ...", average

Liste di Elementi

 List 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 Elementi

 List 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 Elementi

def 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 Elementi

 Una tupla di elementi differenza delle liste e’ simile ad una lista, ma a e’

IMMUTABILE

.

tuple=1,2,3,4,5 tuple=(‘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 Elementi

A 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

.

Dizionari

 Un

dizionario

e’ un insieme di coppie: , 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

Dizionari

 Non 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=dic del dic[‘a’] fun(dic2,’a’) fun(dic3,’a’) dic2[‘b’]=dic2[‘a’]+dic3.get(‘a’,-2) print dic2[‘b’]

Classi ed Oggetti

 Python 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 Oggetti

 Come 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 Oggetti

 Come 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 Oggetti

Esistono 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 Oggetti

 E’ 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 Oggetti

 Come 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 copy class Obj: pass def fun(p): p2=copy.copy(p) if (p2.b==7): p2.b=10 p=Obj() p.a=5 p.b=7 p2=p p2.b=5 p3=fun(p) print p2.a=4 return p2

Classi ed Oggetti

 (

ES13

) Implementare una classe

Stack

con I metodi

push

,

pop

e

is_empty.

Classi ed Oggetti

class 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)

Iteratori

 Tutti 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

CircularQueue

che la classe consente definire delle liste circolari in Python.

di

Iteratori

# Implements a Circular Queue class 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.

Iteratori

 Un 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

class Factorial: def __init__(self): self.fact=0 self.val=1 def __iter__(self): return self def next(self):

Iteratori

(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

Generatori

 Un

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=2 while: yeld val val=val*2 count=0 for i in gen(): if (count >=10): break else: print i count+=1

Generatori

 (

ES18

) Scrivere una funzione generatrice di numeri primi (usando i generatori di Python).

Generatori

def 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 <100 for 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]]

Generatori

def 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]]

Generatori

def 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 Librerie

 Il 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 Librerie

 Il 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 Librerie

import os import re import time import sys lifeline = 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 Rete

 Il modulo socket implementa i costrutti principali per la programmazione di rete tramite socket (C-like).

 socket(family,type) crea un nuovo socket family: AF_UNIX, AF_INET, AF_INET6 type: SOCK_STREAM (tcp), SOCK_DGRAM(udp)

Programmazione di Rete

 bind(host, port) : collega il socket ad un host name e ad una porta specificata  accept() : accetta connessioni da un client.

Restituisce: (nuovo socket per comunicare con il client, indirizzo del client)  send(), recv() : inviano/ricevono dati  close() : 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 Rete

import 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 Rete

import 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 Rete

 select(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 Rete

class 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/

Thread

 Il 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.

Thread

 Thread 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.

Thread

import os import re import time import sys import Queue import 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 Threads for i in range(0,5): t=ThreadScanner(queue) t.start() for host in range(60,70): queue.put(host) queue.join() print time.ctime()

 Oltre al modulo

Thread

Queue , Python mette a disposizione i tradizionali sincronizzazione per meccanismi di l’accesso a strutture dati condivise: 

Lock

: metodi acquire – release  Re-Entrant Lock (

RLocks

)  Semafori