codedx 0.2.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ ## 0.3.0 — 2026-06-08
4
+
5
+ ### Added
6
+
7
+ - `chapter_to_roman(chapter)` — convert chapter number (int, `"1"`, or `"01"`) to Roman numeral (`"I"`–`"XXII"`)
8
+ - `roman_to_chapter(roman)` — convert Roman numeral chapter to int 1–22; case-insensitive
9
+ - `get_range(chapter_code)` — extract code range string from a chapter title (e.g. `"01"` → `"A00-B99"`)
10
+ - All three exported from `codedx` top-level
11
+
12
+ ## 0.2.0
13
+
14
+ - Migrate ICD-10-SE downloads to Ehälsomyndigheten
15
+
16
+ ## 0.1.0
17
+
18
+ - Initial release: ICD-10-SE, WHO ICD-10, ICD-10-CM, KSH97-P, rehab code lookups
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codedx
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Swedish medical coding used for diagnosis codes
5
5
  Author-email: Ludvig Hult <ludvig.hult@gmail.com>
6
6
  Requires-Python: >=3.12
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "codedx"
3
- version = "0.2.0"
3
+ version = "0.3.0"
4
4
  description = "Swedish medical coding used for diagnosis codes"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -1,6 +1,6 @@
1
1
  import pathlib
2
2
 
3
- __version__ = "0.2.0"
3
+ __version__ = "0.3.0"
4
4
  _CACHE_DIR = pathlib.Path.home() / ".cache" / "codedx" / f"v{__version__}"
5
5
 
6
6
  from codedx._core import ( # noqa: E402
@@ -14,6 +14,7 @@ from codedx._core import ( # noqa: E402
14
14
  is_rehab_code,
15
15
  is_retired_icd10se_code,
16
16
  )
17
+ from codedx.chapters import chapter_to_roman, roman_to_chapter, get_range # noqa: E402
17
18
 
18
19
  __all__ = [
19
20
  "get_name",
@@ -25,4 +26,7 @@ __all__ = [
25
26
  "is_ksh97p_code",
26
27
  "is_rehab_code",
27
28
  "is_retired_icd10se_code",
29
+ "chapter_to_roman",
30
+ "roman_to_chapter",
31
+ "get_range",
28
32
  ]
@@ -0,0 +1,55 @@
1
+ """Chapter and block numeral/range utilities for ICD-10."""
2
+
3
+ import re
4
+
5
+ _INT_TO_ROMAN: dict[int, str] = {
6
+ 1: "I", 2: "II", 3: "III", 4: "IV", 5: "V", 6: "VI", 7: "VII",
7
+ 8: "VIII", 9: "IX", 10: "X", 11: "XI", 12: "XII", 13: "XIII",
8
+ 14: "XIV", 15: "XV", 16: "XVI", 17: "XVII", 18: "XVIII",
9
+ 19: "XIX", 20: "XX", 21: "XXI", 22: "XXII",
10
+ }
11
+
12
+ _ROMAN_TO_INT: dict[str, int] = {v: k for k, v in _INT_TO_ROMAN.items()}
13
+
14
+ _RANGE_RE = re.compile(r'\(([A-Z]\d{2}(?:\.\d)?-[A-Z]\d{2}(?:\.\d)?)\)')
15
+
16
+
17
+ def chapter_to_roman(chapter: int | str) -> str:
18
+ """Convert chapter number to Roman numeral. Accepts 1, '1', or '01'."""
19
+ n = int(chapter)
20
+ try:
21
+ return _INT_TO_ROMAN[n]
22
+ except KeyError:
23
+ raise ValueError(f"Chapter number {n!r} out of range 1–22") from None
24
+
25
+
26
+ def roman_to_chapter(roman: str) -> int:
27
+ """Convert Roman numeral chapter (e.g. 'XVIII') to integer 1–22. Case-insensitive."""
28
+ try:
29
+ return _ROMAN_TO_INT[roman.upper()]
30
+ except KeyError:
31
+ raise ValueError(f"Unknown Roman numeral {roman!r}") from None
32
+
33
+
34
+ def get_range(code: str) -> str:
35
+ """Return the code range string for a chapter.
36
+
37
+ Chapter '01' → 'A00-B99' (extracted from title)
38
+ """
39
+ import polars as pl
40
+ from codedx._core import icd10se_table
41
+
42
+ try:
43
+ row = icd10se_table.row(by_predicate=pl.col("Code") == code, named=True)
44
+ except Exception:
45
+ raise ValueError(f"Code {code!r} not found in ICD-10-SE") from None
46
+
47
+ if row["Level"] != "Chapter":
48
+ raise ValueError(f"Code {code!r} is level {row['Level']!r}, not Chapter")
49
+ m = _RANGE_RE.search(row["Titel"])
50
+ if m:
51
+ return m.group(1)
52
+ raise ValueError(f"No range found in chapter title: {row['Titel']!r}")
53
+
54
+
55
+ __all__ = ["chapter_to_roman", "roman_to_chapter", "get_range"]
@@ -5,13 +5,7 @@ import pathlib
5
5
  import polars as pl
6
6
 
7
7
  from codedx import _CACHE_DIR
8
-
9
- _ROMAN = {
10
- "I": 1, "II": 2, "III": 3, "IV": 4, "V": 5, "VI": 6, "VII": 7,
11
- "VIII": 8, "IX": 9, "X": 10, "XI": 11, "XII": 12, "XIII": 13,
12
- "XIV": 14, "XV": 15, "XVI": 16, "XVII": 17, "XVIII": 18,
13
- "XIX": 19, "XX": 20, "XXI": 21, "XXII": 22,
14
- }
8
+ from codedx.chapters import _ROMAN_TO_INT as _ROMAN
15
9
 
16
10
 
17
11
  def _build(work_dir: pathlib.Path) -> pl.DataFrame:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes