mercoledì 21 aprile 2010

Python - 3/3, come nel walzer

Ecco il terzo post dell'introduzione di Python. I primi due post sono qui e qui.
Oggi riprendiamo l'esame dello script per il calcolo del fattoriale, facendolo come si deve, cioè come piace ai matematici. Che ne dite di questo?

#!/usr/bin/env python # ...... 1
# -*- coding: ISO-8859-1 -*-

def calcfact(n): # ...... 2
if n <= 1: # ...... 3
return n # ...... 4
else: # ...... 5
return n * calcfact(n - 1) # ...... 6

# qui inizia il main
st_num = raw_input('numero di cui vuoi il fattoriale: ') # ...... 7
if st_num.isdigit(): # ...... 8
num = int(st_num)
f = calcfact(num)
print 'il fattoriale di', num, 'è', f
else:
print st_num, 'non è un numero!'
Salviamolo in un file, propongo "fact.py" e proviamo a eseguirlo:

$ python fact.py
numero di cui vuoi il fattoriale: 6
il fattoriale di 6 è 720
$
Ma anche:

python fact.py
numero di cui vuoi il fattoriale: z
z non è un numero!
$
Passo ora all'esame del codice, facendo riferimento ai commenti # ......
1 - niente di nuovo, queste due righe le abbiamo già viste la volta scorsa;
2 - definizione di una funzione, "calcfact" nel nostro caso.
la forma è la seguente "def" nome_della_funzione(lista, dei, parametri):
la lista dei parametri può essere vuota; le parentesi e i due punti sono obbligatori;
3 - test "if", quasi uguale a quello degli altri linguaggi, ricordate i due punti. La particolarità è che "else if" si scrive "elif". Come in C (e JavaScript, per Picchio) l'ugualianza si scrive ==. Tutto diffusamente spiegato sul manuale a cui si rimanda;
4 - fine logica della funzione, ritorna i valori delle variabili elencate; se queste sono più di una diventano una lista (non ne abbiamo ancora parlato);
5 - condizione else dell'if del # 3; notare come in Python risultino evidenti i blocchi (anche per i pasticcioni);
6 - ecco la ricorsività, la funzione chiama se stessa e il codice risulta elegante :-) e qui il discorso sarebbe lungo...;
7 - raw_input() è una funzione standard di Python, la trovate all'URL http://docs.python.org/release/3.0.1/genindex.html , click su R etc...;
8 - isdigit() è una funzione troppo semplice, dai!

Ma si può fare ancora un passettino. Che ne dite di lanciare lo script con il numero sulla riga di comando, così:
python fact2.py 7
come facciamo usualmente con i comandi standard?
Si può fare, con picole modifiche il nostro script (stavo per scrivere "listato") diventa:

#!/usr/bin/env python
# -*- coding: ISO-8859-1 -*-

import sys # ...... 1

def calcfact(n):
if n <= 1:
return n
else:
return n * calcfact(n - 1)

# qui inizia il main
narg = len(sys.argv) # ...... 2
if narg == 1: # ...... 3
st_num = raw_input('numero di cui vuoi il fattoriale: ')
else:
st_num = sys.argv[1]

if st_num.isdigit():
num = int(st_num)
f = calcfact(num)
print 'il fattoriale di', num, 'è', f
else:
print st_num, 'non è un numero!'
Da notare:
1 - import di un modulo. I moduli sono raccolte di funzioni e costanti, ad esempio π (pi greco) si trova in math, quindi, dopo aver importato il modulo lo avremo a disposizione come math.pi;
2 - sys.argv è la lista degli argomenti, sys.argv[0] contiene il nome dello script. Sarebbe un errore far riferimento a un elemento della lista che non c'è per cui valutiamo la lunghezza delle lista con len();
3 - dai! si capisce no?

Sono così giunto alla fine dell'esperimento, ringrazio Knulp dell'ospitalità, spero non sia troppo horrificato di come ho trattato il suo blog.
Se sono riuscito a invogliare qualcuno a provare Python (Picchio sei riuscito a fargli scrivere "Hello"?) o Linux il mondo sarà in qualche misura migliore (non molto a dire il vero). A proposito tra una settimana esce la nuova versione di Ubuntu, con rivoluzione incorporata: i pulsanti della barra del titolo delle finestre a sinistra. La comunità degli ubuntisti è perplessa ma io penso che uno spostamento a sinistra, senza esagerare, sia (quasi) sempre cosa positiva.

3 commenti:

  1. Grazie a te, caro juhan, spero che tu ti sia divertito a scrivere così come io a leggere!

    Più avanti magari ti richiederò qualcosina di più avanzato... intanto, aspettiamo la nuova ubuntu sperando che la prima release non sia troppo buggata come troppo spesso succede! (io cmq sono momentaneamente switchato su kubuntu per l'ennesima volta).

    RispondiElimina
  2. Mi sono scordato di chiederti una cosa: cosa ne pensi dell'indentazione in python?
    (cioè del fatto che sia "obbligatorio" indentare i blocchi di codice).

    Quando l'ho sentito la prima volta mi sapeva di fortran/cobol (eh eh), poi ho sentito un sacco di guru difendere questa scelta a spada tratta e mi sono risolto a sospendere ogni giudizio.

    Premesso che io frusto i miei allievi a usare indentazione standardizzata anche per il C o il C++: ma far dipendere la sintassi dalla presenza dei tab? Non è un po' troppo "tranchant"?

    RispondiElimina
  3. L'indentazione è diversa da quella del Fortran (che adesso l'ha abbandonata).
    Ha come aspetto positivo che ti costringe a scrivere i blocchi ordinati. E secondo me è un grosso vantaggio visto che la "manutenzione" del codice è preponderante nella vita di un'applicazione di successo, e raramente si riscrive anche se alle volte...
    Per contro le parentesi graffe o la coppia "begin" - "end" sono più flessibili.
    Inoltre, siccome di solito si prende un pezzo di qua e l'altro di là occorre accordare l'indentazione: io mi sono fatto uno script con awk.
    Poi c'è, secondo me, un altro aspetto da considerare: se ti abitui a usare un linguaggio ragioni in termini di quello e finisci per amarlo ciecamente.

    Per i post mi sono divertito anche se:
    1) ho sbagliato il target;
    2) ho pasticciato con Blogger, per il primo post avevo scritto codice html e l'ho corretto al volo: male;
    3) adesso lo farei in modo diverso;
    4) secondo me i post dovrebbero essere molto più lunghi, c'è molto da dire, ma poi nessuno li leggerebbe, io per primo;
    5) quello che manca e il riscontro della classe (come #1).

    Dimenticato: con Ubuntu (e forse anche con altri) esiste Idle, shell utile per provare interattivamente.
    Se ci saranno altre cose felicissimo, naturalmente.
    Kubuntu ha la fama di essere meno stabile, l'ho usato molto poco, non sulla mia macchina. È, forse più bello graficamente.

    RispondiElimina

Attenzione: I commenti a vecchi post potrebbero essere moderati