Python Tips & Snippets

Home    Gnuplot    Tkinter    Linux    Glossario


Ultima revisione: martedì 16 maggio 2006 20:17:54


Indice

1. tips
2. snippets
3. note

1. tips

1.1. Tre modi per usare Python in Linux

a) Script: preparare un listato di script, con il proprio editor preferito, salvarlo con il suffisso .py (es. mioprg.py) ed avviarlo con il comando
python mioprg.py

b) Script Eseguibile: assicurarsi che la priga riga del sorgente sia del tipo:
#!/usr/bin/env python         oppure
#!/usr/bin/python
renderlo eseguibile con il comando
chmod +x mioprog.py
avviarlo direttamente digitandone il nome (eventualmente completo di path) come per qualsiasi altro programma.
Ricordarsi che dalla propria cartella occorre avviarlo con
./mioprg.py

c) Sessione Interattiva: digitare
python
senza argomenti da qualsiasi shell, ottenendo una risposta del tipo:
Python 2.3.5 (#2, Mar  6 2006, 10:12:24)
[GCC 4.0.3 20060304 (prerelease) (Debian 4.0.2-10)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
Il codice immesso interattivamente dopo il prompt >>> verrà eseguito immediatamente, il che risulta molto comodo per provare semplici istruzioni.
Per chiudere la sessione interattiva digitare Ctrl-D.



1.2. Commentare il codice
Commentare un listato è essenziale, ci sono svariati modi per realizzarlo. Il commento dovrebbe essere formato da frasi complete, con ogni riga preceduta dal carattere #. Il primo carattere della frase in maiuscolo e ciascuna frase separata da un punto e due spazi.
# Commento su una singola riga intera. Finisce con il carattere di Ritorno a capo. 

print "ciao"            # commento alla destra di una istruzione
Un altro modo per inserire commenti lunghi si serve di blocchi di testo delimitati da """ e chiamati docstring. Le docstring andrebbero usate per commentare tutte le funzioni, i metodi, le classi, i moduli ed i package publici. Il commento per un package va inserito all'interno del suo __init__.py.
Le docstring possono essere formate da una sola linea, o da più linee; in quest'ultimo caso il delimitatore di chiusura andrebbe inserito su una linea isolata.
def func1() :
    """Questo è un commento docstring su una singola linea."""

def func2() :
    """Questo è un commento docstring 

    Su piu' linee.
    """



1.3. Le funzioni restituiscono...
Una funzione può essere conclusa, solitamente, in 3 modi:
1) con return, da solo; esegue un compito, ma non restituisce nulla. Assomiglia alle procedure Pascal o alle funzioni void del C.
2) con return x; esegue delle operazioni e restituisce il valore x.
3) con return (x,y,z); esegue delle operazioni e restituisce i valori x,y,z.
def func1(a,b):
    print 3*(a+b)           # Esegue un compito e non restituisce nulla
    return                  # Il return potrebbe anche essere omesso

def func2(a):
    x = a**3
    return x                # Restituisce il cubo di a

def func3(a):
    return (a+1,a*3,a*a)    # Restituisce 3 valori ...

(x,y,z) = func3(2)          # ... che possono, con l'assegnazione multipla,
                            #     essere depositati su 3 variabili distinte
E' evidente che alle funzioni possiamo passare degli argomenti tra parentesi, o nessun argomento ed in tal caso la coppia di parentesi rimarrà vuota.
def beep():
    print chr(7)            # Oppure anche:  print "\a"



1.4. Scambio di variabili
Scambiare il contenuto di due variabili è facilissimo, sfruttando l'assegnazione multipla e senza coinvolgere nessuna variabile appoggio.
a = 5
b = 9
(a,b) = (b,a)               # Ecco fatto !



1.5. Realizzare Stack e Code
Niente di più facile. Basta usare per gli Stack gli oggetti List ed i metodi append() e pop(), rispettivamente per le operazioni di Push e Pop.
a = [7,5,9]
a.append(15)
print a                     # Visualizza: [7, 5, 9, 15]
print a.pop()               # Visualizza: 15 e lo scarica
print a.pop()               # Visualizza: 9 e lo scarica
print a                     # Visualizza: [7, 5]
Mentre per le Code gli oggetti List ed i metodi append() e pop(0), rispettivamente per le operazioni di Append e Pop.
a = [7,5,9]
a.append(15)
print a                     # Visualizza: [7, 5, 9, 15]
print a.pop(0)              # Visualizza: 7 e lo scarica
print a.pop(0)              # Visualizza: 5 e lo scarica
print a                     # Visualizza: [9, 15]
Una lista può contenere qualsiasi tipo di oggetto, non soltanto interi, come negli esempi precedenti.



1.6. Avviare un applicativo
Grazie al modulo os, che occorre importare, ecco la soluzione per aprire il file prova.txt con l'editor kwrite:
import os
os.system('kwrite prova.txt')




2. snippets

2.1. Argomenti della Command Line
#!/usr/bin/python
# prg. cmdline01.py <nomeFile>
# 18-04-2006 Edizioni ByteMan  
# Uso della Command Line ed alterazione del contenuto di un file.

import sys        
# Questo modulo consente l'uso del vettore predefinito sys.argv
# sys.arg[0] contiene il nome della riga di avvio del programma
# sys.arg[1] contiene il nome del primo argomento passato al programma

def main():
   if len(sys.argv) < 2:
      print "Errore: manca il nome del file."
      return
   nameF1 = sys.argv[1]
   nameF2 = nameF1
   try:
      F1 = open(nameF1, 'r')
   except:
      print 'Errore: impossibile aprire il file "' + nameF1 + '" !!'
      return
   testo = F1.read()
   F1.close()
   F2 = open(nameF2, 'w')
   F2.write('# Ho premesso al file tutta questa riga \n')
   F2.write(testo)
   F2.close()
   print "Riga di avvio (sys.argv[0]): '" + sys.argv[0] + "'"
   print "Argomento uno (sys.argv[1]): '" + sys.argv[1] + "'"

main()



2.2. Input multiplo
#!/usr/bin/python
# prg. somma.py <x> <y>
# 18-04-2006 Edizioni ByteMan  
# Somma due valori positivi inseriti contestualmente.

import sys

def somma(x,y):
   z = x
   for i in range(y):
      z += 1
   return z

def main():
   x = int(sys.argv[1])
   y = int(sys.argv[2])
   z = somma(x, y)
   print x, "+", y, "=", z

main()



2.3. Condizioni e ricorsione
L'esempio del calcolo del fattoriale illustra sia l'uso di if, elif, else, sia un semplice caso di ricorsione.
# prg. fatt01.py <x> 
# 18-04-2006 Edizioni ByteMan  
# Calcola il fattoriale di un numero x.

def Fatt(n):
    if type(n) != type(1):              # esclude n non intero (verifica sul tipo)
        return -1
    elif n < 0:                         # esclude n negativo
        return -2
    elif n == 0:                        # singolarita' n=0
        return 1
    else:
        return n * Fatt(n-1)            # calcolo ricorsivo

def main():
    x = input("Digita un numero: ")
    f = Fatt(x)
    if f == -1 :
        print "Errore (1): Il fattoriale e' definito solo per i valori interi."
    elif f == -2 :
        print "Errore (2): Il fattoriale e' definito solo per interi positivi."
    else:
        print f

main()



2.4. Visualizzare un file su video
# prg. printfile.py 
# 19-04-2006 Edizioni ByteMan
# Visualizza un file su video.

def main():
    fname = raw_input("Nome del file: ")
    print '-' * 40                          # Genera 40 trattini
    F1 = open(fname,'r')
    data = F1.read()
    print data

main()



2.5. Generazione di numeri primi
# prg. nprimi.py 
# 25-04-2006 Edizioni ByteMan  
# Genera tutti i numeri primi <= Nmax

def primi(Nmax):
    for N in range(2, Nmax):        # Verifica divisibilita'
        for D in range(2, N+1):
            flagOk = 1
            if ((N % D) == 0) and (N != D):
                flagOk = 0          # Trovato un divisore
                break
        if flagOk:
            print N,

primi(1000)



2.6. Generazione di password casuale
Chiamata senza parametri, la funzione GenPsw genera una password casuale di 8 caratteri, composta di lettere maiuscole/minuscole e cifre numeriche.
# prg. randpsw01.py 
# 26-04-2006 Edizioni ByteMan  
# Generazione casuale di password

import string, whrandom

def GenPsw(ln=8, st=string.letters + string.digits):
    newpsw = ''
    for i in xrange(ln):
        newpsw = newpsw + whrandom.choice(st)
    return newpsw

print GenPsw()
print GenPsw(12,'xyzabcdefgMNQH567')
Ma è possibile anche specificare esplicitamente la lunghezza ln e la stringa st di caratteri da utilizzare.



2.7. Clear Screen
Questa funzione serve per ripulire lo schermo di shell, indipendentemente dal sistema operativo.
# prg. clear01.py 
# 22-04-2006 Edizioni ByteMan  
# Clear Screen

import os

def clearscreen(righe=100):
    """Clear Screen.

    righe e' un argomento opzionale usato soltanto in caso di emergenza.
    """
    import os
    if os.name == "posix":                  # Unix/Linux/MacOS/BSD/etc
        os.system('clear')
    elif os.name in ("nt", "dos", "ce"):    # DOS/Windows
        os.system('CLS')
    else:                                   # Emergenza, per altri S.O.
        print '\n' * numlines

clearscreen()
Si noti l'uso della docstring, racchiusa tra """, utile per l'autodocumentazione della funzione.



2.8. Dimensioni di un file
L'informazione sulla dimensione di un file puo' essere ottenuta in vari modi. I due metodi proposti utilizzano tecniche diverse: il primo sfrutta l'importazione dei moduli appositi os e stat, mentre il secondo ottiene un risultato analogo richiamando i metodi propri dell'oggetto file.
# prg. filesize.py 
# 22-04-2006 Edizioni ByteMan  
# Dimensioni di un file

import os, stat

def filesize1(n):                   # Richiede i moduli os e stat
    info = os.stat(n)
    sz = info[stat.ST_SIZE]
    return sz

def filesize2(n):                   # Non richiede moduli aggiuntivi
    F = open(n,'r')
    F.seek(0,2)
    sz = F.tell()
    F.seek(0,0)
    F.close()
    return sz

filename = "clear01.py"
print "(filesize1) - Il file contiene: ", filesize1(filename), " bytes."
print "(filesize2) - Il file contiene: ", filesize2(filename), " bytes."



2.9. Standard output
L'output sullo schermo di shell viene solitamente effettuato tramite print che provvede ad una serie di facilitazioni per l'utente. Talvolta, però, è necessario un controllo più preciso dell'output. Si veda in proposito il listato seguente.
# prg. write01.py 
# 22-04-2006 Edizioni ByteMan  
# Standard output

import sys                                       # Modulo sys

def main():
    for i in range(10):
        print i,
    print
    for i in range(10):
        sys.stdout.write(str(i))
    print

main()
che produce a video quanto segue
0 1 2 3 4 5 6 7 8 9
0123456789
dove si può notare come gli spazi introdotti automaticamente dalla print non sono presenti con l'uso della sys.stdout.write, che però tratta solamente stringhe.



2.10. Spedire un file, tramite FTP.
Tutti gli altri comandi FTP (lista/cambia/rinomina cartella, ripresa di un download interrotto, ...) sono descritti nel modulo ftplib.
# prg. ftpsend.py 
# 19-04-2006 Edizioni ByteMan  
# Spedisce un file, tramite FTP.

import ftplib                                       # Modulo FTP 

def main():
    server = 'www.miosito.org'                   
    utente = 'agente'
    passwd = 'secret007'
    F1 = 'immagine.gif'
    F2 = 'immagine.gif'
    session = ftplib.FTP(server,utente,passwd)      # Connessione al server FTP 
    myfile = open(F1,'rb')                          # Apre il file da spedire
    session.storbinary('STOR ' + F2, myfile)        # Spedisce il file
    myfile.close()                                  # Chiude il file
    session.quit()                                  # Chiude la sessione FTP 

main()



2.11. Scaricare un file, tramite FTP.
Il classico download di un file
# prg. ftpdown.py 
# 23-04-2006 Edizioni ByteMan  
# Spedisce un file, tramite FTP.

import ftplib                                       # Modulo FTP 

def main():
    server = 'www.miosito.org'                   
    utente = 'agente'
    passwd = 'secret007'
    direct = 'pub/x-files'
    F1 = 'immagine.gif'
    F2 = 'immagine.gif'
    session = ftplib.FTP(server)                    # Connessione al server FTP
    session.login(utente, passwd)                   # Login
    session.cwd(direct)                             # Change directory
    myfile = open(F1,'wb')                          # Apre il file da prelevare
    session.retrbinary('RETR ' + F2, myfile.write)  # Download del file
    myfile.close()                                  # Chiude il file
    session.quit()                                  # Chiude la sessione FTP 

main()



2.12. Controllare una casella postale.
# prg. mail01.py 
# 19-04-2006 Edizioni ByteMan  
# Controllo di una casella di posta.

import poplib, sys, time

def controlla_posta(s,u,p):
    """Funzione che controlla una casella di posta"""
    try:
        connessione = poplib.POP3(s)
        connessione.user(u)
        connessione.pass_(p)
        nmex, sz = connessione.stat()
        connessione.quit()
        return nmex, sz
    except (poplib.socket.error, poplib.error_proto), messaggio:
        print 'Problema:', messaggio
        sys.exit(1)

def main():
    server = 'popmail.serv.org'
    utente = 'agente'
    passwd = 'secret007'
    interv = 120
    while 1:
        try:
            numero_messaggi, dimensione = controlla_posta(server,utente,passwd)
            if numero_messaggi > 0:
                print 'Numero messaggi:', numero_messaggi, 'Dimensioni:', dimensione
            time.sleep(interv)
        except KeyboardInterrupt:
            print 'Sempre al suo servizio!'
            sys.exit(0)

main()



2.13. Realizzare uno script CGI.
Common Gateway Interface è una tecnologia standard usata dai web server per interfacciarsi con applicazioni esterne che generano il codice HTML.
Questo semplice script d'esempio genera una pagina che visualizza la data e l'ora correnti del server. Dopo averlo esaminato è opportuno leggere le puntualizzazioni riportate in coda.
#!/usr/bin/python
import cgitb; cgitb.enable()            # Abilita CGI
import time

def htmlpage():
    print "<HTML>"
    print "<HEAD>"
    print "<TITLE>Edizioni ByteMan - Ora</TITLE>"
    print "</HEAD>"
    print "<BODY>"
    print "<H2>Esempio di lettura dell'ora</h2>"
    print "<P>Data ed ora: %s</P>" % time.ctime()
    print "</BODY>"
    print "</HTML>"
    
print "Content-type: text/html\n"       # Prima riga 'print' obbligatoria
htmlpage()
    
1) E' necessario che il gestore del server autorizzi l'uso di script Python.
2) La prima riga dello script riporta il path per trovare l'interprete Python sul server.
3) Tutte le righe print devono produrre codice HTML corretto.
4) La prima print (in ordine di esecuzione) deve essere quella riportata nel listato.
5) Quando lo script verrà caricato nella directory cgi-bin occorrerà impostargli il permesso di esecuzione.



