sindhinorm
Spelling normalization for Sindhi text typed on mixed keyboards. No dependencies, Python ≥ 3.10.
Sindhi text often mixes look-alike Unicode letters from Urdu, Persian and Arabic keyboards: Farsi yeh ی or alef maksura ى for Sindhi ي, Urdu heh-goal ہ or do-chashmi ھ for ه, keheh ک or Arabic kaf ك for ڪ, plus stray zero-width characters. They look the same but are different characters to software, so search, counting and NLP models treat one word as several.
A fixed character map does not work for Sindhi, because ک and ڪ are both real Sindhi letters: کي ("to") and ڪي ("some") are different words. sindhinorm decides per word, using how often each spelling occurs in Sindhi Wikipedia, and never merges a pair that a native Sindhi speaker judged to be different words.
pip install sindhinorm
from sindhinorm import normalize, explain
normalize("هي ڪتاب آهی") # 'هي ڪتاب آهي' (Farsi yeh fixed)
normalize("ڪي کي") # 'ڪي کي' (two different words: left alone)
explain("ھن آهی کري")
# [{'word': 'ھن', 'output': 'هن', 'rule': 'encoding-merge', 'count_in': 12528, 'count_out': 22047},
# {'word': 'آهی', 'output': 'آهي', 'rule': 'encoding-merge', 'count_in': 0, 'count_out': 62425},
# {'word': 'کري', 'output': 'کري', 'rule': 'native-keep', 'count_in': 14, 'count_out': 14}]
Command line:
sindhinorm < input.txt > output.txt
sindhinorm input.txt -o output.txt
sindhinorm explain "ھن آهی کري"
sindhinorm build-lexicon my_corpus.txt -o my_lexicon.json.gz # your own word counts
sindhinorm -l my_lexicon.json.gz < input.txt > output.txt
Rules
- Unicode NFC. Zero-width non-joiners and joiners are removed unless a ZWNJ sits between two letters (native review found those mark compound and ال-name joins).
- Candidate spellings: every combination of look-alike letters at the word's yeh {ي ی ى ے}, heh {ه ھ ہ} and kaf {ڪ ک ك} positions. The most frequent candidate wins if the rule allows the merge.
- Encoding-only differences (ي/ی/ى, ه/ھ/ہ) are merged whenever the candidate is more frequent.
- Lexical differences (any position involving ک, ڪ, ك or ے) are merged only if the rare form occurs ≤ 100 times and the candidate is ≥ 50× more frequent.
- 24 pairs judged different or unsure by a native reviewer are never merged.
- Words not in the lexicon only get the safest folds (ی ى → ي, ہ → ه).
explain reports which rule decided each word: encoding-merge, lexical-merge,
native-keep, lexical-guard (a more frequent variant exists but may be another word),
already-canonical, no-variant-letters, unknown-fold or unknown-kept.
How well it works
Measured with the bundled lexicon (details and scripts: MorphoTok-SD-UR, docs/sdnorm.md):
| Test | Result |
|---|---|
| Text with ي replaced by ی (UD Sindhi test set, news) | 94.0% of 4,511 altered words restored |
| Random-letter edits, same words (control) | 0.4% "restored": it does not undo arbitrary typos |
| Clean words changed | 1.35% |
Limits.
- Frequency cannot always tell a rare real word from a misspelling. The native keep-list covers the 24 reviewed cases. On the 150 reviewed pairs, the frequency rule alone merged with precision 0.87.
- The canonical spelling follows the Wikipedia majority, not a published standard. For example ھن → هن; some writers prefer ھ.
- One native reviewer. Sindhi only (no Urdu mode).
Licences
- Code: MIT (
LICENSE). - Bundled word list: CC BY-SA 4.0 (
LICENSE-DATA). It is derived from Sindhi Wikipedia (2023-11-01): 61,718 words seen at least twice, with counts.
Metadata
Release files for sindhinorm 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| sindhinorm-0.1.0.tar.gz | 286.1 kB | Without provenance | Details for sindhinorm-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| sindhinorm-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for sindhinorm-0.1.0-py3-none-any.whl |
Total release size: 570.3 kB
Release files / sindhinorm-0.1.0.tar.gz
| Download URL | sindhinorm-0.1.0.tar.gz |
|---|---|
| Size | 286.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c2ace8da6b375304a88523902590e787eb836d21dfa909afd3777a0d97b64e3b
|
|
BLAKE2b-256 checksum How to use checksums |
18ea4d04c17aebdd490ed931a5216eee8dc9d501f74e12674a7dc69bc775d0f9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|
Release files / sindhinorm-0.1.0-py3-none-any.whl
| Download URL | sindhinorm-0.1.0-py3-none-any.whl |
|---|---|
| Size | 284.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
48574606cb47ad05638da30a56f9316c30a6aa2e020986c053c4c40b6cb18599
|
|
BLAKE2b-256 checksum How to use checksums |
c6c0431a76f9fdd4eac033d7f96f77f277a5d02706991e1c9ecbb45cbbd48991
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|
Security for sindhinorm 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.