=== modified file 'bin/tools/amount_to_text.py' --- bin/tools/amount_to_text.py 2009-01-04 22:13:29 +0000 +++ bin/tools/amount_to_text.py 2009-11-13 11:06:47 +0000 @@ -24,147 +24,128 @@ # French #------------------------------------------------------------- -unites = { - 0: '', 1:'un', 2:'deux', 3:'trois', 4:'quatre', 5:'cinq', 6:'six', 7:'sept', 8:'huit', 9:'neuf', - 10:'dix', 11:'onze', 12:'douze', 13:'treize', 14:'quatorze', 15:'quinze', 16:'seize', - 21:'vingt et un', 31:'trente et un', 41:'quarante et un', 51:'cinquante et un', 61:'soixante et un', - 71:'septante et un', 91:'nonante et un', 80:'quatre-vingts' -} - -dizaine = { - 1: 'dix', 2:'vingt', 3:'trente',4:'quarante', 5:'cinquante', 6:'soixante', 7:'septante', 8:'quatre-vingt', 9:'nonante' -} - -centaine = { - 0:'', 1: 'cent', 2:'deux cent', 3:'trois cent',4:'quatre cent', 5:'cinq cent', 6:'six cent', 7:'sept cent', 8:'huit cent', 9:'neuf cent' -} - -mille = { - 0:'', 1:'mille' -} - -def _100_to_text_fr(chiffre): - if chiffre in unites: - return unites[chiffre] - else: - if chiffre%10>0: - return dizaine[chiffre / 10]+'-'+unites[chiffre % 10] - else: - return dizaine[chiffre / 10] - -def _1000_to_text_fr(chiffre): - d = _100_to_text_fr(chiffre % 100) - d2 = chiffre/100 - if d2>0 and d: - return centaine[d2]+' '+d - elif d2>1 and not(d): - return centaine[d2]+'s' - else: - return centaine[d2] or d - -def _10000_to_text_fr(chiffre): - if chiffre==0: - return 'zero' - part1 = _1000_to_text_fr(chiffre % 1000) - part2 = mille.get(chiffre / 1000, _1000_to_text_fr(chiffre / 1000)+' mille') - if part2 and part1: - part1 = ' '+part1 - return part2+part1 - + +to_19_fr = ( 'zéro', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', + 'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize', + 'quatorze', 'quinze', 'seize', 'dix-sept', 'dix-huit', 'dix-neuf' ) +tens_fr = ( 'vingt', 'trente', 'quarante', 'Cinquante', 'Soixante', 'Soixante-dix', 'Quatre-vingts', 'Quatre-vingt Dix') +denom_fr = ( '', + 'Mille', 'Millions', 'Milliards', 'Billions', 'Quadrillions', + 'Quintillion', 'Sextillion', 'Septillion', 'Octillion', 'Nonillion', + 'Décillion', 'Undecillion', 'Duodecillion', 'Tredecillion', 'Quattuordecillion', + 'Sexdecillion', 'Septendecillion', 'Octodecillion', 'Icosillion', 'Vigintillion' ) + +# convert a value < 100 to French. +def _convert_nn_fr(val): + if val < 20: + return to_19_fr[val] + for (dcap, dval) in ((k, 20 + (10 * v)) for (v, k) in enumerate(tens_fr)): + if dval + 10 > val: + if val % 10: + return dcap + '-' + to_19_fr[val % 10] + return dcap + +# convert a value < 1000 to french, special cased because it is the level that kicks +# off the < 100 special case. The rest are more general. This also allows you to +# get strings in the form of 'forty-five hundred' if called directly. +def _convert_nnn_fr(val): + word = '' + (mod, rem) = (val % 100, val // 100) + if rem > 0: + word = to_19_fr[rem] + ' Cent' + if mod > 0: + word = word + ' ' + if mod > 0: + word = word + _convert_nn_fr(mod) + return word + +def french_number(val): + if val < 100: + return _convert_nn_fr(val) + if val < 1000: + return _convert_nnn_fr(val) + for (didx, dval) in ((v - 1, 1000 ** v) for v in range(len(denom_fr))): + if dval > val: + mod = 1000 ** didx + l = val // mod + r = val - (l * mod) + ret = _convert_nnn_fr(l) + ' ' + denom_fr[didx] + if r > 0: + ret = ret + ', ' + french_number(r) + return ret + def amount_to_text_fr(number, currency): - units_number = int(number) units_name = currency - if units_number > 1: - units_name += 's' - units = _10000_to_text_fr(units_number) - units = units_number and '%s %s' % (units, units_name) or '' - - cents_number = int(number * 100) % 100 - cents_name = (cents_number > 1) and 'cents' or 'cent' - cents = _100_to_text_fr(cents_number) - cents = cents_number and '%s %s' % (cents, cents_name) or '' - - if units and cents: - cents = ' '+cents - - return units + cents + list = str(number).split('.') + start_word = french_number(abs(int(list[0]))) + end_word = french_number(int(list[1])) + cents_number = int(list[1]) + cents_name = (cents_number > 1) and ' Cents' or ' Cent' + final_result = start_word +' '+units_name+' '+ end_word +' '+cents_name + return final_result #------------------------------------------------------------- # Dutch #------------------------------------------------------------- -units_nl = { - 0:'', 1:'een', 2:'twee', 3:'drie', 4:'vier', 5:'vijf', 6:'zes', 7:'zeven', 8:'acht', 9:'negen', - 10:'tien', 11:'elf', 12:'twaalf', 13:'dertien', 14:'veertien' -} - -tens_nl = { - 1: 'tien', 2:'twintig', 3:'dertig',4:'veertig', 5:'vijftig', 6:'zestig', 7:'zeventig', 8:'tachtig', 9:'negentig' -} - -hundreds_nl = { - 0:'', 1: 'honderd', -} - -thousands_nl = { - 0:'', 1:'duizend' -} - -def _100_to_text_nl(number): - if number in units_nl: - return units_nl[number] - else: - if number%10 > 0: - if number>10 and number<20: - return units_nl[number % 10]+tens_nl[number / 10] - else: - units = units_nl[number % 10] - if units[-1] == 'e': - joinword = 'ën' - else: - joinword = 'en' - return units+joinword+tens_nl[number / 10] - else: - return tens_nl[number / 10] - -def _1000_to_text_nl(number): - part1 = _100_to_text_nl(number % 100) - part2 = hundreds_nl.get(number / 100, units_nl[number/100] + hundreds_nl[1]) - if part2 and part1: - part1 = ' ' + part1 - return part2 + part1 - -def _10000_to_text_nl(number): - if number==0: - return 'nul' - part1 = _1000_to_text_nl(number % 1000) - if thousands_nl.has_key(number / 1000): - part2 = thousands_nl[number / 1000] - else: - if (number / 1000 % 100 > 0) and (number / 1000 > 100): - space = ' ' - else: - space = '' - part2 = _1000_to_text_nl(number / 1000) + space + thousands_nl[1] - if part2 and part1: - part1 = ' ' + part1 - return part2 + part1 - +to_19_nl = ( 'Nul', 'Een', 'Twee', 'Drie', 'Vier', 'Vijf', 'Zes', + 'Zeven', 'Acht', 'Negen', 'Tien', 'Elf', 'Twaalf', 'Dertien', + 'Veertien', 'Vijftien', 'Zestien', 'Zeventien', 'Achttien', 'Negentien' ) +tens_nl = ( 'Twintig', 'Dertig', 'Veertig', 'Vijftig', 'Zestig', 'Zeventig', 'Tachtig', 'Negentig') +denom_nl = ( '', + 'Duizend', 'Miljoen', 'Miljard', 'Triljoen', 'Quadriljoen', + 'Quintillion', 'Sextiljoen', 'Septillion', 'Octillion', 'Nonillion', + 'Decillion', 'Undecillion', 'Duodecillion', 'Tredecillion', 'Quattuordecillion', + 'Sexdecillion', 'Septendecillion', 'Octodecillion', 'Novemdecillion', 'Vigintillion' ) + +# convert a value < 100 to Dutch. +def _convert_nn_nl(val): + if val < 20: + return to_19_nl[val] + for (dcap, dval) in ((k, 20 + (10 * v)) for (v, k) in enumerate(tens_nl)): + if dval + 10 > val: + if val % 10: + return dcap + '-' + to_19_nl[val % 10] + return dcap + +# convert a value < 1000 to Dutch, special cased because it is the level that kicks +# off the < 100 special case. The rest are more general. This also allows you to +# get strings in the form of 'forty-five hundred' if called directly. +def _convert_nnn_nl(val): + word = '' + (mod, rem) = (val % 100, val // 100) + if rem > 0: + word = to_19_nl[rem] + ' Honderd' + if mod > 0: + word = word + ' ' + if mod > 0: + word = word + _convert_nn_nl(mod) + return word + +def dutch_number(val): + if val < 100: + return _convert_nn_nl(val) + if val < 1000: + return _convert_nnn_nl(val) + for (didx, dval) in ((v - 1, 1000 ** v) for v in range(len(denom_nl))): + if dval > val: + mod = 1000 ** didx + l = val // mod + r = val - (l * mod) + ret = _convert_nnn_nl(l) + ' ' + denom_nl[didx] + if r > 0: + ret = ret + ', ' + dutch_number(r) + return ret + def amount_to_text_nl(number, currency): - units_number = int(number) units_name = currency - units = _10000_to_text_nl(units_number) - units = units_number and '%s %s' % (units, units_name) or '' - - cents_number = int(number * 100) % 100 - cents_name = 'cent' - cents = _100_to_text_nl(cents_number) - cents = cents_number and '%s %s' % (cents, cents_name) or '' - - if units and cents: - cents = ' ' + cents - - return units + cents + list = str(number).split('.') + start_word = dutch_number(int(list[0])) + end_word = dutch_number(int(list[1])) + cents_number = int(list[1]) + cents_name = (cents_number > 1) and 'cent' or 'cent' + final_result = start_word +' '+units_name+' '+ end_word +' '+cents_name + return final_result #------------------------------------------------------------- # Generic functions @@ -183,17 +164,17 @@ Example: 1654: mille six cent cinquante-quatre. """ - if nbr > 1000000: -#TODO: use logger - print "WARNING: number too large '%d', can't translate it!" % (nbr,) - return str(nbr) +# if nbr > 1000000: +##TODO: use logger +# print "WARNING: number too large '%d', can't translate it!" % (nbr,) +# return str(nbr) if not _translate_funcs.has_key(lang): #TODO: use logger print "WARNING: no translation function found for lang: '%s'" % (lang,) #TODO: (default should be en) same as above lang = 'fr' - return _translate_funcs[lang](nbr, currency) + return _translate_funcs[lang](abs(nbr), currency) if __name__=='__main__': from sys import argv === modified file 'bin/tools/amount_to_text_en.py' --- bin/tools/amount_to_text_en.py 2009-07-20 09:32:28 +0000 +++ bin/tools/amount_to_text_en.py 2009-11-13 10:53:12 +0000 @@ -23,85 +23,66 @@ #------------------------------------------------------------- #ENGLISH #------------------------------------------------------------- - -ones = { - 0: '', 1:'One', 2:'Two', 3:'Three', 4:'Four', 5:'Five', 6:'Six', 7:'Seven', 8:'Eight', 9:'Nine', - 10:'Ten', 11:'Eleven', 12:'Twelve', 13:'Thirteen', 14:'Forteen', 15:'Fifteen', 16:'Sixteen', 17:"Seventeen",18:"Eighteen",19:"Nineteen", -} - -tens = { - 1: 'Ten', 2: 'Twenty ', 3:'Thirty', 4:'Forty', 5:'Fifty', 6: 'Sixty', 7 : 'Seventy', 8:'Eighty' ,9: 'Ninety'} - -hundred = { - 0:'',1: 'One Hundred', 2: 'Two Hundred', 3: 'Three Hundred', 4 :'Four Hundred', 5: 'Five Hundred', 6: 'Six Hundred', 7 :'Seven Hundred', 8:' Eight Hundred ', 9:'Nine Hundred ' -} - -thousands ={ - 0:'',1: 'One Thousand' -} - -lacs = { - 0:'',1: 'Lac' -} - -def _100_to_text(number): - if number in ones: - return ones[number] - else: - if number%10>0: - return tens[number / 10]+'-'+ones[number % 10] - else: - return tens[number / 10] - -def _1000_to_text(number): - d = _100_to_text(number % 100) - d2 = number/100 - if d2>0 and d: - return hundred[d2]+' '+d - elif d2>1 and not(d): - return hundred[d2]+'s' - else: - return hundred[d2] or d - -def _10000_to_text(number): - if number==0: - return 'zero' - part1 = _1000_to_text(number % 1000) - part2 = thousands.get(number / 1000, _1000_to_text(number / 1000)+' Thousands') - if part2 and part1: - part1 = ' '+part1 - return part2+part1 - -def _1000000_to_text(number): - if number==0: - return 'zero' - part1 = _10000_to_text(number % 100000) - part2 = lacs.get(number / 100000, _10000_to_text(number / 100000)+' Lacs') - if part2 and part1: - part1 = ' '+part1 - return part2+part1 - +from tools.translate import _ + +to_19 = ( 'Zero', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', + 'Seven', 'Eight', 'Nine', 'Ten', 'Eleven', 'Twelve', 'Thirteen', + 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen' ) +tens = ( 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety') +denom = ( '', + 'Thousand', 'Million', 'Billion', 'Trillion', 'Quadrillion', + 'Quintillion', 'Sextillion', 'Septillion', 'Octillion', 'Nonillion', + 'Decillion', 'Undecillion', 'Duodecillion', 'Tredecillion', 'Quattuordecillion', + 'Sexdecillion', 'Septendecillion', 'Octodecillion', 'Novemdecillion', 'Vigintillion' ) + +# convert a value < 100 to English. +def _convert_nn(val): + if val < 20: + return to_19[val] + for (dcap, dval) in ((k, 20 + (10 * v)) for (v, k) in enumerate(tens)): + if dval + 10 > val: + if val % 10: + return dcap + '-' + to_19[val % 10] + return dcap + +# convert a value < 1000 to english, special cased because it is the level that kicks +# off the < 100 special case. The rest are more general. This also allows you to +# get strings in the form of 'forty-five hundred' if called directly. +def _convert_nnn(val): + word = '' + (mod, rem) = (val % 100, val // 100) + if rem > 0: + word = to_19[rem] + ' Hundred' + if mod > 0: + word = word + ' ' + if mod > 0: + word = word + _convert_nn(mod) + return word + +def english_number(val): + if val < 100: + return _convert_nn(val) + if val < 1000: + return _convert_nnn(val) + for (didx, dval) in ((v - 1, 1000 ** v) for v in range(len(denom))): + if dval > val: + mod = 1000 ** didx + l = val // mod + r = val - (l * mod) + ret = _convert_nnn(l) + ' ' + denom[didx] + if r > 0: + ret = ret + ', ' + english_number(r) + return ret def amount_to_text(number, currency): - lacs_number = int(number) units_name = currency - if lacs_number > 1: - units_name += 's' - - lacs = _1000000_to_text(lacs_number) - lacs = lacs_number and '%s %s' % (lacs, units_name) or '' - - units_number = int(number * 10000) % 10000 - units = _10000_to_text(units_number) - units = units_number and '%s %s' % (units, units_name) or '' - - cents_number = int(number * 100) % 100 - cents_name = (cents_number > 1) and 'cents' or 'cent' - cents = _100_to_text(cents_number) - cents = cents_number and '%s %s' % (cents.lower(), cents_name) or '' - if cents: - lacs += ' and %s' % (cents, ) - return lacs + list = str(number).split('.') + start_word = english_number(int(list[0])) + end_word = english_number(int(list[1])) + cents_number = int(list[1]) + cents_name = (cents_number > 1) and 'Cents' or 'Cent' + final_result = start_word +' '+units_name+' and ' + end_word +' '+cents_name + return final_result #------------------------------------------------------------- @@ -119,15 +100,15 @@ 1654: thousands six cent cinquante-quatre. """ import netsvc - if nbr > 10000000: - netsvc.Logger().notifyChannel('translate', netsvc.LOG_WARNING, _("Number too large '%d', can not translate it")) - return str(nbr) +# if nbr > 10000000: +# netsvc.Logger().notifyChannel('translate', netsvc.LOG_WARNING, _("Number too large '%d', can not translate it")) +# return str(nbr) if not _translate_funcs.has_key(lang): netsvc.Logger().notifyChannel('translate', netsvc.LOG_WARNING, _("no translation function found for lang: '%s'" % (lang,))) #TODO: (default should be en) same as above lang = 'en' - return _translate_funcs[lang](nbr, currency) + return _translate_funcs[lang](abs(nbr), currency) if __name__=='__main__': from sys import argv