Progetta un programma che prenda numeri compresi tra 0 e 9.999 e stampi la versione parlata del numero.
def convert_to_spoken(num):
    if not num:
        return 'zero'
    
    if num > 9999:
        print('Il numero deve essere inferiore a 10.000')
        return
    
    singles = {1: 'uno', 2: 'due', 3: 'tre', 4: 'quattro',
        5: 'cinque', 6: 'sei', 7: 'sette', 8: 'otto',
        9: 'nove'
    }
    
    teens = {10: 'dieci', 11: 'undici', 12: 'dodici',
        13: 'tredici', 14: 'quattordici', 15: 'quindici',
        16: 'sedici', 17: 'diciassette', 18: 'diciotto',
        19: 'diciannove'
    }
    
    tens = {2: 'venti', 3: 'trenta', 4: 'quaranta', 5: 'cinquanta',
        6: 'sessanta', 7: 'settanta', 8: 'ottanta', 9: 'novanta',
    }
    
    # crea una lista di passaggi in base alla lunghezza del numero
    steps = [
        ('mila', 1000000), ('cento', 1000),
        ('', 0)
    ]
    
    # spezza il numero in gruppi di 3 cifre ciascuno
    digits = []
    while num > 0:
        r = num % 1000
        digits.insert(0, r)
        num //= 1000
    
    spoken_num = []
    # converte ogni gruppo di 3 cifre nel formato parlato
    for i, dig in enumerate(digits):
        if dig == 0:
            continue
        
        lbl, step = steps[i]
        a, b = divmod(dig, step)
        
        spoken_num.append(convert_to_spoken_3dig(a, b, 
            singles, teens, tens))
        spoken_num.append(lbl)
    
    return ' '.join(spoken_num)

def convert_to_spoken_3dig(a, b, singles, teens, tens):
    spoken_nums = []
    
    # converte la cifra delle centinaia
    if a:
        spoken_nums.append(singles[a] + 'cento')
    
    # converte la cifra delle decine
    if b:
        if b in singles:
            spoken_nums.append(singles[b])
        elif b in teens:
            spoken_nums.append(teens[b])
        else:
            t, o = divmod(b, 10)
            spoken_nums.append(tens[t])
            if o:
                spoken_nums.append(singles[o])
    
    return ' '.join(spoken_nums)