Repository: ShailChoksi/text2digits

Issue:
Problems to convert date in format like "January sixth twenty twenty"
from text2digits import text2digits
t2d = text2digits.Text2Digits()
print(t2d.convert("january six twenty nineteen"))
print(t2d.convert("january 6 2019"))
print(t2d.convert("january six twenty twenty"))
print(t2d.convert("january 6 2020"))
print(t2d.convert("january six twenty twenty one"))
print(t2d.convert("january six in twenty twenty one"))
print(t2d.convert("january 6 2021"))

Output:
january 62019
january 6 2019
january 62020
january 12120 (!! pay attention to number)
january 62021
january 6 in 2021
january 6 2021

Comments:

Patch:
diff --git a/setup.py b/setup.py
index 7c315ef..f61f06c 100644
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
 
 setuptools.setup(
     name="text2digits",
-    version="0.0.9",
+    version="0.1.0",
     author="Shail Choksi",
     author_email="choksishail@gmail.com",
     description="A small library to convert text numbers to digits in a string",
diff --git a/text2digits/rules.py b/text2digits/rules.py
index b892c4b..bc7a96e 100644
--- a/text2digits/rules.py
+++ b/text2digits/rules.py
@@ -119,15 +119,16 @@ class CombinationRule(Rule):
         result = Decimal(0)
         last_glue = ''
         prev_scale = 1
+        all_scales = [token.scale() for token in tokens]
 
-        for token in tokens:
+        for index, token in enumerate(tokens):
             assert token.type != WordType.OTHER, 'Invalid token type (only numbers are allowed here)'
 
             if token.has_large_scale():
                 # Multiply the scale at least with a value of 1 (and not 0)
                 current = max(1, current)
 
-            if token.scale() < prev_scale:
+            if token.scale() < prev_scale and prev_scale > max(all_scales[index:]):
                 # Flush the result when switching from a larger to a smaller scale
                 # e.g. one thousand *FLUSH* six hundred *FLUSH* sixty six
                 result += current
@@ -141,7 +142,6 @@ class CombinationRule(Rule):
 
         return CombinedToken(tokens, result, last_glue)
 
-
 class ConcatenationRule(Rule):
     """
     This rule handles all the "year cases" like twenty twenty where we simply concatenate the numbers together. The numbers are already transformed to digits by the CombinationRule.
@@ -154,7 +154,8 @@ class ConcatenationRule(Rule):
 
         # Find all numeric tokens
         while i < len(tokens):
-            if tokens[i].type in self.valid_types:
+            if tokens[i].type in self.valid_types and not tokens[i].is_ordinal():
+                # Avoid ordinals. Example: 'look at the second one' should convert into '2nd 1' not '21'
                 i += 1
             else:
                 break
diff --git a/text2digits/tokens_basic.py b/text2digits/tokens_basic.py
index 1a8e006..b6238e6 100644
--- a/text2digits/tokens_basic.py
+++ b/text2digits/tokens_basic.py
@@ -22,6 +22,7 @@ class Token(object):
              'nineteen']
     TENS = ['twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety']
     SCALES = ['hundred', 'thousand', 'million', 'billion', 'trillion']
+    SCALE_VALUES = [100, 1000, 1000000, 1000000000, 1000000000000] # used for has_large_scale
     CONJUNCTION = ['and']
     ORDINAL_WORDS = {'oh': 'zero', 'first': 'one', 'second': 'two', 'third': 'three', 'fifth': 'five',
                      'eighth': 'eight', 'ninth': 'nine', 'twelfth': 'twelve'}
@@ -96,7 +97,8 @@ class Token(object):
         if self.type == WordType.SCALES:
             return True
         elif self.type in [WordType.LITERAL_INT, WordType.LITERAL_FLOAT]:
-            return Decimal(self._word) >= 100 and Decimal(self._word) % 10 == 0
+            # whether the value is a scale (e.g. 100, 1000, 1000000, etc.)
+            return Decimal(self._word) in self.SCALE_VALUES
         else:
             return False
 


Test patch:
diff --git a/tests/test_number_conversion.py b/tests/test_number_conversion.py
index 4679158..a483bcd 100644
--- a/tests/test_number_conversion.py
+++ b/tests/test_number_conversion.py
@@ -29,6 +29,8 @@ def test_str_unchanged_if_no_numbers(input_text):
     ("I am the fourth cousin", "I am the 4 cousin"),
     ("forty-two", "42"),
     ("forty_two", "42"),
+    ("six hundred seventy five thousand word book", "675000 word book"),
+    ("one million two hundred twenty nine thousand three hundred and eighty six", "1229386"),
 ])
 def test_positive_integers(input_text, expected):
     t2d_default = text2digits.Text2Digits()
@@ -114,6 +116,7 @@ def test_spelling_correction(input_text, expected):
     ("1.2345 hundred", "123.45"),
     ("twenty 1.0", "20 1.0"),
     ("100 and two", "102"),
+    ('6 2020', '6 2020'),
 ])
 def test_number_literals(input_text, expected):
     t2d_default = text2digits.Text2Digits()