Indice del libro


Questo modulo illustrerà degli esempi di programmi più o meno difficili scritti in Python.

Massimo comune divisore di due interi

modifica

Una funzione che riceve come argomenti due interi e restituisce il loro massimo comune divisore.

Versione ricorsiva usa la differenza tra i due numeri:

def mcd(a, b):
    """Restituisce il Massimo Comune Divisore tra a e b"""
    if a*b == 0: return 1
    if a==b:  return a
    elif a>b: return mcd(a-b, b)
    else:     return mcd(b-a, a)

Versione iterativa, usa il resto della divisione tra i due numeri:

def mcd(a, b):
    """Restituisce il Massimo Comune Divisore tra a e b"""
    while b:
        a, b = b, a%b
    return a

Minimo comune multiplo tra due numeri

modifica

Funzione che si basa sulla precedente funzione iterativa per calcolare il MCD tra due numeri. Adattata alla versione 3.1.1 di Python.

def mcd(a, b):
    while b:
        a, b = b, a%b
    return a

def mcm(a, b):
    """Restituisce il Minimo Comune Multiplo tra a e b"""
    return a // mcd(a, b) * b

Successione di Fibonacci

modifica

Questa funzione genera in sequenza gli elementi della successione di Fibonacci minori del valore passato come argomento. Tratto da diveintopython.org. Adattata alla versione di Python 3.1.1.

def fibonacci(max):
    a, b = 0, 1
    while a < max:
        yield a
        a, b = b, a+b

for n in fibonacci(1000):
    print(n)

Calcolo del codice fiscale

modifica

Questo programma chiede all'utente alcuni dati e calcola il suo codice fiscale (CF). Questo programma presuppone l'esistenza di un file codicicomuni.txt nella stessa cartella. Il file codicicomuni.txt deve contenere i dati nella forma:

<codice>,<nome del comune>,<provincia>
<codice>,<nome del comune>,<provincia>
...

Questo programma non effettua controlli sui dati inseriti dall'utente.

# -*- coding: utf-8  -*-
#!/usr/local/bin/python

###
# Costanti di visibilità globale
##
MESI = 'ABCDEHLMPRST'
CONSONANTI = 'BCDFGHJKLMNPQRSTVWXYZ'
VOCALI = 'AEIOU'
LETTERE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
REGOLECONTROLLO = {
    'A':(0,1),   'B':(1,0),   'C':(2,5),   'D':(3,7),   'E':(4,9),
    'F':(5,13),  'G':(6,15),  'H':(7,17),  'I':(8,19),  'J':(9,21),
    'K':(10,2),  'L':(11,4),  'M':(12,18), 'N':(13,20), 'O':(14,11),
    'P':(15,3),  'Q':(16,6),  'R':(17,8),  'S':(18,12), 'T':(19,14),
    'U':(20,16), 'V':(21,10), 'W':(22,22), 'X':(23,25), 'Y':(24,24),
    'Z':(25,23),
    '0':(0,1),   '1':(1,0),   '2':(2,5),   '3':(3,7),   '4':(4,9),
    '5':(5,13),  '6':(6,15),  '7':(7,17),  '8':(8,19),  '9':(9,21)
                  }

def leggicodicicomuni(nomefile):
    """Restituisce un dizionario ricavato da un file di testo CVS."""
    cc={}
    for riga in file(nomefile):
        codice, citta, prov = riga.split(',')
        cc[citta] = codice
    return cc

CODICICOMUNI=leggicodicicomuni('codicicomuni.txt')

###
# Funzioni
##
def leggidati():
    """Legge i dati necessari come stringhe immesse dall'utente."""
    cognome = raw_input('Cognome: ')
    nome = raw_input('Nome: ')
    giornonascita = raw_input('Giorno di nascita: ')
    mesenascita = raw_input('Mese di nascita (numero): ')
    annonascita = raw_input(u"Anno di nascita: ")
    sesso = raw_input(u"Sesso (M/F): ")
    cittanascita = raw_input(u"Comune di nascita: ")
    return (cognome, nome, giornonascita, mesenascita, annonascita,
            sesso, cittanascita)

def trelettere(stringa,nome=True):
    """Ricava, da stringa, 3 lettere in base alla convenzione dei CF."""
    cons = [c for c in stringa if c in CONSONANTI]
    if nome and len(cons)>3:
        return [cons[0],cons[2],cons[3]]
    voc = [c for c in stringa if c in VOCALI]
    chars=cons+voc
    if len(chars)<3:
        chars+=['X', 'X']
    return chars[:3]
 
def datan(giorno, mese, anno, sesso):
    """Restituisce il campo data del CF."""
    chars = (list(anno[-2:]) + [MESI[int(mese)-1]])
    gn=int(giorno)
    if sesso=='F':
        gn+=40
    chars += list("%02d" % gn)
    return chars

def codicecontrollo(c):
    """Restituisce il codice di controllo, l'ultimo carattere del CF."""
    sommone = 0
    for i, car in enumerate(c):
        j = 1 - i % 2
        sommone += REGOLECONTROLLO[car][j]
    resto = sommone % 26
    return [LETTERE[resto]]

def codicefiscale(cognome, nome, giornonascita, mesenascita, annonascita,
                  sesso, cittanascita):
    """Restituisce il CF costruito sulla base degli argomenti."""
    nome=nome.upper()
    cognome=cognome.upper()
    sesso=sesso.upper()
    cittanascita = cittanascita.upper()
    chars = (trelettere(cognome,False) +
             trelettere(nome) +
             datan(giornonascita, mesenascita, annonascita, sesso) +
             list(CODICICOMUNI[cittanascita]))
    chars += codicecontrollo(chars)
    return ''.join(chars)

###
# Programma principale
##
cf = codicefiscale(*leggidati())
print "Il tuo codice fiscale e\': %s" % cf

Test di Primalità

modifica

Questa funzione restituisce il valore booleano True se il numero passato come argomento è primo, False se il numero non è primo. Adattata alla versione Python 3.1.1

def primo(numero):
    l = int(numero ** 0.5) + 1  # I fattori primi di un numero sono minori o uguali alla radice del numero stesso
    for n in range(2, l):       # Esegue un ciclo for per vedere se l'argomento numero ha qualche divisore
        if numero % n == 0:
            return False        # Se numero ha un divisore, viene restituito False
    return True                 # Altrimenti True

Ecco una versione più veloce, con Python 2.6.4:

def primo(n):
	if n == 2: return True  # Se n è uguale a 2, è primo
	if n % 2 == 0: return False  # Se n è pari, non è primo
	for x in xrange(3, int(n**0.5)+1, 2):  # Cerco in tutti i numeri da 3 alla radice quadrata di n, saltando i numeri pari
		if n % x == 0:  # Se n è divisibile per una qualunque x, non è primo
			return False
	return True  # Se non è divisibile per nessuna x, allora è primo

Scomposizione in fattori primi di un intero

modifica

Questa funzione restituisce una stringa contenente i fattori primi di un numero n dato in input.

Adattata alla versione 3.1.1 di Python

Esempio:

>>> scomposizione(232132)
232132 = 1 * 2 * 2 * 131 * 443

Ecco la funzione:

def scomposizione(n):
	fattore = str(n) + " = 1"                   # Creazione della stringa fattore
	d = 2                                       # Assegnamento del valore 2 alla variabile d
	while n >= d:                               # Inizio del ciclo while
		if n % d == 0:                      # Se il numero n è divisibile per d: la stringa fattore viene incrementata
			fattore += ' * ' + str(d)
			n /= d                      # Il valore di n viene diviso per d
		else:
			d = d + 1                   # Se n non è divisibile per d, il valore di d viene incrementato di 1       
	return fattore

Divisori di un numero

modifica

Questa funzione elenca tutti i divisori di un numero, compreso 1.

Adattata alla versione 3.1.1 di Python

def divisori(n):
	a = []
	for x in range(1, n + 1):
		if n % x == 0:
			a.append(int(x))
	print(a)

Qui un'altra versione, che utilizza le list comprehension ed è più veloce, perché controlla tutti i numeri fino a n/2, adattata a Python 2.6.4:

def divisori(n): return [c for c in xrange(1, int(n/2)+1) if n % c == 0]+[n]

Crivello di Eratostene

modifica

Di seguito l'implementazione del Crivello di Eratostene. Funzionamento:

  1. Viene creata una lista num di interi, da 0 fino al numero n;
  2. Si sostituisce l'elemento in posizione uno con uno zero;
  3. Per ogni numero x da 0 alla radice quadrata di n si controlla che l'elemento in posizione num[x] sia diverso da 0;
  4. Se lo è si cambiano tutti i suoi multipli con degli 0;
  5. Si eliminano tutti gli 0 dalla lista;
  6. Si ritorna la lista.

Adattato alla versione 2.6.4 di Python.

def Crivello(n):
    num = list(range(n+1))
    num[1] = 0
    for x in range(int(n**0.5)+1):
            if num[x] != 0:
                    num[2*x::x] = [0]*(int(n/x)-1)
    return list(filter(None, num))