7
\$\begingroup\$

First it asks for user to input a number and it will convert it into words. For example:

104382426112

to

One Hundred Four Billion Three Hundred Eighty Two Million Four Hundred Twenty Six Thousand One Hundred Twelve

I follow some basic if else condition only to make it works. Here is the code:

def once(num):
    word = ''
    if num == '1':
        word = "One"
    if num == '2':
        word = "Two"
    if num == '3':
        word = "Three"
    if num == '4':
        word = "Four"
    if num == '5':
        word = "Five"
    if num == '6':
        word = "Six"
    if num == '7':
        word = "Seven"
    if num == '8':
        word = "Eight"
    if num == '9':
        word = "Nine"
    word = word.strip()
    return word

def ten(num):
    word = ''
    if num[0] == '1':
        if num[1] == '0':
            word = "Ten"
        if num[1] == '1':
            word = "Eleven"
        if num[1] == '2':
            word = "Twelve"
        if num[1] == '3':
            word = "Thirteen"
        if num[1] == '4':
            word = "Fourteen"
        if num[1] == '5':
            word = "Fifteen"
        if num[1] == '6':
            word = "Sixteen"
        if num[1] == '7':
            word = "Seventeen"
        if num[1] == '8':
            word = "Eighteen"
        if num[1] == '9':
            word = "Nineteen"
    else:
        text = once(num[1])
        if num[0] == '2':
            word = "Twenty"
        if num[0] == '3':
            word = "Thirty"
        if num[0] == '4':
            word = "Fourty"
        if num[0] == '5':
            word = "Fifty"
        if num[0] == '6':
            word = "Sixty"
        if num[0] == '7':
            word = "Seventy"
        if num[0] == '8':
            word = "Eighty"
        if num[0] == '9':
            word = "Ninety"
        word = word + " " + text
    word = word.strip()
    return word

def hundred(num):
    word = ''
    text = ten(num[1:])
    if num[0] == '1':
        word = "One"
    if num[0] == '2':
        word = "Two"
    if num[0] == '3':
        word = "Three"
    if num[0] == '4':
        word = "Four"
    if num[0] == '5':
        word = "Five"
    if num[0] == '6':
        word = "Six"
    if num[0] == '7':
        word = "Seven"
    if num[0] == '8':
        word = "Eight"
    if num[0] == '9':
        word = "Nine"
    if num[0] != '0':
        word = word + " Hundred "
    word = word + text
    word = word.strip()
    return word

def thousand(num):
    word = ''
    pref = ''
    text = ''
    length = len(num)
    if length == 6:
        text = hundred(num[3:])
        pref = hundred(num[:3])
    if length == 5:
        text = hundred(num[2:])
        pref = ten(num[:2])
    if length == 4:
        text = hundred(num[1:])
        if num[0] == '1':
            word = "One"
        if num[0] == '2':
            word = "Two"
        if num[0] == '3':
            word = "Three"
        if num[0] == '4':
            word = "Four"
        if num[0] == '5':
            word = "Five"
        if num[0] == '6':
            word = "Six"
        if num[0] == '7':
            word = "Seven"
        if num[0] == '8':
            word = "Eight"
        if num[0] == '9':
            word = "Nine"
        word = word + " Thousand "
    word = word + text
    if length == 6 or length == 5:
        word = pref + " Thousand " + word
    word = word.strip()
    return word

def million(num):
    word = ''
    pref = ''
    text = ''
    length = len(num)
    if length == 9:
        text = thousand(num[3:])
        pref = hundred(num[:3])
    if length == 8:
        text = thousand(num[2:])
        pref = ten(num[:2])
    if length == 7:
        text = thousand(num[1:])
        if num[0] == '1':
            word = "One"
        if num[0] == '2':
            word = "Two"
        if num[0] == '3':
            word = "Three"
        if num[0] == '4':
            word = "Four"
        if num[0] == '5':
            word = "Five"
        if num[0] == '6':
            word = "Six"
        if num[0] == '7':
            word = "Seven"
        if num[0] == '8':
            word = "Eight"
        if num[0] == '9':
            word = "Nine"
        word = word + " Million "
    word = word + text
    if length == 9 or length == 8:
        word = pref + " Million " + word
    word = word.strip()
    return word

def billion(num):
    word = ''
    pref = ''
    text = ''
    length = len(num)
    if length == 12:
        text = million(num[3:])
        pref = hundred(num[:3])
    if length == 11:
        text = million(num[2:])
        pref = ten(num[:2])
    if length == 10:
        text = million(num[1:])
        if num[0] == '1':
            word = "One"
        if num[0] == '2':
            word = "Two"
        if num[0] == '3':
            word = "Three"
        if num[0] == '4':
            word = "Four"
        if num[0] == '5':
            word = "Five"
        if num[0] == '6':
            word = "Six"
        if num[0] == '7':
            word = "Seven"
        if num[0] == '8':
            word = "Eight"
        if num[0] == '9':
            word = "Nine"
        word = word + " Billion "
    word = word + text
    if length == 12 or length == 11:
        word = pref + " Billion " + word
    word = word.strip()
    return word


#104382426112 One Hundred Four Billion Three Hundred Eighty Two Million Four Hundred Twenty Six Thousand One HUndred Twelve
test = int(input())
a = str(test)
leng = len(a)
if leng == 1:
    num = once(a)
if leng == 2:
    num = ten(a)
if leng == 3:
    num = hundred(a)
if leng > 3 and leng < 7:
    num = thousand(a)
if leng > 6 and leng < 10:
    num = million(a)
if leng > 9 and leng < 13:
    num = billion(a)
print (num)
\$\endgroup\$
5
  • \$\begingroup\$ Note that n needs to be defined. \$\endgroup\$ Aug 25, 2017 at 17:40
  • \$\begingroup\$ Oh ya it was to make it works for more then one test case so. Should i remove the loop from the code now? or let it be there? \$\endgroup\$ Aug 25, 2017 at 17:42
  • \$\begingroup\$ Just edit the code to set n = 1 or something. \$\endgroup\$ Aug 25, 2017 at 17:43
  • \$\begingroup\$ Do I need to edit it on the question asked above too, so other wont suggest to define n first? \$\endgroup\$ Aug 25, 2017 at 17:45
  • \$\begingroup\$ No answers have been posted yet, so go ahead and edit the question so that the code is a runnable program. \$\endgroup\$ Aug 25, 2017 at 17:47

4 Answers 4

12
\$\begingroup\$

The first step to improve your code:

Instead of

if num == '1':
    word = "One"
if num == '2':
    word = "Two"
if num == '3':
    word = "Three"
if num == '4':
    word = "Four"
if num == '5':
    word = "Five"
if num == '6':
    word = "Six"
if num == '7':
    word = "Seven"
if num == '8':
    word = "Eight"
if num == '9':
    word = "Nine"

you may use a list - and num (converted to integer) will become the index to that list. For example

