Improve german support (#222)

* german: fix case in currency names

Also, add more tests for german language.

* german: default to amount of euros, not cents

If a non-float number is provided, interpret it as a quantity in euros,
not cents.

* german: handle "ein Euro" vs "eins Euro" exception

* german: prefer "einhundert" over "hundert"

"hundert" is usually colloquial (even if widely used).

Exception: "eintausendste" and "hundertste" are special cases, here
"hundertste" and "tausendste" are usually preferred (see Duden).
This commit is contained in:
Hugo Lefeuvre
2018-11-16 22:19:36 +01:00
committed by Ernesto Rodriguez Ortiz
parent 4d8c93847c
commit 66a47e2423
2 changed files with 45 additions and 12 deletions

View File

@@ -78,7 +78,9 @@ class Num2Word_DE(Num2Word_EU):
ctext, cnum, ntext, nnum = curr + next
if cnum == 1:
if nnum < 10 ** 6:
if nnum == 100 or nnum == 1000:
return ("ein" + ntext, nnum)
elif nnum < 10 ** 6:
return next
ctext = "eine"
@@ -110,22 +112,36 @@ class Num2Word_DE(Num2Word_EU):
if outword.endswith(key):
outword = outword[:len(outword) - len(key)] + self.ords[key]
break
return outword + "te"
res = outword + "te"
# Exception: "hundertste" is usually preferred over "einhundertste"
if res == "eintausendste" or res == "einhundertste":
res = res.replace("ein", "", 1)
return res
def to_ordinal_num(self, value):
self.verify_ordinal(value)
return str(value) + "."
def to_currency(self, val, longval=True, old=False):
hightxt = "euro"
lowtxt = "cent"
hightxt = "Euro"
lowtxt = "Cent"
if old:
hightxt = "mark"
lowtxt = "pfennig/e"
hightxt = "Mark"
lowtxt = "Pfennig/e"
return self.to_splitnum(val, hightxt=hightxt, lowtxt=lowtxt,
cents = int(round(val*100))
res = self.to_splitnum(cents, hightxt=hightxt, lowtxt=lowtxt,
jointxt="und", longval=longval)
# Handle exception, in german is "ein Euro" and not "eins Euro"
if res.startswith("eins "):
res = res.replace("eins ", "ein ", 1)
return res
def to_year(self, val, longval=True):
if not (val // 100) % 10:
return self.to_cardinal(val)

View File

@@ -52,6 +52,7 @@ class Num2WordsDETest(TestCase):
)
def test_cardinal_at_some_numbers(self):
self.assertEqual(num2words(100, lang='de'), "einhundert")
self.assertEqual(num2words(2000000, lang='de'), "zwei millionen")
self.assertEqual(num2words(4000000000, lang='de'), "vier milliarden")
self.assertEqual(num2words(1000000000, lang='de'), "eine milliarde")
@@ -65,7 +66,7 @@ class Num2WordsDETest(TestCase):
self.assertEqual(
num2words(4500072900000111, lang='de'),
"vier billiarden fünfhundert billionen " +
"zweiundsiebzig milliarden neunhundert millionen hundertelf"
"zweiundsiebzig milliarden neunhundert millionen einhundertelf"
)
def test_ordinal_num(self):
@@ -79,12 +80,28 @@ class Num2WordsDETest(TestCase):
self.assertRaises(TypeError, num2words, 2.453, ordinal=True, lang='de')
def test_currency(self):
self.assertEqual(num2words(12.00, to='currency', lang='de'),
'zwölf euro')
self.assertEqual(num2words(1, lang='de', to='currency'),
'ein Euro')
self.assertEqual(num2words(12, lang='de', to='currency'),
'zwölf Euro')
self.assertEqual(num2words(12.00, lang='de', to='currency'),
'zwölf Euro')
self.assertEqual(num2words(100.0, lang='de', to='currency'),
"einhundert Euro")
self.assertEqual(num2words(190, lang='de', to='currency'),
"einhundertneunzig Euro")
self.assertEqual(num2words(1.90, lang='de', to='currency'),
"ein Euro und neunzig Cent")
self.assertEqual(num2words(3.4, lang='de', to='currency'),
"drei Euro und vierzig Cent")
self.assertEqual(num2words(20.18, lang='de', to='currency'),
"zwanzig Euro und achtzehn Cent")
self.assertEqual(num2words(3.04, lang='de', to='currency'),
"drei Euro und vier Cent")
def test_old_currency(self):
self.assertEqual(num2words(12.00, to='currency', lang='de', old=True),
'zwölf mark')
'zwölf Mark')
def test_year(self):
self.assertEqual(num2words(2002, to='year', lang='de'),