2.14. Formattazione di un testo.
Questo esempio mostra l'uso di un semplice dizionario per sostituire in un file di testo le vocali accentate con le corrispondenti vocali apostrofate. Viene poi suddiviso il testo in paragrafi, assumendo che dopo ogni punto fermo inizi un nuovo paragrafo. Nel contempo si verifica che la prima lettera di ciascun paragrafo sia maiuscola. Un altro effetto ottenuto è che ogni paragrafo costituisce una riga unica doppiamente spaziata dalla successiva.
# -*- coding: iso-8859-1 -*-
# prg. formatxt.py 
# 23-04-2006 Edizioni ByteMan
# Formattazione Testo

def format(fname):
    # Lettura del file di testo origine
    f = open(fname)
    testo1 = f.read()
    f.close()
    # Definizione del dizionario delle vocali da sostituire
    diz = {"à":"a'", "á":"a'", "è":"e'", "é":"e'", "ì":"i'", "í":"i'", "ò":"o'", "ó":"o'", "ù":"u'", "ú":"u'"}
    for item in diz:
        testo1 = testo1.replace(item, diz[item])
        testo1 = testo1.replace('\n',' ')
    # Formattazione del testo
    testo2 = ''
    paragrafi = testo1.split('.')
    for x in xrange(len(paragrafi)-1):
        testo2 = testo2 + paragrafi[x].lstrip().capitalize() + '.\n\n'
    # Scrittura del file con il testo aggiornato
    f = open(fname, 'w')
    f.write(testo2)
    f.close()
    # print testo2

