Подтвердить что ты не робот

Как сообщить Python о преобразовании целых чисел в слова

Я пытаюсь сказать Python преобразовать целые числа в слова.

Пример: (используя песню 99 бутылок пива на стене)

Я использовал этот код для написания программы:

for i in range(99,0,-1):
    print i, "Bottles of beer on the wall,"
    print i, "bottles of beer."
    print "Take one down and pass it around,"
    print i-1, "bottles of beer on the wall."
    print

Но я не могу понять, как написать программу, чтобы вместо цифр отображались слова (т.е. девяносто девять, девяносто восемь и т.д.).

Я расправляю свою голову в книге питона, которую я имею, я понимаю, что, может быть, я просто не понимаю, что for/if/elif/else петли, но я просто вращаю свои колеса.

Может ли кто-нибудь дать представление? Я не ищу прямого ответа, хотя это могло бы помочь мне увидеть мою проблему, просто все, что мне указывало в правильном направлении, было бы здорово.

4b9b3361

Ответ 1

Пакет inflect может это сделать.

https://pypi.python.org/pypi/inflect

$ pip install inflect

а затем:

>>>import inflect
>>>p = inflect.engine()
>>>p.number_to_words(99)
ninety-nine

Ответ 2

Используйте pynum2word модуль, который можно найти в sourceforge

>>> import num2word
>>> num2word.to_card(15)
'fifteen'
>>> num2word.to_card(55)
'fifty-five'
>>> num2word.to_card(1555)
'one thousand, five hundred and fifty-five'

Ответ 3

Мы адаптировали существующее хорошее решение (ref) для преобразования чисел в слова следующим образом:

def numToWords(num,join=True):
    '''words = {} convert an integer number into words'''
    units = ['','one','two','three','four','five','six','seven','eight','nine']
    teens = ['','eleven','twelve','thirteen','fourteen','fifteen','sixteen', \
             'seventeen','eighteen','nineteen']
    tens = ['','ten','twenty','thirty','forty','fifty','sixty','seventy', \
            'eighty','ninety']
    thousands = ['','thousand','million','billion','trillion','quadrillion', \
                 'quintillion','sextillion','septillion','octillion', \
                 'nonillion','decillion','undecillion','duodecillion', \
                 'tredecillion','quattuordecillion','sexdecillion', \
                 'septendecillion','octodecillion','novemdecillion', \
                 'vigintillion']
    words = []
    if num==0: words.append('zero')
    else:
        numStr = '%d'%num
        numStrLen = len(numStr)
        groups = (numStrLen+2)/3
        numStr = numStr.zfill(groups*3)
        for i in range(0,groups*3,3):
            h,t,u = int(numStr[i]),int(numStr[i+1]),int(numStr[i+2])
            g = groups-(i/3+1)
            if h>=1:
                words.append(units[h])
                words.append('hundred')
            if t>1:
                words.append(tens[t])
                if u>=1: words.append(units[u])
            elif t==1:
                if u>=1: words.append(teens[u])
                else: words.append(tens[t])
            else:
                if u>=1: words.append(units[u])
            if (g>=1) and ((h+t+u)>0): words.append(thousands[g]+',')
    if join: return ' '.join(words)
    return words

#example usages:
print numToWords(0)
print numToWords(11)
print numToWords(110)
print numToWords(1001000025)
print numToWords(123456789012)

результаты:

zero
eleven
one hundred ten
one billion, one million, twenty five
one hundred twenty three billion, four hundred fifty six million, seven hundred
eighty nine thousand, twelve

Обратите внимание, что он работает для целых чисел. Тем не менее тривиально делить число с плавающей точкой на две целые части.

Ответ 4

Вот способ сделать это в Python 3:

