| |
| |
|
|
| """From https://github.com/peresolb/number-conversion/""" |
| import sys |
| import os |
| import nltk |
|
|
|
|
| |
| b = { |
| 1: "én", |
| 2: "to", |
| 3: "tre", |
| 4: "fire", |
| 5: "fem", |
| 6: "seks", |
| 7: "sju", |
| 8: "åtte", |
| 9: "ni", |
| 10: "ti", |
| } |
| b_nn = { |
| 1: "ein", |
| 2: "to", |
| 3: "tre", |
| 4: "fire", |
| 5: "fem", |
| 6: "seks", |
| 7: "sju", |
| 8: "åtte", |
| 9: "ni", |
| 10: "ti", |
| } |
|
|
| |
| t = { |
| 11: "elleve", |
| 12: "tolv", |
| 13: "tretten", |
| 14: "fjorten", |
| 15: "femten", |
| 16: "seksten", |
| 17: "sytten", |
| 18: "atten", |
| 19: "nitten", |
| } |
|
|
|
|
| |
| do = { |
| 20: "tjue", |
| 30: "tretti", |
| 40: "førti", |
| 50: "femti", |
| 60: "seksti", |
| 70: "sytti", |
| 80: "åtti", |
| 90: "nitti", |
| } |
|
|
|
|
| |
| doo = {100: "hundre"} |
|
|
|
|
| |
| dooo = {1000: "tusen"} |
|
|
|
|
| |
| def _revdict(numberdict): |
| newdict = {} |
| for k, v in numberdict.items(): |
| newdict[v] = k |
| return newdict |
|
|
|
|
| |
| |
| b_r, b_nn_r, t_r, do_r, doo_r, dooo_r = ( |
| _revdict(b), |
| _revdict(b_nn), |
| _revdict(t), |
| _revdict(do), |
| _revdict(doo), |
| _revdict(dooo), |
| ) |
|
|
|
|
| def _oneten(nr, reverse=False, nn=False): |
| """Function taking an int from 1-10 and returning the corresponding word, |
| or, if reverse=True, taking a numberword from 1-10 and returning the digit""" |
| if reverse == False: |
| if not type(nr) is int: |
| return None |
| if nr <= 10: |
| if nn == False: |
| return b[nr] |
| else: |
| return b_nn[nr] |
| else: |
| if not type(nr) is str: |
| return None |
| if nn == False: |
| if nr in b_r.keys(): |
| return b_r[nr] |
| else: |
| if nr in b_nn_r.keys(): |
| return b_nn_r[nr] |
|
|
|
|
| def _onedig(nr, reverse=False, nn=False): |
| if reverse == False: |
| if not _oneten(nr) == "ti": |
| if nn == False: |
| return _oneten(nr) |
| else: |
| return _oneten(nr, nn=True) |
| if reverse == True: |
| if not _oneten(nr, reverse=True) == 10: |
| if nn == False: |
| return _oneten(nr, reverse=True) |
| else: |
| return _oneten(nr, reverse=True, nn=True) |
|
|
|
|
| def _teen(nr, reverse=False): |
| """Function taking a primitive two-digit int in the teen range and returning the |
| corresponding word, or, if reverse=True, the corresponding number word""" |
| if reverse == False: |
| if not type(nr) is int: |
| return None |
| if nr in t.keys(): |
| return t[nr] |
| else: |
| if not type(nr) is str: |
| return None |
| if nr in t_r.keys(): |
| return t_r[nr] |
|
|
|
|
| def _twodig(nr, reverse=False): |
| """Function taking a primitive two-digit int in the range 20-90 and returning |
| the corresponding word, or, if reverse=True, the corresponding number word""" |
| if reverse == False: |
| if not type(nr) is int: |
| return None |
| if nr in do.keys(): |
| return do[nr] |
| else: |
| if not type(nr) is str: |
| return None |
| if nr in do_r.keys(): |
| return do_r[nr] |
|
|
|
|
| def _numparser(numword, nn=False): |
| """Parse word to see if they start with a wd in firstnumwords. |
| If yes, return firstnumword and second part""" |
| if not type(numword) is str: |
| return None |
| firstpart = "" |
| scndpart = "" |
| firstnumwords = list(do_r.keys()) |
| for s in firstnumwords: |
| if numword.startswith(s): |
| slength = len(s) |
| firstpart = s |
| scndpart = numword[slength:] |
| if nn == False: |
| if ( |
| scndpart in b_r.keys() and b_r[scndpart] < 10 |
| ): |
| return (firstpart, scndpart) |
| else: |
| if ( |
| scndpart in b_nn_r.keys() and b_nn_r[scndpart] < 10 |
| ): |
| return (firstpart, scndpart) |
|
|
|
|
| def _one_to_nineteen(nr, reverse=False, nn=False): |
| """Function taking a primitive two-digit int in the range 1-19 |
| and returning the corresponding word, or, if reverse=True, the corresponding number word""" |
| if reverse == False: |
| if not type(nr) is int: |
| return None |
| if nr < 11: |
| if nn == False: |
| return _oneten(nr) |
| else: |
| return _oneten(nr, nn=True) |
| elif nr < 20: |
| return _teen(nr) |
| else: |
| if not type(nr) is str: |
| return None |
| if nn == False: |
| if type(_oneten(nr, reverse=True)) is int: |
| return _oneten(nr, reverse=True) |
| elif type(_teen(nr, reverse=True)): |
| return _teen(nr, reverse=True) |
| else: |
| if type(_oneten(nr, reverse=True, nn=True)) is int: |
| return _oneten(nr, reverse=True, nn=True) |
| elif type(_teen(nr, reverse=True)): |
| return _teen(nr, reverse=True) |
|
|
|
|
| def _one_to_nn(nr, reverse=False, nn=False): |
| """Function taking an int in the range 1-99 and returning the corresponding word. Reverse as before""" |
| if reverse == False: |
| if not type(nr) is int: |
| return None |
| if nr > 0: |
| if nr < 20: |
| if nn == False: |
| return _one_to_nineteen(nr) |
| else: |
| return _one_to_nineteen(nr, nn=True) |
| elif nr < 100: |
| if nr in do.keys(): |
| return _twodig(nr) |
| else: |
| nrstring = str(nr) |
| frstdig = int(nrstring[0]) * 10 |
| scndig = int(nrstring[1]) |
| frstwd = _twodig(frstdig) |
| if nn == False: |
| scnwd = _onedig(scndig) |
| else: |
| scnwd = _onedig(scndig, nn=True) |
| nrwd = frstwd + scnwd |
| return nrwd |
| else: |
| if not type(nr) is str: |
| return None |
| if nn == False: |
| if type(_one_to_nineteen(nr, reverse=True)) is int: |
| return _one_to_nineteen(nr, reverse=True) |
| elif type(_twodig(nr, reverse=True)) is int: |
| return _twodig(nr, reverse=True) |
| else: |
| if _numparser(nr) == None: |
| return None |
| parsed = _numparser(nr) |
| first = _twodig(parsed[0], reverse=True) |
| second = _one_to_nineteen(parsed[1], reverse=True) |
| return first + second |
| else: |
| if type(_one_to_nineteen(nr, reverse=True, nn=True)) is int: |
| return _one_to_nineteen(nr, reverse=True, nn=True) |
| elif type(_twodig(nr, reverse=True)) is int: |
| return _twodig(nr, reverse=True) |
| else: |
| if _numparser(nr, nn=True) == None: |
| return None |
| parsed = _numparser(nr, nn=True) |
| first = _twodig(parsed[0], reverse=True) |
| second = _one_to_nineteen(parsed[1], reverse=True, nn=True) |
| return first + second |
|
|
|
|
| def _one_to_nnn(nr, reverse=False, nn=False): |
| """Function taking an int in the range 1-999 and returning the corresponding word. Reverse as before""" |
| if reverse == False: |
| if not type(nr) is int: |
| return None |
| if nr == 0: |
| return None |
| if nr < 100: |
| if nn == False: |
| return _one_to_nn(nr) |
| else: |
| return _one_to_nn(nr, nn=True) |
| elif nr < 1000: |
| if nr == 100: |
| return doo[100] |
| else: |
| nrstring = str(nr) |
| frstdig = int(nrstring[0]) |
| scndig = int(nrstring[1]) |
| thrdig = int(nrstring[2]) |
| scthdig = int(nrstring[1:]) |
| if nn == False: |
| frstwd = _onedig(frstdig) |
| else: |
| frstwd = _onedig(frstdig, nn=True) |
| nrwd = "" |
| if scndig == 0: |
| if thrdig == 0: |
| nrwd = "%s %s" % (frstwd, doo[100]) |
| else: |
| if nn == False: |
| thrdwd = _one_to_nn(thrdig) |
| else: |
| thrdwd = _one_to_nn(thrdig, nn=True) |
| if frstdig != 1: |
| nrwd = "%s %s og %s" % ( |
| frstwd, |
| doo[100], |
| thrdwd, |
| ) |
| else: |
| nrwd = "%s og %s" % (doo[100], thrdwd) |
| else: |
| scthwd = "" |
| if nn == False: |
| scthwd = _one_to_nn(scthdig) |
| else: |
| scthwd = _one_to_nn(scthdig, nn=True) |
| if frstdig != 1: |
| nrwd = "%s %s og %s" % (frstwd, doo[100], scthwd) |
| else: |
| nrwd = "%s og %s" % (doo[100], scthwd) |
| return nrwd |
| else: |
| if not type(nr) is str: |
| return None |
| if type(doo_r.get(nr, None)) is int: |
| return doo_r[nr] |
| elif ( |
| len(nr.split(" ")) == 1 |
| and type(_one_to_nn(nr, reverse=True)) is int |
| and nn == False |
| ): |
| return _one_to_nn(nr, reverse=True) |
| elif ( |
| len(nr.split(" ")) == 1 |
| and type(_one_to_nn(nr, reverse=True, nn=True)) is int |
| and nn == True |
| ): |
| return _one_to_nn(nr, reverse=True, nn=True) |
| elif len(nr.split(" ")) == 2: |
| splitwords = nr.split(" ") |
| if nn == False and nr == "ett hundre": |
| return 100 |
| elif nn == True and nr == "eitt hundre": |
| return 100 |
| elif ( |
| type(_one_to_nn(splitwords[0], reverse=True)) is int |
| and splitwords[1] == "hundre" |
| ): |
| return _one_to_nn(splitwords[0], reverse=True) * 100 |
| elif len(nr.split(" ")) == 3: |
| splitwords = nr.split(" ") |
| if splitwords[0] == "hundre" and splitwords[1] == "og": |
| if nn == False: |
| if type(_one_to_nn(splitwords[2], reverse=True)) is int: |
| return 100 + _one_to_nn(splitwords[2], reverse=True) |
| else: |
| if type(_one_to_nn(splitwords[2], reverse=True, nn=True)) is int: |
| return 100 + _one_to_nn(splitwords[2], reverse=True, nn=True) |
| else: |
| return None |
| elif len(nr.split(" ")) == 4: |
| splitwords = nr.split(" ") |
| if nn == False: |
| if ( |
| splitwords[0] == "ett" |
| and splitwords[1] == "hundre" |
| and splitwords[2] == "og" |
| and type(_one_to_nn(splitwords[3], reverse=True)) is int |
| ): |
| return 100 + _one_to_nn(splitwords[3], reverse=True) |
| elif ( |
| type(_one_to_nn(splitwords[0], reverse=True)) is int |
| and _one_to_nn(splitwords[0], reverse=True) < 10 |
| and splitwords[1] == "hundre" |
| and splitwords[2] == "og" |
| and type(_one_to_nn(splitwords[3], reverse=True)) is int |
| ): |
| hundreds = _one_to_nn(splitwords[0], reverse=True) * 100 |
| tens = _one_to_nn(splitwords[3], reverse=True) |
| return hundreds + tens |
| else: |
| return None |
| else: |
| if ( |
| splitwords[0] == "eitt" |
| and splitwords[1] == "hundre" |
| and splitwords[2] == "og" |
| and type(_one_to_nn(splitwords[3], reverse=True, nn=True)) is int |
| ): |
| return 100 + _one_to_nn(splitwords[3], reverse=True, nn=True) |
| elif ( |
| type(_one_to_nn(splitwords[0], reverse=True, nn=True)) is int |
| and _one_to_nn(splitwords[0], reverse=True, nn=True) < 10 |
| and splitwords[1] == "hundre" |
| and splitwords[2] == "og" |
| and type(_one_to_nn(splitwords[3], reverse=True, nn=True)) is int |
| ): |
| hundreds = _one_to_nn(splitwords[0], reverse=True, nn=True) * 100 |
| tens = _one_to_nn(splitwords[3], reverse=True, nn=True) |
| return hundreds + tens |
| else: |
| return None |
|
|
|
|
| def _high_hundred(nr, nn=False): |
| """In Norwegian, as in English, it is possible to express the numbers 1100-1999 with hundreds, |
| e.g. "tolv hundre og nittiåtte", /twelve hundred and ninety-eight/. We want to be able to convert |
| these to integers. However, we don't need to produce them, so this algoritm only goes from strings to integers""" |
| if not type(nr) is str: |
| return None |
| if len(nr.split(" ")) > 1: |
| frstwd = nr.split(" ")[0] |
| if not type(_teen(frstwd, reverse=True)) is int: |
| return None |
| frstdig = _teen(frstwd, reverse=True) |
| if len(nr.split(" ")) == 2 and nr.split(" ")[1] == "hundre": |
| return frstdig * 100 |
| elif ( |
| len(nr.split(" ")) == 4 |
| and nr.split(" ")[1] == "hundre" |
| and nr.split(" ")[2] == "og" |
| ): |
| if ( |
| nn == False and type(_one_to_nn(nr.split(" ")[3], reverse=True)) is int |
| ): |
| lastdigs = _one_to_nn(nr.split(" ")[3], reverse=True) |
| return (frstdig * 100) + lastdigs |
| elif ( |
| nn == True |
| and type(_one_to_nn(nr.split(" ")[3], reverse=True, nn=True)) is int |
| ): |
| lastdigs = _one_to_nn(nr.split(" ")[3], reverse=True, nn=True) |
| return (frstdig * 100) + lastdigs |
|
|
|
|
| def _one_to_nnnnnn(nr, reverse=False, nn=False): |
| """Function taking an int in the range 1-999999 and returning the corresponding word. Reverse as before""" |
| if reverse == False: |
| if not type(nr) is int: |
| return None |
| if nr == 0: |
| return None |
| if nr < 1000: |
| if nn == False: |
| return _one_to_nnn(nr) |
| else: |
| return _one_to_nnn(nr, nn=True) |
| elif nr < 1000000: |
| if nr == 1000: |
| if nn == False: |
| return "ett tusen" |
| else: |
| return "eitt tusen" |
| else: |
| nrstring = str(nr) |
| ultdig = int(nrstring[-1]) |
| penultdig = int(nrstring[-2]) |
| antepenultdig = int(nrstring[-3]) |
| ult_and_penultdig = int(nrstring[-2:]) |
| ult_penult_antepenultdig = int(nrstring[-3:]) |
| tailstring = "" |
| if antepenultdig == 0: |
| if penultdig == 0: |
| if ultdig == 0: |
| tailstring = "tusen" |
| else: |
| if nn == False: |
| ultstring = _one_to_nnn(ultdig) |
| tailstring = "tusen og %s" % ultstring |
| else: |
| ultstring = _one_to_nnn(ultdig, nn=True) |
| tailstring = "tusen og %s" % ultstring |
| else: |
| if nn == False: |
| ult_and_penultstring = _one_to_nnn(ult_and_penultdig) |
| tailstring = ( |
| "tusen og %s" % ult_and_penultstring |
| ) |
| else: |
| ult_and_penultstring = _one_to_nnn( |
| ult_and_penultdig, nn=True |
| ) |
| tailstring = ( |
| "tusen og %s" % ult_and_penultstring |
| ) |
| else: |
| if nn == False: |
| ult_penult_antepenultstring = _one_to_nnn( |
| ult_penult_antepenultdig |
| ) |
| if str(ult_penult_antepenultdig)[0] == "1": |
| tailstring = ( |
| "tusen ett %s" % ult_penult_antepenultstring |
| ) |
| else: |
| tailstring = ( |
| "tusen %s" % ult_penult_antepenultstring |
| ) |
| else: |
| ult_penult_antepenultstring = _one_to_nnn( |
| ult_penult_antepenultdig, nn=True |
| ) |
| if str(ult_penult_antepenultdig)[0] == "1": |
| tailstring = ( |
| "tusen eitt %s" % ult_penult_antepenultstring |
| ) |
| else: |
| tailstring = ( |
| "tusen %s" % ult_penult_antepenultstring |
| ) |
| startdigs = int( |
| nrstring[:-3] |
| ) |
| startstring = "" |
| if startdigs == 1: |
| if nn == False: |
| startstring = "ett" |
| else: |
| startstring = "eitt" |
| elif startdigs > 99 and startdigs < 200: |
| if nn == False: |
| startnumstring = _one_to_nnn(startdigs) |
| startstring = "ett %s" % startnumstring |
| else: |
| startnumstring = _one_to_nnn(startdigs, nn=True) |
| startstring = "eitt %s" % startnumstring |
| else: |
| if nn == False: |
| startstring = _one_to_nnn(startdigs) |
| else: |
| startstring = _one_to_nnn(startdigs, nn=True) |
| numstring = "%s %s" % (startstring, tailstring) |
| return numstring |
| else: |
| if not type(nr) is str: |
| return None |
| if type(_one_to_nnn(nr, reverse=True)) is int and nn == False: |
| return _one_to_nnn(nr, reverse=True) |
| elif type(_one_to_nnn(nr, reverse=True, nn=True)) is int and nn == True: |
| return _one_to_nnn(nr, reverse=True, nn=True) |
| elif nr == "tusen": |
| return 1000 |
| elif ( |
| len(nr.split(" ")) > 1 and nr.split(" ")[-1] == "tusen" |
| ): |
| wdlist = nr.split(" ") |
| firstphrase = " ".join(wdlist[:-1]) |
| if type(_one_to_nnn(firstphrase, reverse=True)) is int and nn == False: |
| firstdig = _one_to_nnn(firstphrase, reverse=True) |
| return firstdig * 1000 |
| elif ( |
| type(_one_to_nnn(firstphrase, reverse=True, nn=True)) is int |
| and nn == True |
| ): |
| firstdig = _one_to_nnn(firstphrase, reverse=True, nn=True) |
| return firstdig * 1000 |
| elif ( |
| len(nr.split(" ")) == 2 and nr.split(" ")[0] == "ett" and nn == False |
| ): |
| return 1000 |
| elif len(nr.split(" ")) == 2 and nr.split(" ")[0] == "eitt" and nn == True: |
| return 1000 |
| else: |
| return None |
| else: |
| if len(nr.split(" ")) > 1: |
| numwordlist = nr.split(" ") |
| if ( |
| "tusen" in numwordlist |
| ): |
| tusenind = numwordlist.index("tusen") |
| lastwords = numwordlist[tusenind:] |
| firstwords = numwordlist[:tusenind] |
| lastdigs = 0 |
| if len(lastwords) == 3: |
| if lastwords[1] == "og": |
| lastword = lastwords[-1] |
| if nn == False: |
| lastdigs = _one_to_nnn(lastword, reverse=True) |
| elif nn == True: |
| lastdigs = _one_to_nnn(lastword, reverse=True, nn=True) |
| elif ( |
| nn == False |
| and type(_one_to_nnn(" ".join(lastwords[1:]), reverse=True)) |
| is int |
| and lastwords[2] == "hundre" |
| ): |
| hundredphrase = " ".join(lastwords[1:]) |
| lastdigs = _one_to_nnn(hundredphrase, reverse=True) |
| elif ( |
| nn == True |
| and type( |
| _one_to_nnn( |
| " ".join(lastwords[1:]), reverse=True, nn=True |
| ) |
| ) |
| is int |
| and lastwords[2] == "hundre" |
| ): |
| hundredphrase = " ".join(lastwords[1:]) |
| lastdigs = _one_to_nnn(hundredphrase, reverse=True, nn=True) |
| else: |
| return None |
| elif ( |
| len(lastwords) == 5 and lastwords[2] == "hundre" |
| ): |
| hundredphrase = " ".join(lastwords[1:]) |
| if nn == False: |
| lastdigs = _one_to_nnn(hundredphrase, reverse=True) |
| else: |
| lastdigs = _one_to_nnn(hundredphrase, reverse=True, nn=True) |
| else: |
| return None |
| firstdigs = 0 |
| firstphrase = " ".join(firstwords) |
| if len(firstwords) == 0: |
| firstdigs = 1000 |
| elif ( |
| len(firstwords) == 1 and firstwords[0] == "ett" and nn == False |
| ): |
| firstdigs = 1000 |
| elif ( |
| len(firstwords) == 1 and firstwords[0] == "eitt" and nn == True |
| ): |
| firstdigs = 1000 |
| elif ( |
| type(_one_to_nnn(firstphrase, reverse=True)) is int |
| and nn == False |
| ): |
| firstdigs = _one_to_nnn(firstphrase, reverse=True) * 1000 |
| elif ( |
| type(_one_to_nnn(firstphrase, reverse=True, nn=True)) is int |
| and nn == True |
| ): |
| firstdigs = ( |
| _one_to_nnn(firstphrase, reverse=True, nn=True) * 1000 |
| ) |
| else: |
| return None |
| if type(firstdigs) is int and type(lastdigs) is int: |
| return firstdigs + lastdigs |
|
|
|
|
| def convert_nums(nr, reverse=False, nn=False): |
| """Functions for converting numbers. Only works for numbers in range 0-999999 for now""" |
| if reverse == False: |
| if type(nr) is int: |
| returnstring = "" |
| if nr == 0: |
| returnstring = "null" |
| elif nr < 1000000: |
| if nn == False: |
| returnstring = _one_to_nnnnnn(nr) |
| else: |
| returnstring = _one_to_nnnnnn(nr, nn=True) |
| else: |
| return None |
| return returnstring |
| else: |
| if type(nr) is str: |
| returnint = 0 |
| if nr == "null": |
| returnint = 0 |
| elif nn == False and type(_one_to_nnnnnn(nr, reverse=True)) is int: |
| returnint = _one_to_nnnnnn(nr, reverse=True) |
| elif nn == True and type(_one_to_nnnnnn(nr, reverse=True, nn=True)) is int: |
| returnint = _one_to_nnnnnn(nr, reverse=True, nn=True) |
| elif nn == False and type(_high_hundred(nr)) is int: |
| returnint = _high_hundred(nr) |
| elif nn == True and type(_high_hundred(nr, nn=True)) is int: |
| returnint = _high_hundred(nr, nn=True) |
| else: |
| return None |
| return returnint |
|
|
|
|
| if __name__ == "__main__": |
| |
| mydigit = 243564 |
| mynumstring = "hundre og atten tusen fire hundre og trettién" |
| mydigit_nn = 34381 |
| mynumstring_nn = "tre hundre og førtiein" |
|
|
| print( |
| "Digit conversion bm: %s\nString conversion bm: %s" |
| % (convert_nums(mydigit), convert_nums(mynumstring, reverse=True)) |
| ) |
| print( |
| "Digit conversion nn: %s\nString conversion nn: %s" |
| % ( |
| convert_nums(mydigit_nn, nn=True), |
| convert_nums(mynumstring_nn, nn=True, reverse=True), |
| ) |
| ) |
|
|