format('esempio.txt')
La prima riga del listato, uno pseudocommento, imposta effettivamente il tipo di codifica per interpretare i codici dei caratteri. Da notare, poi, il metodo replace per sostituire ripetutamente tutte le lettere interessate, il metodo split per dividere il testo in paragrafi, il metodo lstrip per eliminare gli spazi iniziali, ed il metodo capitalize per ottenere la prima lettera maiuscola di ogni paragrafo. L'uso della classe xrange(), al posto di range(), restituisce un oggetto invece che una lista. Nei loop questo comporta una maggior velocità ed un uso più efficiente della memoria.



2.15. Sostituzione stringhe in un testo.
#!/usr/bin/python
# prg. quotecomm.py 
# 27-04-2006 Edizioni ByteMan
# Sostituzione stringhe in un file

import sys

def main():
   if len(sys.argv) < 2:
      print "Errore: manca il nome del file."
      return
   nameF1 = sys.argv[1]
   nameF2 = nameF1
   try:
      F1 = open(nameF1, 'r')
   except:
      print 'Errore: impossibile aprire il file "' + nameF1 + '" !!'
      return
   testo = F1.read()
   F1.close()
   testo = testo.replace('&quot;</font><font color="#008000">', '&quot;')
   testo = testo.replace('"#008000">&quot;&quot;&quot;', '"#444444">&quot;&quot;&quot;')
   F2 = open(nameF2, 'w')
   F2.write(testo)
   F2.close()

