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 ctext, cnum, ntext, nnum = curr + next
if cnum == 1: if cnum == 1:
if nnum < 10 ** 6: if nnum == 100 or nnum == 1000:
return ("ein" + ntext, nnum)
elif nnum < 10 ** 6:
return next return next
ctext = "eine" ctext = "eine"
@@ -110,21 +112,35 @@ class Num2Word_DE(Num2Word_EU):
if outword.endswith(key): if outword.endswith(key):
outword = outword[:len(outword) - len(key)] + self.ords[key] outword = outword[:len(outword) - len(key)] + self.ords[key]
break 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): def to_ordinal_num(self, value):
self.verify_ordinal(value) self.verify_ordinal(value)
return str(value) + "." return str(value) + "."
def to_currency(self, val, longval=True, old=False): def to_currency(self, val, longval=True, old=False):
hightxt = "euro" hightxt = "Euro"
lowtxt = "cent" lowtxt = "Cent"
if old: if old:
hightxt = "mark" hightxt = "Mark"
lowtxt = "pfennig/e" lowtxt = "Pfennig/e"
return self.to_splitnum(val, hightxt=hightxt, lowtxt=lowtxt, cents = int(round(val*100))
jointxt="und", longval=longval) 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): def to_year(self, val, longval=True):
if not (val // 100) % 10: if not (val // 100) % 10:

View File

@@ -52,6 +52,7 @@ class Num2WordsDETest(TestCase):
) )
def test_cardinal_at_some_numbers(self): 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(2000000, lang='de'), "zwei millionen")
self.assertEqual(num2words(4000000000, lang='de'), "vier milliarden") self.assertEqual(num2words(4000000000, lang='de'), "vier milliarden")
self.assertEqual(num2words(1000000000, lang='de'), "eine milliarde") self.assertEqual(num2words(1000000000, lang='de'), "eine milliarde")
@@ -65,7 +66,7 @@ class Num2WordsDETest(TestCase):
self.assertEqual( self.assertEqual(
num2words(4500072900000111, lang='de'), num2words(4500072900000111, lang='de'),
"vier billiarden fünfhundert billionen " + "vier billiarden fünfhundert billionen " +
"zweiundsiebzig milliarden neunhundert millionen hundertelf" "zweiundsiebzig milliarden neunhundert millionen einhundertelf"
) )
def test_ordinal_num(self): def test_ordinal_num(self):
@@ -79,12 +80,28 @@ class Num2WordsDETest(TestCase):
self.assertRaises(TypeError, num2words, 2.453, ordinal=True, lang='de') self.assertRaises(TypeError, num2words, 2.453, ordinal=True, lang='de')
def test_currency(self): def test_currency(self):
self.assertEqual(num2words(12.00, to='currency', lang='de'), self.assertEqual(num2words(1, lang='de', to='currency'),
'zwölf euro') '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): def test_old_currency(self):
self.assertEqual(num2words(12.00, to='currency', lang='de', old=True), self.assertEqual(num2words(12.00, to='currency', lang='de', old=True),
'zwölf mark') 'zwölf Mark')
def test_year(self): def test_year(self):
self.assertEqual(num2words(2002, to='year', lang='de'), self.assertEqual(num2words(2002, to='year', lang='de'),