Skip to content

Instantly share code, notes, and snippets.

@matabares
Created March 31, 2020 17:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matabares/fffd50d233e2d9baeecdc27ff73c590d to your computer and use it in GitHub Desktop.
Save matabares/fffd50d233e2d9baeecdc27ff73c590d to your computer and use it in GitHub Desktop.
from __future__ import print_function
american_number_system = {
'zero': 0,
'one': 1,
'two': 2,
'three': 3,
'four': 4,
'five': 5,
'six': 6,
'seven': 7,
'eight': 8,
'nine': 9,
'ten': 10,
'eleven': 11,
'twelve': 12,
'thirteen': 13,
'fourteen': 14,
'fifteen': 15,
'sixteen': 16,
'seventeen': 17,
'eighteen': 18,
'nineteen': 19,
'twenty': 20,
'thirty': 30,
'forty': 40,
'fifty': 50,
'sixty': 60,
'seventy': 70,
'eighty': 80,
'ninety': 90,
'hundred': 100,
'thousand': 1000,
'million': 1000000,
'billion': 1000000000,
'point': '.'
}
decimal_words = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']
"""
#TODO
indian_number_system = {
'zero': 0,
'one': 1,
'two': 2,
'three': 3,
'four': 4,
'five': 5,
'six': 6,
'seven': 7,
'eight': 8,
'nine': 9,
'ten': 10,
'eleven': 11,
'twelve': 12,
'thirteen': 13,
'fourteen': 14,
'fifteen': 15,
'sixteen': 16,
'seventeen': 17,
'eighteen': 18,
'nineteen': 19,
'twenty': 20,
'thirty': 30,
'forty': 40,
'fifty': 50,
'sixty': 60,
'seventy': 70,
'eighty': 80,
'ninety': 90,
'hundred': 100,
'thousand': 1000,
'lac': 100000,
'lakh': 100000,
'crore': 10000000
}
"""
"""
function to form numeric multipliers for million, billion, thousand etc.
input: list of strings
return value: integer
"""
def number_formation(number_words):
numbers = []
for number_word in number_words:
numbers.append(american_number_system[number_word])
if len(numbers) == 4:
return (numbers[0] * numbers[1]) + numbers[2] + numbers[3]
elif len(numbers) == 3:
return numbers[0] * numbers[1] + numbers[2]
elif len(numbers) == 2:
if 100 in numbers:
return numbers[0] * numbers[1]
else:
return numbers[0] + numbers[1]
else:
return numbers[0]
"""
function to convert post decimal digit words to numerial digits
input: list of strings
output: double
"""
def get_decimal_sum(decimal_digit_words):
decimal_number_str = []
for dec_word in decimal_digit_words:
if(dec_word not in decimal_words):
return 0
else:
decimal_number_str.append(american_number_system[dec_word])
final_decimal_string = '0.' + ''.join(map(str,decimal_number_str))
return float(final_decimal_string)
"""
function to return integer for an input `number_sentence` string
input: string
output: int or double or None
"""
def word_to_num(number_sentence):
if type(number_sentence) is not str:
raise ValueError("Type of input is not string! Please enter a valid number word (eg. \'two million twenty three thousand and forty nine\')")
number_sentence = number_sentence.replace('-', ' ')
number_sentence = number_sentence.lower() # converting input to lowercase
if(number_sentence.isdigit()): # return the number if user enters a number string
return int(number_sentence)
split_words = number_sentence.strip().split() # strip extra spaces and split sentence into words
clean_numbers = []
clean_decimal_numbers = []
# removing and, & etc.
for word in split_words:
if word in american_number_system:
clean_numbers.append(word)
# Error message if the user enters invalid input!
if len(clean_numbers) == 0:
raise ValueError("No valid number words found! Please enter a valid number word (eg. two million twenty three thousand and forty nine)")
# Error if user enters million,billion, thousand or decimal point twice
if clean_numbers.count('thousand') > 1 or clean_numbers.count('million') > 1 or clean_numbers.count('billion') > 1 or clean_numbers.count('point')> 1:
raise ValueError("Redundant number word! Please enter a valid number word (eg. two million twenty three thousand and forty nine)")
# separate decimal part of number (if exists)
if clean_numbers.count('point') == 1:
clean_decimal_numbers = clean_numbers[clean_numbers.index('point')+1:]
clean_numbers = clean_numbers[:clean_numbers.index('point')]
billion_index = clean_numbers.index('billion') if 'billion' in clean_numbers else -1
million_index = clean_numbers.index('million') if 'million' in clean_numbers else -1
thousand_index = clean_numbers.index('thousand') if 'thousand' in clean_numbers else -1
if (thousand_index > -1 and (thousand_index < million_index or thousand_index < billion_index)) or (million_index>-1 and million_index < billion_index):
raise ValueError("Malformed number! Please enter a valid number word (eg. two million twenty three thousand and forty nine)")
total_sum = 0 # storing the number to be returned
if len(clean_numbers) > 0:
# hack for now, better way TODO
if len(clean_numbers) == 1:
total_sum += american_number_system[clean_numbers[0]]
else:
if billion_index > -1:
billion_multiplier = number_formation(clean_numbers[0:billion_index])
total_sum += billion_multiplier * 1000000000
if million_index > -1:
if billion_index > -1:
million_multiplier = number_formation(clean_numbers[billion_index+1:million_index])
else:
million_multiplier = number_formation(clean_numbers[0:million_index])
total_sum += million_multiplier * 1000000
if thousand_index > -1:
if million_index > -1:
thousand_multiplier = number_formation(clean_numbers[million_index+1:thousand_index])
elif billion_index > -1 and million_index == -1:
thousand_multiplier = number_formation(clean_numbers[billion_index+1:thousand_index])
else:
thousand_multiplier = number_formation(clean_numbers[0:thousand_index])
total_sum += thousand_multiplier * 1000
if thousand_index > -1 and thousand_index != len(clean_numbers)-1:
hundreds = number_formation(clean_numbers[thousand_index+1:])
elif million_index > -1 and million_index != len(clean_numbers)-1:
hundreds = number_formation(clean_numbers[million_index+1:])
elif billion_index > -1 and billion_index != len(clean_numbers)-1:
hundreds = number_formation(clean_numbers[billion_index+1:])
elif thousand_index == -1 and million_index == -1 and billion_index == -1:
hundreds = number_formation(clean_numbers)
else:
hundreds = 0
total_sum += hundreds
# adding decimal part to total_sum (if exists)
if len(clean_decimal_numbers) > 0:
decimal_sum = get_decimal_sum(clean_decimal_numbers)
total_sum += decimal_sum
return total_sum
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment