I programmi seguenti sono un esempio che mostra diversi livelli di "pythonizzazione" del codice,
partendo da una prima versione che può facilmente essere scritta da chi proviene da altri
linguaggi a minore astrazione, come BASIC, C, Pascal, per arrivare ad una
forma più idiomatica del linguaggio Python.
Primissima versione Python2 "pensata come in Pascal"
import random
#-------------------------------------------------------------------
# Cancella console e scrive messaggio iniziale
#-------------------------------------------------------------------
for z in range(24):
print
print "PYTHON MASTER MIND"
print "------------------"
print
#-------------------------------------------------------------------
# Prepara lista a con il codice da indovinare
#-------------------------------------------------------------------
a = [0, 0, 0, 0]
i = 0
while i < 4:
a[i] = random.randint(1, 6)
i = i + 1
#-------------------------------------------------------------------
# Ciclo principale
#-------------------------------------------------------------------
t = 0
while 1:
#-------------------------------------------------------------------
# Copia la lista a nella lista b
#-------------------------------------------------------------------
b = [0, 0, 0, 0]
i = 0
while i < 4:
b[i] = a[i]
i = i + 1
#-------------------------------------------------------------------
# Legge sequenza da tastiera e la splitta nella lista c
#-------------------------------------------------------------------
d = raw_input("Codice? ")
c = [0, 0, 0, 0]
i = 0
while i < 4:
c[i] = eval(d[i])
i = i + 1
#-------------------------------------------------------------------
# Calcola quanti giusti nella posizione giusta
#-------------------------------------------------------------------
neri = 0
i = 0
while i < 4:
if c[i] == b[i]:
neri = neri + 1
c[i] = 999
b[i] = 0
i = i + 1
#-------------------------------------------------------------------
# Calcola quanti rimanenti giusti ma nella posizione sbagliata
#-------------------------------------------------------------------
bianchi = 0
i = 0
while i < 4:
j = 0
while j < 4:
if c[i] == b[j]:
bianchi = bianchi + 1
c[i] = 999
b[j] = 0
j = j + 1
i = i + 1
#-------------------------------------------------------------------
# Scrive risultato
#-------------------------------------------------------------------
t = t + 1
print "Tentativo",t," Codice",d," NERI =",neri," BIANCHI =",bianchi
if neri == 4:
break
print "ESATTO!"
Seconda versione
Le iterazioni while sono state sostituite con for.
import random
a = [0, 0, 0, 0]
b = [0, 0, 0, 0]
c = [0, 0, 0, 0]
for i in range(4):
a[i] = random.randint(1, 6)
while 1:
neri = 0
bianchi = 0
for i in range(4):
b[i] = a[i]
d = raw_input("Tenta: ")
for i in range(4):
c[i] = eval(d[i])
for i in range(4):
if c[i] == b[i]:
neri = neri + 1
c[i] = 999
b[i] = 0
for i in range(4):
for j in range(4):
if c[i] == b[j]:
bianchi = bianchi + 1
b[j] = 0
print " "*15,"Codice",d," NERI =", \
neri," BIANCHI =",bianchi
if neri == 4:
print "ESATTO!"
break
Terza versione
Le iterazioni sulle liste sono state sostituite
con list comprehension. La copia degli elementi
della lista 'a' nella lista 'b' è stata ridotta ad un semplice
sezionamento dell'intera lista 'a'. I due cicli per il
controllo bianchi/neri sono stati accorpati.
import random
a = [0] * 4
b = [0] * 4
c = [0] * 4
a = [random.randint(1, 6) for i in range(4)]
while True:
neri = bianchi = 0
b = a[:]
d = raw_input("Tenta: ")
c = [int(d[i]) for i in range(4)]
for i in range(4):
if c[i] = =b[i]:
neri += 1
b[i] = 0
else:
for j in range(4):
if c[i] == b[j] and b[j] != c[j]:
bianchi += 1
b[j] = 0
break
print " "*15,"Codice",d," NERI =", \
neri," BIANCHI =",bianchi
if neri == 4:
print "ESATTO!"
break
Quarta versione (compatibile Python2 e 3)
Il controllo bianchi/neri è stato spostato in una funzione a parte
(generalizzata per accettare codici di qualsiasi lunghezza) e non
non è più necessaria una lista di copia. La lista passata al parametro
't' viene modificata, ma trattandosi del codice inserito da tastiera questo
viene rinnovato ad ogni ciclo. Il risultato viene scritto usando la
formattazione di stringa in cui i diversi campi '%' vengono sostituiti rispettivamente
con i valori presenti nella tupla finale. La dichiarazione iniziale delle
liste non è più necessaria. La costruzione della lista tentativo viene fatta
iterando direttamente sugli elementi della stringa immessa da tastiera,
invece che iterare attraverso indici. Infine l'input da tastiera e la
stampa a video sono state rese compatibili Python2 e 3.
from random import randint
#------------------------------------------------------------------------------
def confronta(c, t):
neri = bianchi = 0
for i in range(len(c)):
if c[i] == t[i]:
neri += 1
t[i] = 0
else:
for j in range(len(c)):
if c[i] == t[j] and t[j] != c[j]:
bianchi += 1
t[j] = 0
break
return neri, bianchi
#------------------------------------------------------------------------------
codice = [randint(1, 6) for i in range(4)]
while True:
try: d = raw_input("Tenta: ") #Py2
except NameError: d = input("Tenta: ") #Py3
tentativo = [int(i) for i in d]
neri, bianchi = confronta(codice, tentativo)
print("%15s Codice=%4s NERI=%1s BIANCHI=%1s" % (" ", d, neri, bianchi))
if neri == 4: break
print("ESATTO!")
#------------------------------------------------------------------------------
Idiomatic Python
Una serie di linee guida per scrivere codice pythonicamente corretto:
python.net/~goodger/projects/pycon/2007/idiomatic/handout.html
↑