Skip to content
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
21 changes: 19 additions & 2 deletions normalization/languages/swedish/number_normalizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ def _parse_0_999(self, words: list[str], i: int, n: int) -> tuple[int, int] | No
return i + 1, 0

if _fold(words[i]) == "hundra":
tail = self._parse_0_99(words, i + 1, n)
tail = self._parse_0_99_after_hundred(words, i + 1, n)
if tail is not None:
je, tv = tail
return je, 100 + tv
Expand All @@ -334,14 +334,31 @@ def _parse_0_999(self, words: list[str], i: int, n: int) -> tuple[int, int] | No
return None
base = m * 100
j = i + 2
tail = self._parse_0_99(words, j, n)
tail = self._parse_0_99_after_hundred(words, j, n)
if tail is not None:
je, tv = tail
return je, base + tv
return j, base

return self._parse_0_99(words, i, n)

def _parse_0_99_after_hundred(
self, words: list[str], i: int, n: int
) -> tuple[int, int] | None:
"""Parse 0–99, additionally accepting standalone ``en``/``ett`` as 1.

A bare ``en``/``ett`` is ambiguous with the article elsewhere, so
``_parse_0_99`` leaves it as a word. After a hundreds block it can only
be the unit 1 (``hundra ett`` = 101, ``hundra ett tusen`` = 101000), so
it is safe to read here.
"""
result = self._parse_0_99(words, i, n)
if result is not None:
return result
if i < n and _fold(words[i]) in ("en", "ett"):
return i + 1, 1
return None

def _continues_number(self, word: str) -> bool:
fw = _fold(word)
if fw == "hundra" or fw == "tusen":
Expand Down
18 changes: 18 additions & 0 deletions tests/unit/languages/swedish_number_normalizer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,21 @@ def test_kronor_word_not_treated_as_currency_suffix(
normalizer: SwedishNumberNormalizer,
) -> None:
assert normalizer("25 kronor") == "25 kronor"


@pytest.mark.parametrize(
("text", "expected"),
[
("hundra ett", "101"),
("två hundra en", "201"),
("hundra ett tusen", "101000"),
("två hundra ett tusen", "201000"),
("tre hundra ett tusen fem", "301005"),
],
)
def test_unit_one_after_hundred_keeps_grouping(
normalizer: SwedishNumberNormalizer, text: str, expected: str
) -> None:
"""``en``/``ett`` as the ones part after a hundreds block is the unit 1, so
the thousands multiplier is not dropped (``hundra ett tusen`` = 101000)."""
assert normalizer(text) == expected