main()



2.16. Grafico funzione tramite gnuplot.
Gnuplot è un semplice programma open source per produrre grafici rapidamente a partire da un file di dati o da espressioni analitiche. Dopo aver installato i pacchetti per utilizzarlo:
apt-get install gnuplot
apt-get install python-gnuplot
python consente di utilizzarne le funzioni dentro gli script. L'esempio mostra le basi di partenza per visualizzare una funzione trigonometrica.
#!/usr/bin/python
# prg. gplot.py 
# 12-05-2006 Edizioni ByteMan  

import Gnuplot

g = Gnuplot.Gnuplot()
g.title('Test Funzione Coseno')			# Titolo del grafico
g.xlabel('X')					# Scritta lungo l'asse X
g.ylabel('Y')					# Scritta lungo l'asse Y
g.set_range('xrange', '[0:10]')			# Impostazione intervallo X
g.set_range('yrange', '[-1.01:1.01]')		# Impostazione intervallo Y
g('plot cos(x)')
raw_input('Premere Invio per finire...') 	# Pausa per osservare il grafico




3. note

3.1. Libere riflessioni su Python.

Python è uno strano e meraviglioso linguaggio che, ad un programmatore di lunga data, riporta indietro i profumi delle buone cose di una volta (una per tutte la libertà di introdurre le variabili nel momento in cui servono), ma al tempo stesso fornisce strumenti moderni come gli oggetti. Per certi versi è simile a Java ma non ne impone le follie organizzative. Python è talmente semplice ed elegante, ma al tempo stesso talmente completo e potente, da potersi ritenere il linguaggio con cui insegnare a programmare (o con cui imparare a programmare da soli). Python è infatti anche molto simile a C, di cui ha perso fortunatamente molte asperità, e quindi può costituire un ottimo strumento per prepararsi alla carriera di professionista.

