From 3bcc02e8e29dd11f5ad37563d05e7822acc7fea6 Mon Sep 17 00:00:00 2001 From: Apricot-S Date: Fri, 6 Feb 2026 00:14:15 +0900 Subject: [PATCH 1/9] chore: Ignore lint assert (S101) --- pyproject.toml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 31909a8..4097c33 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,13 +78,9 @@ ignore = [ "PLR0913", # too-many-arguments "PLR0915", # too-many-statements "PLR2004", # magic-value-comparison - - "FBT001", # boolean-type-hint-positional-argument - "FBT002", # boolean-default-value-positional-argument - "FBT003", # boolean-positional-value-in-call - - # Will be fixed later - "S101", + "FBT001", # boolean-type-hint-positional-argument + "FBT002", # boolean-default-value-positional-argument + "FBT003", # boolean-positional-value-in-call ] [tool.ruff.lint.pycodestyle] From e32b622ba445c675c4c86a49e58704ffea61e1c2 Mon Sep 17 00:00:00 2001 From: Apricot-S Date: Fri, 6 Feb 2026 00:26:21 +0900 Subject: [PATCH 2/9] refactor --- mahjong/tile.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/mahjong/tile.py b/mahjong/tile.py index 88b4764..b4dd531 100644 --- a/mahjong/tile.py +++ b/mahjong/tile.py @@ -85,13 +85,12 @@ def _split_string(string: str | None, offset: int, red: int | None = None) -> li return [] for i in string: - if (i in {"r", "0"}) and has_aka_dora: - assert red is not None + if red is not None and i in {"r", "0"}: temp.append(red) data.append(red) else: tile = offset + (int(i) - 1) * 4 - if tile == red and has_aka_dora: + if red is not None and tile == red: # prevent non reds to become red tile += 1 if tile in data: @@ -106,9 +105,9 @@ def _split_string(string: str | None, offset: int, red: int | None = None) -> li return data - results = _split_string(man, 0, FIVE_RED_MAN) - results += _split_string(pin, 36, FIVE_RED_PIN) - results += _split_string(sou, 72, FIVE_RED_SOU) + results = _split_string(man, 0, FIVE_RED_MAN if has_aka_dora else None) + results += _split_string(pin, 36, FIVE_RED_PIN if has_aka_dora else None) + results += _split_string(sou, 72, FIVE_RED_SOU if has_aka_dora else None) results += _split_string(honors, 108) return results From 263a94637f8d2878ec225509ce8bbd6b41f3c152 Mon Sep 17 00:00:00 2001 From: Apricot-S Date: Fri, 6 Feb 2026 00:29:35 +0900 Subject: [PATCH 3/9] refactor: Replace internal functions with private methods --- mahjong/tile.py | 67 ++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/mahjong/tile.py b/mahjong/tile.py index b4dd531..7ee66b1 100644 --- a/mahjong/tile.py +++ b/mahjong/tile.py @@ -61,6 +61,35 @@ def to_136_array(tiles: Sequence[int]) -> list[int]: results.extend(base_id + i for i in range(count)) return results + @staticmethod + def _split_string(string: str | None, offset: int, red: int | None = None) -> list[int]: + if not string: + return [] + + data = [] + temp = [] + + for i in string: + if red is not None and i in {"r", "0"}: + temp.append(red) + data.append(red) + else: + tile = offset + (int(i) - 1) * 4 + if red is not None and tile == red: + # prevent non reds to become red + tile += 1 + if tile in data: + count_of_tiles = len([x for x in temp if x == tile]) + new_tile = tile + count_of_tiles + data.append(new_tile) + + temp.append(tile) + else: + data.append(tile) + temp.append(tile) + + return data + @staticmethod def string_to_136_array( sou: str | None = None, @@ -76,40 +105,10 @@ def string_to_136_array( has_aka_dora has to be True for this to do that. We need it to increase readability of our tests """ - - def _split_string(string: str | None, offset: int, red: int | None = None) -> list[int]: - data = [] - temp = [] - - if not string: - return [] - - for i in string: - if red is not None and i in {"r", "0"}: - temp.append(red) - data.append(red) - else: - tile = offset + (int(i) - 1) * 4 - if red is not None and tile == red: - # prevent non reds to become red - tile += 1 - if tile in data: - count_of_tiles = len([x for x in temp if x == tile]) - new_tile = tile + count_of_tiles - data.append(new_tile) - - temp.append(tile) - else: - data.append(tile) - temp.append(tile) - - return data - - results = _split_string(man, 0, FIVE_RED_MAN if has_aka_dora else None) - results += _split_string(pin, 36, FIVE_RED_PIN if has_aka_dora else None) - results += _split_string(sou, 72, FIVE_RED_SOU if has_aka_dora else None) - results += _split_string(honors, 108) - + results = TilesConverter._split_string(man, 0, FIVE_RED_MAN if has_aka_dora else None) + results += TilesConverter._split_string(pin, 36, FIVE_RED_PIN if has_aka_dora else None) + results += TilesConverter._split_string(sou, 72, FIVE_RED_SOU if has_aka_dora else None) + results += TilesConverter._split_string(honors, 108) return results @staticmethod From a7d26a9ee732e526bcd78e9a039c02bdbe455299 Mon Sep 17 00:00:00 2001 From: Apricot-S Date: Fri, 6 Feb 2026 00:51:22 +0900 Subject: [PATCH 4/9] refactor --- mahjong/tile.py | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/mahjong/tile.py b/mahjong/tile.py index 7ee66b1..aa8a49f 100644 --- a/mahjong/tile.py +++ b/mahjong/tile.py @@ -66,27 +66,35 @@ def _split_string(string: str | None, offset: int, red: int | None = None) -> li if not string: return [] - data = [] - temp = [] - - for i in string: - if red is not None and i in {"r", "0"}: - temp.append(red) + data: list[int] = [] + seen: set[int] = set() + counts: dict[int, int] = {} + + is_explicit_aka = {"r", "0"} + for ch in string: + # explicit aka markers + if red is not None and ch in is_explicit_aka: data.append(red) + seen.add(red) + # explicit aka does not increment the regular tile count + continue + + tile = offset + (int(ch) - 1) * 4 + + # numeric '5' should not map to aka id when aka support is present + if red is not None and tile == red: + tile += 1 + + if tile in seen: + count_of_tiles = counts.get(tile, 0) + new_tile = tile + count_of_tiles + data.append(new_tile) + seen.add(new_tile) + counts[tile] = count_of_tiles + 1 else: - tile = offset + (int(i) - 1) * 4 - if red is not None and tile == red: - # prevent non reds to become red - tile += 1 - if tile in data: - count_of_tiles = len([x for x in temp if x == tile]) - new_tile = tile + count_of_tiles - data.append(new_tile) - - temp.append(tile) - else: - data.append(tile) - temp.append(tile) + data.append(tile) + seen.add(tile) + counts[tile] = counts.get(tile, 0) + 1 return data From 9b475cdc7c8b8f2e6e681778d78890f414543a4b Mon Sep 17 00:00:00 2001 From: Apricot-S Date: Fri, 6 Feb 2026 01:48:24 +0900 Subject: [PATCH 5/9] refactor: rename variables --- mahjong/tile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mahjong/tile.py b/mahjong/tile.py index aa8a49f..5496b5d 100644 --- a/mahjong/tile.py +++ b/mahjong/tile.py @@ -70,10 +70,10 @@ def _split_string(string: str | None, offset: int, red: int | None = None) -> li seen: set[int] = set() counts: dict[int, int] = {} - is_explicit_aka = {"r", "0"} + explicit_aka = {"r", "0"} for ch in string: # explicit aka markers - if red is not None and ch in is_explicit_aka: + if red is not None and ch in explicit_aka: data.append(red) seen.add(red) # explicit aka does not increment the regular tile count From 56fa80175f741b8c906d3042499bb1d86ca0ce7c Mon Sep 17 00:00:00 2001 From: Apricot-S Date: Fri, 6 Feb 2026 09:06:57 +0900 Subject: [PATCH 6/9] refactor: Use Counter --- mahjong/tile.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mahjong/tile.py b/mahjong/tile.py index 5496b5d..8ca01a0 100644 --- a/mahjong/tile.py +++ b/mahjong/tile.py @@ -1,3 +1,4 @@ +from collections import Counter from collections.abc import Collection, Sequence from typing import Any @@ -68,7 +69,7 @@ def _split_string(string: str | None, offset: int, red: int | None = None) -> li data: list[int] = [] seen: set[int] = set() - counts: dict[int, int] = {} + counts: Counter[int] = Counter() explicit_aka = {"r", "0"} for ch in string: @@ -86,7 +87,7 @@ def _split_string(string: str | None, offset: int, red: int | None = None) -> li tile += 1 if tile in seen: - count_of_tiles = counts.get(tile, 0) + count_of_tiles = counts[tile] new_tile = tile + count_of_tiles data.append(new_tile) seen.add(new_tile) @@ -94,7 +95,7 @@ def _split_string(string: str | None, offset: int, red: int | None = None) -> li else: data.append(tile) seen.add(tile) - counts[tile] = counts.get(tile, 0) + 1 + counts[tile] = counts[tile] + 1 return data From 959ed75bc2796b811efe5f658995d7f10dabf9da Mon Sep 17 00:00:00 2001 From: Apricot-S Date: Fri, 6 Feb 2026 09:11:17 +0900 Subject: [PATCH 7/9] refactor --- mahjong/tile.py | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/mahjong/tile.py b/mahjong/tile.py index 8ca01a0..491a91c 100644 --- a/mahjong/tile.py +++ b/mahjong/tile.py @@ -67,7 +67,7 @@ def _split_string(string: str | None, offset: int, red: int | None = None) -> li if not string: return [] - data: list[int] = [] + result: list[int] = [] seen: set[int] = set() counts: Counter[int] = Counter() @@ -75,29 +75,25 @@ def _split_string(string: str | None, offset: int, red: int | None = None) -> li for ch in string: # explicit aka markers if red is not None and ch in explicit_aka: - data.append(red) - seen.add(red) - # explicit aka does not increment the regular tile count - continue - - tile = offset + (int(ch) - 1) * 4 - - # numeric '5' should not map to aka id when aka support is present - if red is not None and tile == red: - tile += 1 + tile = red + else: + tile = offset + (int(ch) - 1) * 4 + # numeric '5' should not map to aka id when aka support is present + if red is not None and tile == red: + tile += 1 if tile in seen: count_of_tiles = counts[tile] new_tile = tile + count_of_tiles - data.append(new_tile) + result.append(new_tile) seen.add(new_tile) counts[tile] = count_of_tiles + 1 else: - data.append(tile) + result.append(tile) seen.add(tile) counts[tile] = counts[tile] + 1 - return data + return result @staticmethod def string_to_136_array( From cd5ab79a7a390ab2a4ee0a6e828138bb48375c48 Mon Sep 17 00:00:00 2001 From: Apricot-S Date: Fri, 6 Feb 2026 09:34:23 +0900 Subject: [PATCH 8/9] refactor --- mahjong/tile.py | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/mahjong/tile.py b/mahjong/tile.py index 491a91c..2437efe 100644 --- a/mahjong/tile.py +++ b/mahjong/tile.py @@ -67,31 +67,24 @@ def _split_string(string: str | None, offset: int, red: int | None = None) -> li if not string: return [] - result: list[int] = [] - seen: set[int] = set() counts: Counter[int] = Counter() + result: list[int] = [] explicit_aka = {"r", "0"} for ch in string: # explicit aka markers if red is not None and ch in explicit_aka: - tile = red - else: - tile = offset + (int(ch) - 1) * 4 - # numeric '5' should not map to aka id when aka support is present - if red is not None and tile == red: - tile += 1 - - if tile in seen: - count_of_tiles = counts[tile] - new_tile = tile + count_of_tiles - result.append(new_tile) - seen.add(new_tile) - counts[tile] = count_of_tiles + 1 - else: - result.append(tile) - seen.add(tile) - counts[tile] = counts[tile] + 1 + result.append(red) + continue + + tile = offset + (int(ch) - 1) * 4 + # numeric '5' should not map to aka id when aka support is present + if red is not None and tile == red: + tile += 1 + + count_of_tiles = counts[tile] + result.append(tile + count_of_tiles) + counts[tile] += 1 return result From 9d8eb8b3383818a814f763868309a1e72211bb7a Mon Sep 17 00:00:00 2001 From: Apricot-S Date: Fri, 6 Feb 2026 09:37:44 +0900 Subject: [PATCH 9/9] refactor --- mahjong/tile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mahjong/tile.py b/mahjong/tile.py index 2437efe..a9898d5 100644 --- a/mahjong/tile.py +++ b/mahjong/tile.py @@ -73,7 +73,7 @@ def _split_string(string: str | None, offset: int, red: int | None = None) -> li explicit_aka = {"r", "0"} for ch in string: # explicit aka markers - if red is not None and ch in explicit_aka: + if ch in explicit_aka and red is not None: result.append(red) continue