Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjusted handling for big numbers in Portuguese and Spanish #600

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 25 additions & 5 deletions num2words/lang_ES.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,12 +208,19 @@ class Num2Word_ES(Num2Word_EU):
'ZWL': (GENERIC_DOLLARS, ('céntimo', 'céntimos')),
}

# //CHECK: Is this sufficient??
GIGA_SUFFIX = None
MEGA_SUFFIX = "illón"

def set_high_numwords(self, high):
max = 3 + 3 * len(high)
for word, n in zip(high, range(max, 3, -3)):
if n % 6 == 0:
self.cards[10 ** n] = word + self.MEGA_SUFFIX
else:
self.cards[10 ** n] = "mil " + word + self.MEGA_SUFFIX

def setup(self):
lows = ["cuatr", "tr", "b", "m"]
lows = ["cuatr", "cuatr", "tr", "tr", "b", "b", "m", "m"]
self.high_numwords = self.gen_high_numwords([], [], lows)
self.negword = "menos "
self.pointword = "punto"
Expand Down Expand Up @@ -277,15 +284,24 @@ def merge(self, curr, next):
if cnum == 1:
if nnum < 1000000:
return next
ctext = "un"
if nnum >= 1000000000 and "mil " in ntext:
ctext = ""
else:
ctext = "un"
elif cnum == 100 and not nnum % 1000 == 0:
ctext += "t" + self.gender_stem

if nnum < cnum:
if cnum < 100:
if cnum == 1000000000 and nnum > 1:
ctext = ctext[:-3] + "lones"
elif cnum < 100:
return "%s y %s" % (ctext, ntext), cnum + nnum
return "%s %s" % (ctext, ntext), cnum + nnum
elif (not nnum % 1000000) and cnum > 1:

is_mil_multiple = nnum % 1000000 == 0 and cnum > 1
contains_mil = nnum >= 1000000000 and "mil " in ntext

if is_mil_multiple or contains_mil:
ntext = ntext[:-3] + "lones"

if nnum == 100:
Expand All @@ -300,6 +316,10 @@ def merge(self, curr, next):
else:
ntext = " " + ntext

if ctext == "":
result = " ".join([ctext, ntext])
result = result.strip()
return (result, cnum * nnum)
return (ctext + ntext, cnum * nnum)

def to_ordinal(self, value):
Expand Down
22 changes: 18 additions & 4 deletions num2words/lang_PT.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,17 @@ class Num2Word_PT(Num2Word_EU):
GIGA_SUFFIX = None
MEGA_SUFFIX = "ilião"

def set_high_numwords(self, high):
max = 3 + 3 * len(high)
for word, n in zip(high, range(max, 3, -3)):
if n % 6 == 0:
self.cards[10 ** n] = word + self.MEGA_SUFFIX
else:
self.cards[10 ** n] = "mil " + word + self.MEGA_SUFFIX

def setup(self):
super(Num2Word_PT, self).setup()
lows = ["quatr", "tr", "b", "m"]
lows = ["quatr", "quatr", "tr", "tr", "b", "b", "m", "m"]
self.high_numwords = self.gen_high_numwords([], [], lows)
self.negword = "menos "
self.pointword = "vírgula"
Expand Down Expand Up @@ -120,7 +128,11 @@ def merge(self, curr, next):
if cnum == 1:
if nnum < 1000000:
return next
ctext = "um"
if nnum < 1000000 or "mil " not in ntext:
ctext = "um"
else:
ctext = ""

elif cnum == 100 and not nnum % 1000 == 0:
ctext = "cento"

Expand All @@ -129,21 +141,23 @@ def merge(self, curr, next):
return ("%s e %s" % (ctext, ntext), cnum + nnum)
return ("%s e %s" % (ctext, ntext), cnum + nnum)

elif (not nnum % 1000000000) and cnum > 1:
elif ((not nnum % 1000000000) and cnum > 1) or ctext == "":
ntext = ntext[:-4] + "liões"
elif (not nnum % 1000000) and cnum > 1:
ntext = ntext[:-4] + "lhões"
# correct "milião" to "milhão"
if ntext == 'milião':
ntext = 'milhão'
elif 'miliões' in ntext:
ntext = ntext.replace('miliões', 'milhões')
if nnum == 100:
ctext = self.hundreds[cnum]
ntext = ""

else:
ntext = " " + ntext

return (ctext + ntext, cnum * nnum)
return ((ctext + ntext).strip(), cnum * nnum)

def to_cardinal(self, value):
result = super(Num2Word_PT, self).to_cardinal(value)
Expand Down
3 changes: 3 additions & 0 deletions num2words/lang_PT_BR.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ def setup(self):
self.low_numwords[3] = 'dezessete'
self.low_numwords[4] = 'dezesseis'

lows = ["quatr", "tr", "b", "m"]
self.high_numwords = self.gen_high_numwords([], [], lows)

self.thousand_separators = {
3: "milésimo",
6: "milionésimo",
Expand Down
40 changes: 38 additions & 2 deletions tests/test_pt.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,27 @@ def test_cardinal_integer(self):
num2words(73421, lang='pt'),
'setenta e três mil quatrocentos e vinte e um'
)
self.assertEqual(num2words(100000, lang='pt'), 'cem mil')
self.assertEqual(
num2words(100000, lang='pt'),
'cem mil'
)
self.assertEqual(
num2words(1000014, lang='pt'),
'um milhão e catorze'
)
self.assertEqual(
num2words(1001000, lang='pt'),
'um milhão e mil'
)

self.assertEqual(
num2words(250050, lang='pt'),
'duzentos e cinquenta mil e cinquenta'
)
self.assertEqual(
num2words(4000014, lang='pt'),
'quatro milhões e catorze'
)
self.assertEqual(
num2words(6000000, lang='pt'), 'seis milhões'
)
Expand All @@ -107,7 +123,7 @@ def test_cardinal_integer(self):
)
self.assertEqual(
num2words(145254635102, lang='pt'),
'cento e quarenta e cinco mil duzentos e cinquenta e quatro '
'cento e quarenta e cinco mil milhões duzentos e cinquenta e quatro '
'milhões seiscentos e trinta e cinco mil cento e dois'
)
self.assertEqual(
Expand All @@ -134,6 +150,26 @@ def test_cardinal_integer(self):
num2words(2000000000000000000, lang='pt'),
'dois triliões'
)
self.assertEqual(
num2words(1000000000000000000000000001, lang='pt'),
'mil quatriliões e um'
)
self.assertEqual(
num2words(11111111111111111111111111111, lang='pt'),
'onze mil quatriliões e cento e onze quatriliões '
'e cento e onze mil triliões e cento e onze triliões '
'e cento e onze mil biliões cento e onze biliões cento e onze '
'mil milhões cento e onze milhões cento e onze mil cento e onze'
)
self.assertEqual(
num2words(500000000000000000000000000, lang='pt'),
'quinhentos quatriliões'
)
self.assertEqual(
num2words(900000000000000000000000000009, lang='pt'),
'novecentos mil quatriliões e nove'
)


def test_cardinal_integer_negative(self):
self.assertEqual(num2words(-1, lang='pt'), 'menos um')
Expand Down
Loading