E' un linguaggio interpretato e quindi i programmi scritti in Python richiedono la presenza dell'interprete installato sulla macchina. Un programma deve essere lanciato in questo modo:

python testprogr.py param01 param02
Questo comporta un vantaggio ed uno svantaggio: il vantaggio è che il programma gira dovunque sia disponibile l'interprete, lo svantaggio è che funziona un po' più lentamente di un programma C. Un programma Python può essere scritto ed eseguito su tutte le versioni di queste piattaforme:

Unix, Linux, Windows, FreeBSD, OpenBSD, NetBSD, McOS

Non si creda, inoltre, che Python sia un linguaggio per studenti o che sia in qualche modo limitato: dispone delle librerie necessarie per trattare qualunque problema che si possa presentare nella vita professionale, dalla creazione di interfacce grafiche con l'ausilio di vari toolkit su qualunque piattaforma fino alla creazione di interpreti di linguaggi. Python viene ormai usato da molti anni da schiere di programmatori professionisti che con esso hanno creato una moltitudine di programmi di ogni tipo, alcuni dei quali sono persino dei successi commerciali.

Tutti i sistemi operativi mettono a disposizione degli ambienti di lavoro, noti come IDE (Integrated Development Environement), che includono tutto il necessario per scrivere codice e che, soprattutto, si occupano della manutenzione dei progetti (l'insieme dei file dell'applicativo). Un buon IDE può semplificare di molto la vita ad un programmatore, soprattutto se inesperto o pigro. Tuttavia, nei primi tempi di apprendimento, è meglio stare alla larga dagli IDE ed è più opportuno utilizzare un normale editor di testo (Kwrite, NotePad e simili). Solo dopo aver capito i meccanismi di base è consigliabile provare a lavorare con un IDE.
E per finire, alcuni suggerimenti:





Copyright (c) 2006 Edizioni ByteMan - www.linux.byteman.it