Spaces:
Running
on
Zero
Running
on
Zero
# https://github.com/Greatdane/Convert-Numbers-to-Japanese/blob/master/Convert-Numbers-to-Japanese.py | |
# Japanese Number Converter | |
# - Currently using length functions - possible to use Recursive Functions? Difficult with the many exceptions | |
# - Works up to 9 figures (999999999) | |
romaji_dict = {".": "ten", "0": "zero", "1": "ichi", "2": "ni", "3": "san", "4": "yon", "5": "go", "6": "roku", "7": "nana", | |
"8": "hachi", "9": "kyuu", "10": "juu", "100": "hyaku", "1000": "sen", "10000": "man", "100000000": "oku", | |
"300": "sanbyaku", "600": "roppyaku", "800": "happyaku", "3000": "sanzen", "8000":"hassen", "01000": "issen"} | |
kanji_dict = {".": "点", "0": "零", "1": "一", "2": "二", "3": "三", "4": "四", "5": "五", "6": "六", "7": "七", | |
"8": "八", "9": "九", "10": "十", "100": "百", "1000": "千", "10000": "万", "100000000": "億", | |
"300": "三百", "600": "六百", "800": "八百", "3000": "三千", "8000":"八千", "01000": "一千"} | |
hiragana_dict = {".": "てん", "0": "ゼロ", "1": "いち", "2": "に", "3": "さん", "4": "よん", "5": "ご", "6": "ろく", "7": "なな", | |
"8": "はち", "9": "きゅう", "10": "じゅう", "100": "ひゃく", "1000": "せん", "10000": "まん", "100000000": "おく", | |
"300": "さんびゃく", "600": "ろっぴゃく", "800": "はっぴゃく", "3000": "さんぜん", "8000":"はっせん", "01000": "いっせん" } | |
key_dict = {"kanji" : kanji_dict, "hiragana" : hiragana_dict, "romaji": romaji_dict} | |
def len_one(convert_num,requested_dict): | |
# Returns single digit conversion, 0-9 | |
return requested_dict[convert_num] | |
def len_two(convert_num,requested_dict): | |
# Returns the conversion, when number is of length two (10-99) | |
if convert_num[0] == "0": #if 0 is first, return len_one | |
return len_one(convert_num[1],requested_dict) | |
if convert_num == "10": | |
return requested_dict["10"] # Exception, if number is 10, simple return 10 | |
if convert_num[0] == "1": # When first number is 1, use ten plus second number | |
return requested_dict["10"] + " " + len_one(convert_num[1],requested_dict) | |
elif convert_num[1] == "0": # If ending number is zero, give first number plus 10 | |
return len_one(convert_num[0],requested_dict) + " " + requested_dict["10"] | |
else: | |
num_list = [] | |
for x in convert_num: | |
num_list.append(requested_dict[x]) | |
num_list.insert(1, requested_dict["10"]) | |
# Convert to a string (from a list) | |
output = "" | |
for y in num_list: | |
output += y + " " | |
output = output[:len(output) - 1] # take off the space | |
return output | |
def len_three(convert_num,requested_dict): | |
# Returns the conversion, when number is of length three (100-999) | |
num_list = [] | |
if convert_num[0] == "1": | |
num_list.append(requested_dict["100"]) | |
elif convert_num[0] == "3": | |
num_list.append(requested_dict["300"]) | |
elif convert_num[0] == "6": | |
num_list.append(requested_dict["600"]) | |
elif convert_num[0] == "8": | |
num_list.append(requested_dict["800"]) | |
else: | |
num_list.append(requested_dict[convert_num[0]]) | |
num_list.append(requested_dict["100"]) | |
if convert_num[1:] == "00" and len(convert_num) == 3: | |
pass | |
else: | |
if convert_num[1] == "0": | |
num_list.append(requested_dict[convert_num[2]]) | |
else: | |
num_list.append(len_two(convert_num[1:], requested_dict)) | |
output = "" | |
for y in num_list: | |
output += y + " " | |
output = output[:len(output) - 1] | |
return output | |
def len_four(convert_num,requested_dict, stand_alone): | |
# Returns the conversion, when number is of length four (1000-9999) | |
num_list = [] | |
# First, check for zeros (and get deal with them) | |
if convert_num == "0000": | |
return "" | |
while convert_num[0] == "0": | |
convert_num = convert_num[1:] | |
if len(convert_num) == 1: | |
return len_one(convert_num,requested_dict) | |
elif len(convert_num) == 2: | |
return len_two(convert_num,requested_dict) | |
elif len(convert_num) == 3: | |
return len_three(convert_num,requested_dict) | |
# If no zeros, do the calculation | |
else: | |
# Have to handle 1000, depending on if its a standalone 1000-9999 or included in a larger number | |
if convert_num[0] == "1" and stand_alone: | |
num_list.append(requested_dict["1000"]) | |
elif convert_num[0] == "1": | |
num_list.append(requested_dict["01000"]) | |
elif convert_num[0] == "3": | |
num_list.append(requested_dict["3000"]) | |
elif convert_num[0] == "8": | |
num_list.append(requested_dict["8000"]) | |
else: | |
num_list.append(requested_dict[convert_num[0]]) | |
num_list.append(requested_dict["1000"]) | |
if convert_num[1:] == "000" and len(convert_num) == 4: | |
pass | |
else: | |
if convert_num[1] == "0": | |
num_list.append(len_two(convert_num[2:],requested_dict)) | |
else: | |
num_list.append(len_three(convert_num[1:],requested_dict)) | |
output = "" | |
for y in num_list: | |
output += y + " " | |
output = output[:len(output) - 1] | |
return output | |
def len_x(convert_num,requested_dict): | |
#Returns everything else.. (up to 9 digits) | |
num_list = [] | |
if len(convert_num[0:-4]) == 1: | |
num_list.append(requested_dict[convert_num[0:-4]]) | |
num_list.append(requested_dict["10000"]) | |
elif len(convert_num[0:-4]) == 2: | |
num_list.append(len_two(convert_num[0:2],requested_dict)) | |
num_list.append(requested_dict["10000"]) | |
elif len(convert_num[0:-4]) == 3: | |
num_list.append(len_three(convert_num[0:3],requested_dict)) | |
num_list.append(requested_dict["10000"]) | |
elif len(convert_num[0:-4]) == 4: | |
num_list.append(len_four(convert_num[0:4],requested_dict, False)) | |
num_list.append(requested_dict["10000"]) | |
elif len(convert_num[0:-4]) == 5: | |
num_list.append(requested_dict[convert_num[0]]) | |
num_list.append(requested_dict["100000000"]) | |
num_list.append(len_four(convert_num[1:5],requested_dict, False)) | |
if convert_num[1:5] == "0000": | |
pass | |
else: | |
num_list.append(requested_dict["10000"]) | |
else: | |
assert False, "Not yet implemented, please choose a lower number." | |
num_list.append(len_four(convert_num[-4:],requested_dict, False)) | |
output = "" | |
for y in num_list: | |
output += y + " " | |
output = output[:len(output) - 1] | |
return output | |
def remove_spaces(convert_result): | |
# Remove spaces in Hirigana and Kanji results | |
correction = "" | |
for x in convert_result: | |
if x == " ": | |
pass | |
else: | |
correction += x | |
return correction | |
def do_convert(convert_num,requested_dict): | |
#Check lengths and convert accordingly | |
if len(convert_num) == 1: | |
return(len_one(convert_num,requested_dict)) | |
elif len(convert_num) == 2: | |
return(len_two(convert_num,requested_dict)) | |
elif len(convert_num) == 3: | |
return(len_three(convert_num,requested_dict)) | |
elif len(convert_num) == 4: | |
return(len_four(convert_num,requested_dict, True)) | |
else: | |
return(len_x(convert_num,requested_dict)) | |
def split_Point(split_num,dict_choice): | |
# Used if a decmial point is in the string. | |
split_num = split_num.split(".") | |
split_num_a = split_num[0] | |
split_num_b = split_num[1] | |
split_num_b_end = " " | |
for x in split_num_b: | |
split_num_b_end += len_one(x,key_dict[dict_choice]) + " " | |
# To account for small exception of small tsu when ending in jyuu in hiragana/romaji | |
if split_num_a[-1] == "0" and split_num_a[-2] != "0" and dict_choice == "hiragana": | |
small_Tsu = Convert(split_num_a,dict_choice) | |
small_Tsu = small_Tsu[0:-1] + "っ" | |
return small_Tsu + key_dict[dict_choice]["."] + split_num_b_end | |
if split_num_a[-1] == "0" and split_num_a[-2] != "0" and dict_choice == "romaji": | |
small_Tsu = Convert(split_num_a,dict_choice) | |
small_Tsu = small_Tsu[0:-1] + "t" | |
return small_Tsu + key_dict[dict_choice]["."] + split_num_b_end | |
return Convert(split_num_a,dict_choice) + " " + key_dict[dict_choice]["."] + split_num_b_end | |
def do_kanji_convert(convert_num): | |
# Converts kanji to arabic number | |
if convert_num == "零": | |
return 0 | |
# First, needs to check for MAN 万 and OKU 億 kanji, as need to handle differently, splitting up the numbers at these intervals. | |
# key tells us whether we need to add or multiply the numbers, then we create a list of numbers in an order we need to add/multiply | |
key = [] | |
numberList = [] | |
y = "" | |
for x in convert_num: | |
if x == "万" or x == "億": | |
numberList.append(y) | |
key.append("times") | |
numberList.append(x) | |
key.append("plus") | |
y = "" | |
else: | |
y += x | |
if y != "": | |
numberList.append(y) | |
numberListConverted = [] | |
baseNumber = ["一", "二", "三", "四", "五", "六", "七", "八", "九"] | |
linkNumber = ["十", "百", "千", "万", "億"] | |
# Converts the kanji number list to arabic numbers, using the 'base number' and 'link number' list above. For a link number, we would need to | |
# link with a base number | |
for noX in numberList: | |
count = len(noX) | |
result = 0 | |
skip = 1 | |
for x in reversed(noX): | |
addTo = 0 | |
skip -= 1 | |
count = count - 1 | |
if skip == 1: | |
continue | |
if x in baseNumber: | |
for y, z in kanji_dict.items(): | |
if z == x: | |
result += int(y) | |
elif x in linkNumber: | |
if noX[count - 1] in baseNumber and count > 0: | |
for y, z in kanji_dict.items(): | |
if z == noX[count - 1]: | |
tempNo = int(y) | |
for y, z in kanji_dict.items(): | |
if z == x: | |
addTo += tempNo * int(y) | |
result += addTo | |
skip = 2 | |
else: | |
for y, z in kanji_dict.items(): | |
if z == x: | |
result += int(y) | |
numberListConverted.append(int(result)) | |
result = numberListConverted[0] | |
y = 0 | |
# Iterate over the converted list, and either multiply/add as instructed in key list | |
for x in range(1,len(numberListConverted)): | |
if key[y] == "plus": | |
try: | |
if key[y+1] == "times": | |
result = result + numberListConverted[x] * numberListConverted[x+1] | |
y += 1 | |
else: | |
result += numberListConverted[x] | |
except IndexError: | |
result += numberListConverted[-1] | |
break | |
else: | |
result = result * numberListConverted[x] | |
y += 1 | |
return result | |
def Convert(convert_num, dict_choice='hiragana'): | |
# Input formatting | |
convert_num = str(convert_num) | |
convert_num = convert_num.replace(',','') | |
dict_choice = dict_choice.lower() | |
# If all is selected as dict_choice, return as a list | |
if dict_choice == "all": | |
result_list = [] | |
for x in "kanji", "hiragana", "romaji": | |
result_list.append(Convert(convert_num,x)) | |
return result_list | |
dictionary = key_dict[dict_choice] | |
# Exit if length is greater than current limit | |
if len(convert_num) > 9: | |
return("Number length too long, choose less than 10 digits") | |
# Remove any leading zeroes | |
while convert_num[0] == "0" and len(convert_num) > 1: | |
convert_num = convert_num[1:] | |
# Check for decimal places | |
if "." in convert_num: | |
result = split_Point(convert_num,dict_choice) | |
else: | |
result = do_convert(convert_num, dictionary) | |
# Remove spaces and return result | |
if key_dict[dict_choice] == romaji_dict: | |
pass | |
else: | |
result = remove_spaces(result) | |
return result | |
def ConvertKanji(convert_num): | |
if convert_num[0] in kanji_dict.values(): | |
# Check to see if 点 (point) is in the input, and handle by splitting at 点, before and after is handled separately | |
if "点" in convert_num: | |
point = convert_num.find("点") | |
endNumber = "" | |
for x in convert_num[point+1:]: | |
endNumber += list(kanji_dict.keys())[list(kanji_dict.values()).index(x)] | |
return(str(do_kanji_convert(convert_num[0:point])) + "." + endNumber) | |
else: | |
return(str(do_kanji_convert(convert_num))) | |