2
\$\begingroup\$

This program created by me spells a number in the standard notation (Billions, Millions etc). I was wondering if there is a better way to do the same thing, or if I have been a victim of some of the bad practices in this language.

I am fairly new to Python and have only been learning it for the past 20 days. Any other types of suggestions and feedback on my variable naming practices, techniques would be wonderful.

names_dict = {}
names_dict['ones'] = {0: '', 1:'one', 2:'two', 3:'three', 4:'four', 5:'five', 6:'six', 7:'seven', 8:'eight', 9:'nine'}
names_dict['tens'] = {0: '', 2: 'twenty', 3: 'thirty', 4: 'fourty', 5: 'fifty', 6: 'sixty', 7: 'seventy', 8: 'eighty', 9: 'ninty'}

exep = {0: 'ten', 1: 'eleven', 2: 'twelve', 3: 'thirteen', 4: 'fourteen', 5: 'fifteen', 6: 'sixteen', 7: 'seventeen', 8: 'eighteen', 9: 'ninteen'}
sufix = {0: 'billion', 1: 'million', 2: 'thousand', 3: ''}

# int ----> list
def digit_extract(num):
    digit = [0]*12
    iterator = 0
    while num != 0:
        digit[iterator] = num % 10
        iterator += 1
        num //= 10
    return digit[::-1]

#list [3 digit] to str
def hundered(three_digit):
    name = ''
    if three_digit[0] != 0:
        name += names_dict['ones'][three_digit[0]] + ' '  + 'hundered' + ' '

    if three_digit[1] != 1:
        if three_digit[1] != 0:
            name += names_dict['tens'][three_digit[1]] + ' '
        if three_digit[2] != 0:
            name += names_dict['ones'][three_digit[2]]
    else:
        name += exep[three_digit[2]]

    return name

def numberNames():
    num = int(input('Enter the number: '))
    digits = digit_extract(num)
    final_name = ''

    for i in range(4):
        hund = hundered(digits[i*3: (i*3) + 3])
        if hund != '':
            final_name += hund + ' ' + sufix[i] + ' '

    print(final_name.title())

numberNames()
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Spelling: hundred, not "hundered"; ninety, not "ninty", nineteen, not "ninteen", forty, not "fourty" (yes, I know that last one is inconsistent, but that's English for you!) \$\endgroup\$ May 15, 2018 at 10:34

1 Answer 1

3
\$\begingroup\$
  1. There is no reason for dictionaries when you have an ordered list of items starting at zero with no missing indexes, a list will do just fine.

     suffixes = ['billion', 'million', 'thousand', '']
    
  2. names_dict could be two seperate variables, because you are only accessing it with literal keys.

    ONES = {0: '', 1:'one', 2:'two', 3:'three', 4:'four', 5:'five', 6:'six', 7:'seven', 8:'eight', 9:'nine'}
    TENS = {0: '', 2: 'twenty', 3: 'thirty', 4: 'fourty', 5: 'fifty', 6: 'sixty', 7: 'seventy', 8: 'eighty', 9: 'ninty'}
    
  3. although it may not be as efficient, digit_extract() can be made very simple with a list comprehension:

    def digit_extract(num, digits=12):
        return [
            (num // (10**n)) % 10
            for n in range(digits, -1, -1)
        ]
    

    note the default amount of digits, so if your requirements change it will be easy to modifiy your code. If you choose to go this route, then you will have to account for the number of digits not being divisible by three.

  4. Your solution for digit_extract() is also fine, but consider using reversed(digit) instead of digit[::-1] as reversed is more readable.

  5. Since hundred() takes exactly three args, there is no need to pass it a list.

    def hundred(hundreds, tens, ones):
        ...
    

    would work instead, and if one wanted to pass a list they could call hundred(*three_digit).

  6. when documenting python functions, the convention is to provide a docstring

    def hundered(three_digit):
        """
        list [3 digit] to str
        """
    

    this allows documentation to be accessed by hundred.__doc__.

  7. Consider passing an integer argument to numberNames() and returning a string. Example:

    def numberNames(num):
        ...
        return final_name.title()
    
    if __name__ == "__main__":
        print(numberNames(input('Enter the number: ')))
    

    This way numberNames can be reused in other contexts. the if __name__ == "__main__": condition allows your program to be imported as a module and its code reused without runnint the program.

  8. You can also simplify the for loop by iterating over digits and suffixes seperatly:

    for suffix, i in zip(suffixes, range(0, 12, 3)):
        hund = hundered(digits[i:i+3])
        if hund != '':
            final_name += hund + ' ' + suffix + ' '
    

feedback on my variable naming practices

Just because you mentioned it, try not to mix camel case (i.e. functionName) and undersocres (i.e. function_name). pep8 suggests underscores and naming constant variables in all caps.

\$\endgroup\$

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.