Sync with files in zip

This commit is contained in:
tso
2005-06-18 16:20:11 +00:00
parent f1e887bcd2
commit 9acd82c4d5
10 changed files with 312 additions and 91 deletions

View File

@@ -1,7 +1,7 @@
'''
Module: num2word.py
Requires: num2word_*.py
Version: 0.1
Version: 0.2
Author:
Taro Ogawa (tso@users.sourceforge.org)
@@ -23,6 +23,9 @@ Notes:
The module is a wrapper for language-specific modules. It imports the
appropriate modules as defined by locale settings. If unable to
load an appropriate module, an ImportError is raised.
History:
0.2: n2w, to_card, to_ord, to_ordnum now imported correctly
'''
import locale as _locale
@@ -43,13 +46,15 @@ for _loc in [_locale.getlocale(), _locale.getdefaultlocale()]:
for _module in _modules:
try:
n2w = __import__(_module)
n2wmod = __import__(_module)
break
except ImportError:
pass
try:
to_card, to_ord, to_ordnum = n2w.to_card, n2w.to_ord, n2w.to_ordnum
n2w, to_card, to_ord, to_ordnum, to_year = (n2wmod.n2w, n2wmod.to_card,
n2wmod.to_ord, n2wmod.to_ordnum,
n2wmod.to_year)
except NameError:
raise ImportError("Could not import any of these modules: %s"
% (", ".join(_modules)))

View File