ones = ['', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine']

word = ones[int(num)]    # instead of "if num == '1': word = 'One' if num == '2' etc."

resulting to only 2 lines of the code (instead of 18).
(And similarly for many of the other parts of your program).


To save repeatedly typing apostrophes (') and commas (,) when filling your lists, e. g. in the same one as I just wrote

ones = ['Zero', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine']

you may use a common trick - first write them all into one string (delimiting them with 1 or more spaces)

'Zero One Two Three Four Five Six Seven Eight Nine'

and then use the .split() method to create the list of individual words from it.
So you will obtain:

ones = 'Zero One Two Three Four Five Six Seven Eight Nine'.split()
\$\endgroup\$
3
\$\begingroup\$

There are a lots of if statements in your program and many repeats. You did use functions, which is good, but mostly your program is strait line code. There are several potential problems that I see.

The input statement should provide a prompt, test = int(input('Enter a number: ')). Casting the input to int will crash the program if user does not input an int. The program will also crash if the number is too large (a trillion) and no output if zero. The two solution would be to use the try and except statements or accept a string input and check for validity. The input variable number would be more descriptive than test.

The first three def statements, once, ten and hundred could be put in a dictionary in a list or tulpe format and a smaller program could provide the same information as all of the if statements.

The thousand, million and billion could be in a list and use the same dictionary as the hundred. The length of the number can be used for the starting point.

#example

#                       ten=0   ten=1     tens=2
#
one2hundred_dict = {0: ('Zero', 'Ten'),
                    1: ('One', 'Eleven'),
                    2: ('Two', 'Twelve', 'Twenty'),
                    3: ('Three', 'thirteen', 'Thirty'),
                    4: ('Four', 'Fourteen', 'Forty')}
                    #...

def two_digits(str_num):
    if len(str_num) == 1:
        ones = int(str_num[0])    # ones = rows
        tens = 0                  # tens = columns
    else:
        tens = int(str_num[0])
        ones = int(str_num[1])
    if tens == 0 or tens == 1:
        return one2hundred_dict[ones][tens]
    else:
        word = one2hundred_dict[tens][2]
        word += ' ' + one2hundred_dict[ones][0]
        return word

def three_digits(str_num):
    hundreds = int(str_num[0])
    if hundreds == 0:
        return two_digits((str_num)[-2:])
    tens_ones = str_num[1:]
    word = one2hundred_dict[hundreds][0] + ' ' + 'Hundred'
    if tens_ones != '00':
        word += ' ' + two_digits(tens_ones)
    return word

word_list = ['','Thousand','Million','Billion']
num = '104232423112'
#num = '100000023112'
#num = '23012'
#num = '4'
print(num)
Words = ''
if num == '0':
    Words = one2hundred_dict[0][0]
else:
    while len(num) > 0:
        while num[0] == '0':
            num = num[1:]
        indx = (len(num) -1) / 3
        pos = len(num) % 3
        if pos == 0:
            pos = 3
            word = three_digits(num[:pos]) + ' ' + word_list[indx]
        else:
            word = two_digits(num[:pos]) + ' ' + word_list[indx]
        if Words:
            Words += ' ' + word
        else:
            Words = word
        num = num[pos:]
print(Words)
print
\$\endgroup\$
2
\$\begingroup\$

The identifier once is odd. It looks like you wanted to talk about the ones place. But your other identifiers are singular, so one would make the most sense.

Please replace your repetitive if statements with dictionaries. For example:

words = 'Zero One Two Three Four Five Six Seven Eight Nine'
value_to_word = { val, word
                  for val, word in enumerate(words.split()) }

And then e.g. assert value_to_word['Six'] == 6 would work.

Also, paying so much attention to length seems a bit unnatural. It is essentially log_10 of the number under consideration. You might instead choose to view this as a bookkeeping task, where you keep accounting for the portion of the number that has so far been translated to words. So after outputting "two thousand" you might use arithmetic subtraction

test -= 2000

to keep track of your remaining translation task (though I would name it n instead). This would be helpful if a feature request asked you to support a switch that sometimes required seconds in an hour to come out as "three thousand six hundred" like you produce now, or alternatively to come out as "thirty-six hundred".

\$\endgroup\$
2
\$\begingroup\$

As suggested by @MarianD I remove the if condition with the list. And here is Some functional improved code.

one = ['', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine']
tenp = ['Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen']
tenp2 = ['', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety']


def once(num):
    global one
    word = ''
    word = one[int(num)]
    word = word.strip()
    return word


def ten(num):
    global tenp
    global tenp2
    word = ''
    if num[0] == '1':
        word = tenp[int(num[1])]
    else:
        text = once(num[1])
        word = tenp2[int(num[0])]
        word = word + " " + text
    word = word.strip()
    return word


def hundred(num):
    global one
    word = ''
    text = ten(num[1:])
    word = one[int(num[0])]
    if num[0] != '0':
        word = word + " Hundred "
    word = word + text
    word = word.strip()
    return word


def thousand(num):
    word = ''
    pref = ''
    text = ''
    length = len(num)
    if length == 6:
        text = hundred(num[3:])
        pref = hundred(num[:3])
    if length == 5:
        text = hundred(num[2:])
        pref = ten(num[:2])
    if length == 4:
        text = hundred(num[1:])
        word = one[int(num[0])]
    if num[0] != '0' or num[1] != '0' or num[2] != '0':
        word = word + " Thousand "
    word = word + text
    if length == 6 or length == 5:
        word = pref + word
    word = word.strip()
    return word


def million(num):
    word = ''
    pref = ''
    text = ''
    length = len(num)
    if length == 9:
        text = thousand(num[3:])
        pref = hundred(num[:3])
    if length == 8:
        text = thousand(num[2:])
        pref = ten(num[:2])
    if length == 7:
        text = thousand(num[1:])
        word = one[int(num[0])]
    if num[0] != '0' or num[1] != '0' or num[2] != '0' :
        word = word + " Million "
    word = word + text
    if length == 9 or length == 8:
        word = pref + word
    word = word.strip()
    return word


def billion(num):
    word = ''
    pref = ''
    text = ''
    length = len(num)
    if length == 12:
        text = million(num[3:])
        pref = hundred(num[:3])
    if length == 11:
        text = million(num[2:])
        pref = ten(num[:2])
    if length == 10:
        text = million(num[1:])
        word = one[int(num[0])]
    if num[0] != '0':
        word = word + " Billion "
    word = word + text
    if length == 12 or length == 11:
        word = pref + word
    word = word.strip()
    return word


# 104382426112 One Hundred Four Billion Three Hundred Eighty Two Million Four Hundred Twenty Six Thousand One HUndred Twelve

test = int(input())
a = str(test)
leng = len(a)
if leng == 1:
    if a == '0':
        num = 'Zero'
    else:
        num = once(a)
if leng == 2:
    num = ten(a)
if leng == 3:
    num = hundred(a)
if leng > 3 and leng < 7:
    num = thousand(a)
if leng > 6 and leng < 10:
    num = million(a)
if leng > 9 and leng < 13:
    num = billion(a)
print(num)
\$\endgroup\$
2
  • \$\begingroup\$ The global calls are unnecessary. \$\endgroup\$ Aug 27, 2017 at 23:31
  • \$\begingroup\$ Oh ya!! Is it only needed when we need to alter the value on that global variable? \$\endgroup\$ Aug 28, 2017 at 2:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.