"""Given an int32 number, print it in English."""
def int_to_en(num):
    d = { 0 : 'zero', 1 : 'one', 2 : 'two', 3 : 'three', 4 : 'four', 5 : 'five',
          6 : 'six', 7 : 'seven', 8 : 'eight', 9 : 'nine', 10 : 'ten',
          11 : 'eleven', 12 : 'twelve', 13 : 'thirteen', 14 : 'fourteen',
          15 : 'fifteen', 16 : 'sixteen', 17 : 'seventeen', 18 : 'eighteen',
          19 : 'nineteen', 20 : 'twenty',
          30 : 'thirty', 40 : 'forty', 50 : 'fifty', 60 : 'sixty',
          70 : 'seventy', 80 : 'eighty', 90 : 'ninety' }
    k = 1000
    m = k * 1000
    b = m * 1000
    t = b * 1000

    assert(0 <= num)

    if (num < 20):
        return d[num]

    if (num < 100):
        if num % 10 == 0: return d[num]
        else: return d[num // 10 * 10] + '-' + d[num % 10]

    if (num < k):
        if num % 100 == 0: return d[num // 100] + ' hundred'
        else: return d[num // 100] + ' hundred and ' + int_to_en(num % 100)

    if (num < m):
        if num % k == 0: return int_to_en(num // k) + ' thousand'
        else: return int_to_en(num // k) + ' thousand, ' + int_to_en(num % k)

    if (num < b):
        if (num % m) == 0: return int_to_en(num // m) + ' million'
        else: return int_to_en(num // m) + ' million, ' + int_to_en(num % m)

    if (num < t):
        if (num % b) == 0: return int_to_en(num // b) + ' billion'
        else: return int_to_en(num // b) + ' billion, ' + int_to_en(num % b)

    if (num % t == 0): return int_to_en(num // t) + ' trillion'
    else: return int_to_en(num // t) + ' trillion, ' + int_to_en(num % t)

    raise AssertionError('num is too large: %s' % str(num))

И результат:

0 zero
3 three
10 ten
11 eleven
19 nineteen
20 twenty
23 twenty-three
34 thirty-four
56 fifty-six
80 eighty
97 ninety-seven
99 ninety-nine
100 one hundred
101 one hundred and one
110 one hundred and ten
117 one hundred and seventeen
120 one hundred and twenty
123 one hundred and twenty-three
172 one hundred and seventy-two
199 one hundred and ninety-nine
200 two hundred
201 two hundred and one
211 two hundred and eleven
223 two hundred and twenty-three
376 three hundred and seventy-six
767 seven hundred and sixty-seven
982 nine hundred and eighty-two
999 nine hundred and ninety-nine
1000 one thousand
1001 one thousand, one
1017 one thousand, seventeen
1023 one thousand, twenty-three
1088 one thousand, eighty-eight
1100 one thousand, one hundred
1109 one thousand, one hundred and nine
1139 one thousand, one hundred and thirty-nine
1239 one thousand, two hundred and thirty-nine
1433 one thousand, four hundred and thirty-three
2000 two thousand
2010 two thousand, ten
7891 seven thousand, eight hundred and ninety-one
89321 eighty-nine thousand, three hundred and twenty-one
999999 nine hundred and ninety-nine thousand, nine hundred and ninety-nine
1000000 one million
2000000 two million
2000000000 two billion

Ответ 5

Ну, самый простой способ сделать это - составить список всех интересующих вас чисел:

numbers = ["zero", "one", "two", "three", "four", "five", ... 
           "ninety-eight", "ninety-nine"]

(... указывает, где вы вводите текстовые представления других чисел. Нет, Python не собирается волновать это для вас, вам нужно будет набрать их все, чтобы использовать эту технику. )

Затем, чтобы напечатать номер, просто напечатайте numbers[i]. Легкий peasy.

Конечно, этот список очень много печатает, поэтому вы можете задаться вопросом о простом способе его создания. У английского языка, к сожалению, много нарушений, поэтому вам придется вручную поставить первые двадцать (0-19), но вы можете использовать закономерности для генерации остальных до 99. (Вы также можете генерировать некоторых подростков, но только некоторые из них, поэтому проще всего просто ввести их.)

numbers = "zero one two three four five six seven eight nine".split()
numbers.extend("ten eleven twelve thirteen fourteen fifteen sixteen".split())
numbers.extend("seventeen eighteen nineteen".split())
numbers.extend(tens if ones == "zero" else (tens + "-" + ones) 
    for tens in "twenty thirty forty fifty sixty seventy eighty ninety".split()
    for ones in numbers[0:10])

print numbers[42]  # "forty-two"

Другой подход - написать функцию, которая объединяет правильную строку каждый раз. Снова вам придется жестко запрограммировать первые двадцать номеров, но после этого вы можете легко сгенерировать их с нуля по мере необходимости. Это использует немного меньше памяти (намного меньше, когда вы начинаете работать с большими числами).

Ответ 6

Звучит так, как вам нужно будет использовать массив, где num[1] = "one", num[2] = "two" и т.д. Затем вы можете прокручивать все, как вы уже есть, и

num = array(["one","two","three","four","five","six","seven","eight","nine","ten"])
for i in range(10,0,-1):
    print num[i], "Bottles of beer on the wall,"
    print num[i], "bottles of beer."
    print "Take one down and pass it around,"
    print num[i-1], "bottles of beer on the wall."
    print ""

Ответ 7

Здесь приведена рефакторинговая версия нескольких примеров кода, опубликованных выше (в основном код, вставленный "разработчиком".

def int2words(num):
    """Given an int32 number, print it in English.

    Parameters
    ----------
    num : int

    Returns
    -------
    words : str
    """
    assert (0 <= num)
    d = {
        0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five',
        6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten',
        11: 'eleven', 12: 'twelve', 13: 'thirteen', 14: 'fourteen',
        15: 'fifteen', 16: 'sixteen', 17: 'seventeen', 18: 'eighteen',
        19: 'nineteen', 20: 'twenty',
        30: 'thirty', 40: 'forty', 50: 'fifty', 60: 'sixty',
        70: 'seventy', 80: 'eighty', 90: 'ninety'
    }
    h = [100, 'hundred', 'hundred and']
    k = [h[0] * 10, 'thousand', 'thousand,']
    m = [k[0] * 1000, 'million', 'million,']
    b = [m[0] * 1000, 'billion', 'billion,']
    t = [b[0] * 1000, 'trillion', 'trillion,']
    if num < 20:
        return d[num]
    if num < 100:
        div_, mod_ = divmod(num, 10)
        return d[num] if mod_ == 0 else d[div_ * 10] + '-' + d[mod_]
    else:
        if num < k[0]:
            divisor, word1, word2 = h
        elif num < m[0]:
            divisor, word1, word2 = k
        elif num < b[0]:
            divisor, word1, word2 = m
        elif num < t[0]:
            divisor, word1, word2 = b
        else:
            divisor, word1, word2 = t
        div_, mod_ = divmod(num, divisor)
        if mod_ == 0:
            return '{} {}'.format(int2words(div_), word1)
        else:
            return '{} {} {}'.format(int2words(div_), word2, int2words(mod_))

Ответ 8

И тут приходит мое решение :) Это различные из ранних решений, но разработанные мной самим - может, кому-то понравится больше, чем другим предложениям.

TENS = {30: 'thirty', 40: 'forty', 50: 'fifty', 60: 'sixty', 70: 'seventy', 80: 'eighty', 90: 'ninety'}
ZERO_TO_TWENTY = (
    'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten',
    'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen', 'twenty'
)

def number_to_english(n):
    if any(not x.isdigit() for x in str(n)):
        return ''

    if n <= 20:
        return ZERO_TO_TWENTY[n]
    elif n < 100 and n % 10 == 0:
        return TENS[n]
    elif n < 100:
        return number_to_english(n - (n % 10)) + ' ' + number_to_english(n % 10)
    elif n < 1000 and n % 100 == 0:
        return number_to_english(n / 100) + ' hundred'
    elif n < 1000:
        return number_to_english(n / 100) + ' hundred ' + number_to_english(n % 100)
    elif n < 1000000:
        return number_to_english(n / 1000) + ' thousand ' + number_to_english(n % 1000)

    return ''

Это рекурсивное решение, которое можно легко расширить для больших чисел

Ответ 9

Код для этого:

>>>def handel_upto_99(number):
predef={0:"zero",1:"one",2:"two",3:"three",4:"four",5:"five",6:"six",7:"seven",8:"eight",9:"nine",10:"ten",11:"eleven",12:"twelve",13:"thirteen",14:"fourteen",15:"fifteen",16:"sixteen",17:"seventeen",18:"eighteen",19:"nineteen",20:"twenty",30:"thirty",40:"fourty",50:"fifty",60:"sixty",70:"seventy",80:"eighty",90:"ninety",100:"hundred",100000:"lakh",10000000:"crore",1000000:"million",1000000000:"billion"}
if number in predef.keys():
    return predef[number]
else:
    return predef[(number/10)*10]+' '+predef[number%10]

>>>def return_bigdigit(number,devideby):
predef={0:"zero",1:"one",2:"two",3:"three",4:"four",5:"five",6:"six",7:"seven",8:"eight",9:"nine",10:"ten",11:"eleven",12:"twelve",13:"thirteen",14:"fourteen",15:"fifteen",16:"sixteen",17:"seventeen",18:"eighteen",19:"nineteen",20:"twenty",30:"thirty",40:"fourty",50:"fifty",60:"sixty",70:"seventy",80:"eighty",90:"ninety",100:"hundred",1000:"thousand",100000:"lakh",10000000:"crore",1000000:"million",1000000000:"billion"}
if devideby in predef.keys():
    return predef[number/devideby]+" "+predef[devideby]
else:
    devideby/=10
    return handel_upto_99(number/devideby)+" "+predef[devideby]

>>>def mainfunction(number):
dev={100:"hundred",1000:"thousand",100000:"lakh",10000000:"crore",1000000000:"billion"}
if number is 0:
    return "Zero"
if number<100:
    result=handel_upto_99(number)

else:
    result=""
    while number>=100:
        devideby=1
        length=len(str(number))
        for i in range(length-1):
            devideby*=10
        if number%devideby==0:
            if devideby in dev:
                return handel_upto_99(number/devideby)+" "+ dev[devideby]
            else:
                return handel_upto_99(number/(devideby/10))+" "+ dev[devideby/10]
        res=return_bigdigit(number,devideby)
        result=result+' '+res
        if devideby not in dev:
            number=number-((devideby/10)*(number/(devideby/10)))
        number=number-devideby*(number/devideby)

    if number <100:
        result = result + ' '+ handel_upto_99(number)
return result

результат:

>>>mainfunction(12345)
' twelve thousand three hundred fourty five'
>>>mainfunction(2000)
'two thousand'

Ответ 10

Это работает также для первых 1000 чисел (Python 3). Новаторское решение проблемы, но решение тем не менее...

first_nums = ["", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve",
              "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]
tens = ["ten", "twenty", "thirty","forty","fifty", "sixty","seventy","eighty","ninety"]

for num in range(1,1001):
    if num < 20:
        print(first_nums[num])
    elif num < 100 and num % 10 == 0:
        print(tens[int(num/10 - 1)])
    elif num < 1000 and num % 100 == 0:
        print(first_nums[int(num/100)] + " hundred")
    elif num == 1000:
        print("one thousand")
    elif num < 100 and num % 10 != 0:
        print(tens[int(num//10 - 1)] + " " + first_nums[int(num%10)])
    elif num < 1000:
        if num%100 < 20:
            print(first_nums[int(num//100)] + " hundred and " + first_nums[num%100])
        else:
            print(first_nums[int(num//100)] + " hundred and " + tens[int(num%100//10 - 1)] + " " + first_nums[int(num%10)])

Ответ 11

Вы можете использовать библиотеку python-n2w, просто выполните

pip install n2w

тогда просто

print(n2w.convert(your-number-here))

Ответ 12

Вы должны использовать dictionnary/array. Например:

 to_19= ['zero','one','two','three','four','five','six','seven','eight','nine'..'nineteen']
 tens = ['twenty'...'ninety']

И вы можете сгенерировать строку числа, например:

 if len(str(number)) == 2 and  number > 20:
       word_number = tens[str(number)[0]]+' '+units[str(number)[0]]

Вам нужно проверить, не последняя ли цифра и т.д. классическая проверка значения.

Он напоминает задачу эйлера проекта (проблема 17).. вы должны попытаться найти некоторые решения об этом

Надеюсь, что это поможет

Ответ 13

#This valid till 4 digit number
numbers={1:'one', 2:'two', 3:'three', 4:'four', 5:'five', 6:'six', 7:'seven', 8:'eight', 9:'nine',
10:'ten', 11:'eleven', 12:'twelve', 13:'thirteen', 14:'fourteen', 15:'fifteen', 16:'sixteen',
17:'seventeen', 18:'eighteen', 19:'nineteen', 20:'twenty', 30:'thirty', 40:'forty', 50:'fifty', 
60:'sixty', 70:'seventy', 80:'eighty', 90:'ninety', 100:'hundred', 1000:'thousand'}

def my_fun(num):
    list = []
    num_len = len(str(num)) - 1
    while num_len > 0 and num > 0:
       while num_len > 0 and num > 0:
        if num in numbers and num < 1000:
            list.append(numbers[num])
            num_len = 0
        elif num < 100:
            list.extend([numbers[num - num%10], numbers[num%10]])
            num_len = 0
        else:
            quotent = num//10**num_len # 4567//1000= 4
            num = num % 10**num_len #4567%1000 =567
            if quotent != 0 :
                list.append(numbers[quotent])
                list.append(numbers[10**num_len])
            else:
                list.append(numbers[num])
            num_len -= 1
    return ' '.join(list)

Ответ 14

Это делает работу без какой-либо библиотеки. Используется рекурсия и это индийский стиль. Рави.

def spellNumber(no):
    # str(no) will result in  56.9 for 56.90 so we used the method which is given below.
    strNo = "%.2f" %no
    n = strNo.split(".")
    rs = numberToText(int(n[0])).strip()
    ps =""
    if(len(n)>=2):
        ps = numberToText(int(n[1])).strip()
        rs = "" + ps+ " paise"  if(rs.strip()=="") else  (rs + " and " + ps+ " paise").strip()
    return rs
print(spellNumber(0.67))
print(spellNumber(5858.099))
print(spellNumber(5083754857380.50))    

def numberToText(no):
    ones = " ,one,two,three,four,five,six,seven,eight,nine,ten,eleven,tweleve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen,twenty".split(',')
    tens = "ten,twenty,thirty,fourty,fifty,sixty,seventy,eighty,ninety".split(',')
    text = ""
    if len(str(no))<=2:
        if(no<20):
            text = ones[no]
        else:
            text = tens[no//10-1] +" " + ones[(no %10)]
    elif len(str(no))==3:
        text = ones[no//100] +" hundred " + numberToText(no- ((no//100)* 100))
    elif len(str(no))<=5:
        text = numberToText(no//1000) +" thousand " + numberToText(no- ((no//1000)* 1000))
    elif len(str(no))<=7:
        text = numberToText(no//100000) +" lakh " + numberToText(no- ((no//100000)* 100000))
    else:
        text = numberToText(no//10000000) +" crores " + numberToText(no- ((no//10000000)* 10000000))
    return text