@@ -4,7 +4,7 @@ Requires: num2word_base.py
Version: 0.4
Author:
Taro Ogawa (BLAHhydroxideBLAH_removetheBLAHs@inorbit.com)
Taro Ogawa (tso@users.sourceforge.org)
Copyright:
Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
@@ -22,12 +22,16 @@ Usage:
to_card(1234567890)
to_ord(1234567890)
to_ordnum(12)
'''
from num2word_base import Num2Word_Base
#//TODO: Use orthographics
History
0.4: Use high ascii characters instead of low ascii approximations
add to_currency() and to_year()
'''
from num2word_EU import Num2Word_EU
#//TODO: Use German error messages
class Num2Word_DE(Num2Word_Base):
class Num2Word_DE(Num2Word_EU):
def set_high_numwords(self, high):
max = 3 + 6*len(high)
@@ -51,12 +55,12 @@ class Num2Word_DE(Num2Word_Base):
self.high_numwords = ["zent"]+self.gen_high_numwords(units, tens, lows)
self.mid_numwords = [(1000, "tausand"), (100, "hundert"),
(90, "neunzig"), (80, "achtzig"), (70, "siebzig"),
(60, "sechzig"), (50, "fuenfzig"), (40, "vierzig"),
(30, "dreissig")]
(60, "sechzig"), (50, "f\xFCnfzig"), (40, "vierzig"),
(30, "drei\xDFig")]
self.low_numwords = ["zwanzig", "neunzehn", "achtzen", "siebzehn",
"sechzehn", "fuenfzehn", "vierzehn", "dreizehn",
"zwoelf", "elf", "zehn", "neun", "acht", "sieben",
"sechs", "fuenf", "vier", "drei", "zwei", "eins",
"sechzehn", "f\xFCnfzehn", "vierzehn", "dreizehn",
"zw\xF6lf", "elf", "zehn", "neun", "acht", "sieben",
"sechs", "f\xFCnf", "vier", "drei", "zwei", "eins",
"null"]
self.ords = { "eins" : "ers",
"drei" : "drit",
@@ -114,6 +118,20 @@ class Num2Word_DE(Num2Word_Base):
return str(value) + "te"
def to_currency(self, val, longval=True, old=False):
if old:
return self.to_splitnum(val, hightxt="mark/s", lowtxt="pfennig/e",
jointxt="und",longval=longval)
return super(Num2Word_DE, self).to_currency(val, jointxt="und",
longval=longval)
def to_year(self, val, longval=True):
if not (val//100)%10:
return self.to_cardinal(val)
return self.to_splitnum(val, hightxt="hundert", longval=longval)
n2w = Num2Word_DE()
to_card = n2w.to_cardinal
to_ord = n2w.to_ordinal
@@ -128,6 +146,8 @@ def main():
n2w.test(val)
n2w.test(1325325436067876801768700107601001012212132143210473207540327057320957032975032975093275093275093270957329057320975093272950730)
print n2w.to_currency(112121)
print n2w.to_year(2000)
if __name__ == "__main__":
main()

View File

@@ -1,7 +1,7 @@
'''
Module: num2word_EN.py
Requires: num2word_EU.py
Version: 1.0
Version: 1.2
Author:
Taro Ogawa (tso@users.sourceforge.org)
@@ -23,9 +23,22 @@ Usage:
to_card(1234567890)
to_ord(1234567890)
to_ordnum(1234567890)
to_year(1976)
to_currency(dollars*100 + cents, longval=False)
to_currency((dollars, cents))
History:
1.2: to_ordinal_num() made shorter and simpler (but slower)
strings in merge() now interpolated
to_year() and to_currency() added
1.1: to_ordinal_num() fixed for 11,12,13
'''
from __future__ import division
import num2word_EU
class Num2Word_EN(num2word_EU.Num2Word_EU):
def set_high_numwords(self, high):
max = 3 + 3*len(high)
@@ -35,7 +48,7 @@ class Num2Word_EN(num2word_EU.Num2Word_EU):
def setup(self):
self.negword = "minus "
self.pointword = "point"
self.errmsg_nonnum = "Only numbers may be converted to words."
self.errmsg_nornum = "Only numbers may be converted to words."
self.exclude_title = ["and", "point", "minus"]
self.mid_numwords = [(1000, "thousand"), (100, "hundred"),
@@ -56,18 +69,16 @@ class Num2Word_EN(num2word_EU.Num2Word_EU):
"twelve" : "twelfth" }
def merge(self, curr, next):
ctext, cnum, ntext, nnum = curr + next
if cnum == 1 and nnum < 100:
def merge(self, (ltext, lnum), (rtext, rnum)):
if lnum == 1 and rnum < 100:
return next
elif 100 > cnum > nnum :
return (ctext + "-" + ntext, cnum + nnum)
elif cnum >= 100 > nnum:
return (ctext + " and " + ntext, cnum + nnum)
elif nnum > cnum:
return (ctext + " " + ntext, cnum * nnum)
return (ctext + ", " + ntext, cnum + nnum)
elif 100 > lnum > rnum :
return ("%s-%s"%(ltext, rtext), lnum + rnum)
elif lnum >= 100 > rnum:
return ("%s and %s"%(ltext, rtext), lnum + rnum)
elif rnum > lnum:
return ("%s %s"%(ltext, rtext), lnum * rnum)
return ("%s, %s"%(ltext, rtext), lnum + rnum)
def to_ordinal(self, value):
@@ -88,16 +99,25 @@ class Num2Word_EN(num2word_EU.Num2Word_EU):
def to_ordinal_num(self, value):
self.verify_ordinal(value)
out = str(value)
out += {"1" : "st",
"2" : "nd",
"3" : "rd" }.get(out[-1], "th")
return out
return "%s%s"%(value, self.to_ordinal(value)[-2:])
def to_year(self, val, longval=True):
if not (val//100)%10:
return self.to_cardinal(val)
return self.to_splitnum(val, hightxt="hundred", jointxt="and",
longval=longval)
def to_currency(self, val, longval=True):
return self.to_splitnum(val, hightxt="dollar/s", lowtxt="cent/s",
jointxt="and", longval=longval)
n2w = Num2Word_EN()
to_card = n2w.to_cardinal
to_ord = n2w.to_ordinal
to_ordnum = n2w.to_ordinal_num
to_year = n2w.to_year
def main():
for val in [ 1, 11, 12, 21, 31, 33, 71, 80, 81, 91, 99, 100, 101, 102, 155,
@@ -105,8 +125,10 @@ def main():
8280, 8291, 150000, 500000, 1000000, 2000000, 2000001,
-21212121211221211111, -2.121212, -1.0000100]:
n2w.test(val)
n2w.test(1325325436067876801768700107601001012212132143210473207540327057320957032975032975093275093275093270957329057320975093272950730)
for val in [1,120,1000,1120,1800, 1976,2000,2010,2099,2171]:
print val, "is", n2w.to_currency(val)
print val, "is", n2w.to_year(val)
if __name__ == "__main__":

63
num2word_EN_GB.py Normal file
View File

@@ -0,0 +1,63 @@
'''
Module: num2word_EN_GB.py
Requires: num2word_EN.py
Version: 1.0
Author:
Taro Ogawa (tso@users.sourceforge.org)
Copyright:
Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
Licence:
This module is distributed under the Lesser General Public Licence.
http://www.opensource.org/licenses/lgpl-license.php
Data from:
http://www.uni-bonn.de/~manfear/large.php
Usage:
from num2word_EN import n2w, to_card, to_ord, to_ordnum
to_card(1234567890)
n2w.is_title = True
to_card(1234567890)
to_ord(1234567890)
to_ordnum(1234567890)
to_year(1976)
to_currency(pounds*100 + pence)
to_currency((pounds,pence))
History:
1.0: Split from num2word_EN with the addition of to_currency()
'''
from num2word_EN import Num2Word_EN
class Num2Word_EN_GB(Num2Word_EN):
def to_currency(self, val, longval=True):
return self.to_splitnum(val, hightxt="pound/s", lowtxt="pence",
jointxt="and", longval=longval)
n2w = Num2Word_EN_GB()
to_card = n2w.to_cardinal
to_ord = n2w.to_ordinal
to_ordnum = n2w.to_ordinal_num
to_year = n2w.to_year
def main():
for val in [ 1, 11, 12, 21, 31, 33, 71, 80, 81, 91, 99, 100, 101, 102, 155,
180, 300, 308, 832, 1000, 1001, 1061, 1100, 1500, 1701, 3000,
8280, 8291, 150000, 500000, 1000000, 2000000, 2000001,
-21212121211221211111, -2.121212, -1.0000100]:
n2w.test(val)
n2w.test(1325325436067876801768700107601001012212132143210473207540327057320957032975032975093275093275093270957329057320975093272950730)
for val in [1,120,1000,1120,1800, 1976,2000,2010,2099,2171]:
print val, "is", n2w.to_currency(val)
print val, "is", n2w.to_year(val)
if __name__ == "__main__":
main()

View File

@@ -1,6 +1,6 @@
'''
Module: num2word_EN_old.py
Requires: num2word_EN.py
Module: num2word_EN_GB_old.py
Requires: num2word_EN_GB_old.py
Version: 0.3
Author:
@@ -18,17 +18,23 @@ Usage:
to_card(1234567890)
to_ord(1234567890)
to_ordnum(12)
'''
import num2word_EN
class Num2Word_EN_old(num2word_EN.Num2Word_EN):
History:
0.3: Rename from num2word_EN_old
Todo:
Currency (pounds/shillings/pence)
'''
from num2word_EN_GB import Num2Word_EN_GB
class Num2Word_EN_GB_old(Num2Word_EN_GB):
def base_setup(self):
sclass = super(num2word_EN.Num2Word_EN, self)
sclass = super(Num2Word_EN_GB, self)
self.set_high_numwords = sclass.set_high_numwords
sclass.base_setup()
n2w = Num2Word_EN_old()
n2w = Num2Word_EN_GB_old()
to_card = n2w.to_cardinal
to_ord = n2w.to_ordinal
to_ordnum = n2w.to_ordinal_num
@@ -41,6 +47,9 @@ def main():
n2w.test(val)
n2w.test(1325325436067876801768700107601001012212132143210473207540327057320957032975032975093275093275093270957329057320975093272950730)
for val in [1,120,1000,1120,1800, 1976,2000,2010,2099,2171]:
print val, "is", n2w.to_currency(val)
print val, "is", n2w.to_year(val)
if __name__ == "__main__":
main()

View File

@@ -1,10 +1,10 @@
'''
Module: num2word_ES.py
Requires: num2word_EU.py
Version: 0.2
Version: 0.3
Author:
Taro Ogawa (BLAHhydroxideBLAH@inorbit.removeBLAHtwice.com)
Taro Ogawa (tso@users.sourceforge.org)
Copyright:
Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
@@ -19,8 +19,13 @@ Data from:
Usage:
from num2word_ES import to_card, to_ord, to_ordnum
to_card(1234567890)
# to_ord(1234567890)
# to_ordnum(12)
to_ord(1234567890)
to_ordnum(12)
History:
0.3: Use high ascii characters instead of low ascii approximations
String interpolation where it makes things clearer
add to_currency()
'''
from num2word_EU import Num2Word_EU
@@ -34,7 +39,7 @@ class Num2Word_ES(Num2Word_EU):
max = 3 + 6*len(high)
for word, n in zip(high, range(max, 3, -6)):
self.cards[10**(n-3)] = word + "illo'n"
self.cards[10**(n-3)] = word + "ill\xf2n"
def setup(self):
@@ -50,8 +55,8 @@ class Num2Word_ES(Num2Word_EU):
(80, "ochenta"), (70, "setenta"), (60, "sesenta"),
(50,"cincuenta"), (40,"cuarenta")]
self.low_numwords = ["vientinueve", "vientiocho", "vientisiete",
"vientise'is", "vienticinco", "vienticuatro",
"vientitre's", "vientido's", "vientiuno",
"vientis\xE8is", "vienticinco", "vienticuatro",
"vientitr\xE8s", "vientid\xF2s", "vientiuno",
"viente", "diecinueve", "dieciocho", "diecisiete",
"dieciseis", "quince", "catorce", "trece", "doce",
"once", "diez", "nueve", "ocho", "siete", "seis",
@@ -62,10 +67,10 @@ class Num2Word_ES(Num2Word_EU):
4 : "cuart",
5 : "quint",
6 : "sext",
7 : "se'ptim",
7 : "s\xE8ptim",
8 : "octav",
9 : "noven",
10 : "de'cim" }
10 : "d\xE8cim" }
def merge(self, curr, next):
@@ -80,8 +85,8 @@ class Num2Word_ES(Num2Word_EU):
if nnum < cnum:
if cnum < 100:
return (ctext + " y " + ntext, cnum + nnum)
return (ctext + " " + ntext, cnum + nnum)
return ("%s y %s"%(ctext, ntext), cnum + nnum)
return ("%s %s"%(ctext, ntext), cnum + nnum)
elif (not nnum % 1000000) and cnum > 1:
ntext = ntext[:-3] + "ones"
@@ -110,7 +115,15 @@ class Num2Word_ES(Num2Word_EU):
def to_ordinal_num(self, value):
self.verify_ordinal(value)
# Correct for fem?
return str(value) + "^o"
return "%s\xB0"%value
def to_currency(self, val, longval=True, old=False):
if old:
return self.to_splitnum(val, hightxt="peso/s", lowtxt="peseta/s",
divisor=1000, jointxt="y", longval=longval)
return super(Num2Word_ES, self).to_currency(val, jointxt="y",
longval=longval)
n2w = Num2Word_ES()
@@ -126,7 +139,9 @@ def main():
n2w.test(val)
n2w.test(1325325436067876801768700107601001012212132143210473207540327057320957032975032975093275093275093270957329057320975093272950730)
print n2w.to_currency(1222)
print n2w.to_currency(1222, old=True)
print n2w.to_year(1222)
if __name__ == "__main__":
main()

View File

@@ -1,10 +1,10 @@
'''
Module: num2word_EU.py
Requires: num2word_base.py
Version: 1.0
Version: 1.1
Author:
Taro Ogawa (BLAHhydroxideBLAH@inorbit.removeBLAHtwice.com)
Taro Ogawa (tso@users.sourceforge.org)
Copyright:
Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
@@ -15,6 +15,9 @@ Licence:
Data from:
http://www.uni-bonn.de/~manfear/large.php
History:
1.1: add to_currency()
'''
from num2word_base import Num2Word_Base
@@ -34,3 +37,8 @@ class Num2Word_EU(Num2Word_Base):
tens = ["dec", "vigint", "trigint", "quadragint", "quinquagint",
"sexagint", "septuagint", "octogint", "nonagint"]
self.high_numwords = ["cent"]+self.gen_high_numwords(units, tens, lows)
def to_currency(self, val, longval=True, jointxt=""):
return self.to_splitnum(val, hightxt="Euro/s", lowtxt="Euro cent/s",
jointxt=jointxt, longval=longval)

View File

@@ -1,7 +1,7 @@
'''
Module: num2word_FR.py
Requires: num2word_EU.py
Version: 0.4
Version: 0.5
Author:
Taro Ogawa (tso@users.sourceforge.org)
@@ -14,18 +14,23 @@ Licence:
http://www.opensource.org/licenses/lgpl-license.php
Data from:
http://www.ouc.bc.ca/mola/fr/handouts/numbers.doc.
http://www.ouc.bc.ca/mola/fr/handouts/numbers.doc
http://www.realfrench.net/units/Interunit_63.html
http://www.sover.net/~daxtell/france/Euro/euro.htm
Usage:
from num2word_FR import to_card, to_ord, to_ordnum
to_card(1234567890)
# to_ord(1234567890)
# to_ordnum(12)
to_ord(1234567890)
to_ordnum(12)
History:
0.5: Use high ascii characters instead of low ascii approximations
String interpolation where it makes things clearer
to_currency() added [to_year works by default]
'''
from num2word_EU import Num2Word_EU
#//TODO: correct orthographics
#//TODO: error messages in French
#//TODO: ords
class Num2Word_FR(Num2Word_EU):
@@ -42,7 +47,7 @@ class Num2Word_FR(Num2Word_EU):
self.low_numwords = ["vingt", "dix-neuf", "dix-huit", "dix-sept",
"seize", "quinze", "quatorze", "treize", "douze",
"onze", "dix", "neuf", "huit", "sept", "six",
"cinq", "quatre", "trois", "deux", "un", "ze'ro"]
"cinq", "quatre", "trois", "deux", "un", "z\xE8ro"]
def merge(self, curr, next):
@@ -60,13 +65,16 @@ class Num2Word_FR(Num2Word_EU):
if nnum < cnum < 100:
if nnum % 10 == 1 and cnum <> 80:
return (ctext + " et " + ntext, cnum + nnum)
return (ctext + "-" + ntext, cnum + nnum)
return ("%s et %s"%(ctext, ntext), cnum + nnum)
return ("%s-%s"%(ctext, ntext), cnum + nnum)
elif nnum > cnum:
return (ctext + " " + ntext, cnum * nnum)
return (ctext + " " + ntext, cnum + nnum)
return ("%s %s"%(ctext, ntext), cnum * nnum)
return ("%s %s"%(ctext, ntext), cnum + nnum)
# Is this right for such things as 1001 - "mille uni<6E>me" instead of
# "mille premier"?? "milli<6C>me"??
def to_ordinal(self,value):
self.verify_ordinal(value)
if value == 1:
@@ -74,7 +82,7 @@ class Num2Word_FR(Num2Word_EU):
word = self.to_cardinal(value)
if word[-1] == "e":
word = word[:-1]
return word + "ie'me"
return word + "i\xE8me"
def to_ordinal_num(self, value):
@@ -83,6 +91,12 @@ class Num2Word_FR(Num2Word_EU):
out += {"1" : "er" }.get(out[-1], "me")
return out
def to_currency(self, val, longval=True, old=False):
hightxt = "Euro/s"
if old:
hightxt="franc/s"
return self.to_splitnum(val, hightxt=hightxt, lowtxt="centime/s",
jointxt="et",longval=longval)
n2w = Num2Word_FR()
to_card = n2w.to_cardinal
@@ -97,6 +111,8 @@ def main():
n2w.test(val)
n2w.test(1325325436067876801768700107601001012212132143210473207540327057320957032975032975093275093275093270957329057320975093272950730)
print n2w.to_currency(112121)
print n2w.to_year(1996)
if __name__ == "__main__":

View File

@@ -3,7 +3,7 @@ Module: num2word_base.py
Version: 1.0
Author:
Taro Ogawa (BLAHhydroxideBLAH_removetheBLAHs@inorbit.com)
Taro Ogawa (tso@users.sourceforge.org)
Copyright:
Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
@@ -12,27 +12,14 @@ Licence:
This module is distributed under the Lesser General Public Licence.
http://www.opensource.org/licenses/lgpl-license.php
Data from:
http://www.uni-bonn.de/~manfear/large.php
History:
1.1: add to_splitnum() and inflect()
add to_year() and to_currency() stubs
'''
from __future__ import generators
class OrderedMapping(dict):
def __init__(self, *pairs):
self.order = []
for key, val in pairs:
self[key] = val
def __setitem__(self, key, val):
if key not in self:
self.order.append(key)
super(OrderedMapping, self).__setitem__(key, val)
def __iter__(self):
for item in self.order:
yield item
from orderedmapping import OrderedMapping
class Num2Word_Base(object):
@@ -153,11 +140,11 @@ class Num2Word_Base(object):
def clean(self, val):
out = val
while len(val) <> 1:
while len(val) != 1:
out = []
curr, next = val[:2]
if isinstance(curr, tuple) and isinstance(next, tuple):
out.append(self.merge(curr, next))
left, right = val[:2]
if isinstance(left, tuple) and isinstance(right, tuple):
out.append(self.merge(left, right))
if val[2:]:
out.append(val[2:])
else:
@@ -209,6 +196,48 @@ class Num2Word_Base(object):
return value
# Trivial version
def inflect(self, value, text):
text = text.split("/")
if value == 1:
return text[0]
return "".join(text)
#//CHECK: generalise? Any others like pounds/shillings/pence?
def to_splitnum(self, val, hightxt="", lowtxt="", jointxt="",
divisor=100, longval=True):
out = []
try:
high, low = val
except TypeError:
high, low = divmod(val, divisor)
if high:
hightxt = self.title(self.inflect(high, hightxt))
out.append(self.to_cardinal(high))
if low:
if longval:
if hightxt:
out.append(hightxt)
if jointxt:
out.append(self.title(jointxt))
elif hightxt:
out.append(hightxt)
if low:
out.append(self.to_cardinal(low))
if lowtxt and longval:
out.append(self.title(self.inflect(low, lowtxt)))
return " ".join(out)
def to_year(self, value, **kwargs):
return self.to_cardinal(value)
def to_currency(self, value, **kwargs):
return self.to_cardinal(value)
def base_setup(self):
pass

34
orderedmapping.py Normal file
View File

@@ -0,0 +1,34 @@
'''
Module: orderedmapping.py
Version: 1.0
Author:
Taro Ogawa (tso@users.sourceforge.org)
Copyright:
Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
Licence:
This module is distributed under the Lesser General Public Licence.
http://www.opensource.org/licenses/lgpl-license.php
'''
from __future__ import generators
class OrderedMapping(dict):
def __init__(self, *pairs):
self.order = []
for key, val in pairs:
self[key] = val
def __setitem__(self, key, val):
if key not in self:
self.order.append(key)
super(OrderedMapping, self).__setitem__(key, val)
def __iter__(self):
for item in self.order:
yield item
def __repr__(self):
out = ["%s: %s"%(repr(item), repr(self[item])) for item in self]
out = ", ".join(out)
return "{%s}"%out