savoirfairelinux / num2words

Modules to convert numbers to words. 42 --> forty-two
GNU Lesser General Public License v2.1
820 stars 497 forks source link

Multiple incorrect and failure about Korean ordinal conversion #555

Open dogzz9445 opened 9 months ago

dogzz9445 commented 9 months ago

There are several issues with the Korean ordinal conversion in the to_ordinal function.

  1. The function throws an error when the input is 100 or 1000.
  2. The function always appends '번째' to the ordinal, which may not always be desired. For example, when converting 100, the output should be '백', not '백 번째'.
  3. The function does not consider different ways of expressing 1 in Korean. In Korean, 1 can be expressed as '첫 번째' or '한번' in ordinal form.

Expected Behaviour

num2words.num2words(100, ordinal=True, lang='ko')
'백 번째'
num2words.num2words(100, ordinal=True, lang='ko')
'십만 번째'

There are errors on 100, 1000

Actual Behaviour

num2words.num2words(100, ordinal=True, lang='ko')
===========================================================
ERROR: test_ordinal (tests.test_ko.Num2WordsKOTest.test_ordinal)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "d:\git\num2words\tests\test_ko.py", line 89, in test_ordinal
    self.assertEqual(n2k(num, to="ordinal"), out)
                     ^^^^^^^^^^^^^^^^^^^^^^
  File "d:\git\num2words\tests\test_ko.py", line 26, in n2k
    return num2words(*args, lang='ko', **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "d:\git\num2words\num2words\__init__.py", line 104, in num2words
    return getattr(converter, 'to_{}'.format(to))(number, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "d:\git\num2words\num2words\lang_KO.py", line 110, in to_ordinal
    lastwords[-1] = self.ords[lastwords[-1]]
                    ~~~~~~~~~^^^^^^^^^^^^^^^
KeyError: ''
num2words.num2words(100000, ordinal=True, lang='ko')
'열만 번째'

Steps to reproduce

  1. Run the to_ordinal function with 100 or 1000 as input without error.
  2. Observe the error.
  3. Observe the incorrect ordinal conversion.

Suggested Test Code Snippet

  1. Without Error ASAP

    def test_ordinal(self):
    cases = [(1, "첫 번째"), (101, "백 한 번째"), (2, "두 번째"), (5, "다섯 번째"),
             (10, "열 번째"), (25, "스물다섯 번째"), (100, "백 번째"), 
             (1000, "천 번째"), (10000, "만 번째"), (100000, "십만 번째"),
             (137, "백 서른일곱 번째")]
    for num, out in cases:
        self.assertEqual(n2k(num, to="ordinal"), out)
  2. Suggest Appropriate Case If Possible In the case below, it is left to the developer's authority to attach '번, 번째, 째, 차'.

    def test_ordinal(self):
    cases = [(1, "한"), (101, "백 한"), (2, "둘"), (5, "다섯"),
             (10, "열"), (25, "스물다섯"), (100, "백"), 
             (1000, "천"), (10000, "만"), (100000, "십만"),
             (137, "백 서른일곱")]
    for num, out in cases:
        self.assertEqual(n2k(num, to="ordinal"), out)