Skip to content

Instantly share code, notes, and snippets.

@greed2411
Created July 7, 2021 10:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save greed2411/0226a9d58b7865cbe91d8c1a3fbc2f76 to your computer and use it in GitHub Desktop.
Save greed2411/0226a9d58b7865cbe91d8c1a3fbc2f76 to your computer and use it in GitHub Desktop.
Split, Iterate & Sort on Tamil Strings using Python3
க்
ங்
ச்
ஞ்
ட்
ண்
த்
ந்
ப்
ம்
ய்
ர்
ல்
வ்
ழ்
ள்
ற்
ன்
ஶ்
ஜ்
ஷ்
ஸ்
ஹ்
க்ஷ்
கா
கி
கீ
கு
கூ
கெ
கே
கை
கொ
கோ
கௌ
ஙா
ஙி
ஙீ
ஙு
ஙூ
ஙெ
ஙே
ஙை
ஙொ
ஙோ
ஙௌ
சா
சி
சீ
சு
சூ
செ
சே
சை
சொ
சோ
சௌ
ஞா
ஞி
ஞீ
ஞு
ஞூ
ஞெ
ஞே
ஞை
ஞொ
ஞோ
ஞௌ
டா
டி
டீ
டு
டூ
டெ
டே
டை
டொ
டோ
டௌ
ணா
ணி
ணீ
ணு
ணூ
ணெ
ணே
ணை
ணொ
ணோ
ணௌ
தா
தி
தீ
து
தூ
தெ
தே
தை
தொ
தோ
தௌ
நா
நி
நீ
நு
நூ
நெ
நே
நை
நொ
நோ
நௌ
பா
பி
பீ
பு
பூ
பெ
பே
பை
பொ
போ
பௌ
மா
மி
மீ
மு
மூ
மெ
மே
மை
மொ
மோ
மௌ
யா
யி
யீ
யு
யூ
யெ
யே
யை
யொ
யோ
யௌ
ரா
ரி
ரீ
ரு
ரூ
ரெ
ரே
ரை
ரொ
ரோ
ரௌ
லா
லி
லீ
லு
லூ
லெ
லே
லை
லொ
லோ
லௌ
வா
வி
வீ
வு
வூ
வெ
வே
வை
வொ
வோ
வௌ
ழா
ழி
ழீ
ழு
ழூ
ழெ
ழே
ழை
ழொ
ழோ
ழௌ
ளா
ளி
ளீ
ளு
ளூ
ளெ
ளே
ளை
ளொ
ளோ
ளௌ
றா
றி
றீ
று
றூ
றெ
றே
றை
றொ
றோ
றௌ
னா
னி
னீ
னு
னூ
னெ
னே
னை
னொ
னோ
னௌ
ஶா
ஶி
ஶீ
ஶு
ஶூ
ஶெ
ஶே
ஶை
ஶொ
ஶோ
ஶௌ
ஜா
ஜி
ஜீ
ஜு
ஜூ
ஜெ
ஜே
ஜை
ஜொ
ஜோ
ஜௌ
ஷா
ஷி
ஷீ
ஷு
ஷூ
ஷெ
ஷே
ஷை
ஷொ
ஷோ
ஷௌ
ஸா
ஸி
ஸீ
ஸு
ஸூ
ஸெ
ஸே
ஸை
ஸொ
ஸோ
ஸௌ
ஹா
ஹி
ஹீ
ஹு
ஹூ
ஹெ
ஹே
ஹை
ஹொ
ஹோ
ஹௌ
க்ஷ
க்ஷா
க்ஷி
க்ஷீ
க்ஷு
க்ஷூ
க்ஷெ
க்ஷே
க்ஷை
க்ஷொ
க்ஷோ
க்ஷௌ
ஶ்ரீ
"""
sorting on tamil utf8 strings is a pain.
it's not a natural sort, plus we need to collate the utf8 characters.
when you try to sort "ஈசன்"
expect (str): ஈன்ச
reality (str): ஈசன்
internal python string representaion looks like:
expected (list): ['ஈ', 'ச', 'ன்']
reality (list): ['ஈ', 'ச', 'ன', '்']
more examples:
given : "அகர முதல எழுத்தெல்லாம் ஆதி பகவன் முதற்றே உலகு"
expected: " அஆஉஎகககுதததிதெத்ன்பமுமும்ரறேற்லலலால்ழுவ"
reality : " அஆஉஎகககதததததனபமமமரறறலலலலழவாிுுுுெே்்்்்"
given : "பிள்ளையார்"
expected: "பியார்ளைள்"
reality : "பயரளளாிை்்"
this looks messed up, so i went forward to do something natural about it.
takes a python sting, tries to gets the actual letters using `split_tamil_characters`
and uses it forward for sorting those collated letters using `sort_tamil_characters`
Useful links:
https://nedbatchelder.com/text/unipain.html
https://docs.python.org/3/howto/sorting.html#key-functions
https://github.com/Ezhil-Language-Foundation/open-tamil/blob/main/tamil/utf8.py#L1026
"""
from dataclasses import dataclass
from typing import List
addon_symbols = set(["", "ா", "ி", "ீ", "ு", "ூ", "ெ", "ே", "ை", "ொ", "ோ", "ௌ", "்"])
@dataclass
class TamilCharacter:
letter : str
order : int
def split_tamil_characters(tamil_str: str) -> List[str]:
"""
works on simple logic that:
'ன' + '்' = 'ன்'
given a word, returns split string
according to how tamil is defined, not
the python way.
ex: word = "ஈசன்"
returns: ['ஈ', 'ச', 'ன்']
"""
ta_letters = []
for char in tamil_str:
if char in addon_symbols:
ta_letters[-1] += char
else:
ta_letters.append(char)
return ta_letters
def sort_tamil_characters(tamil_str: str) -> str:
ta_letters = split_tamil_characters(tamil_str)
ta_letters = [TamilCharacter(letter=letter, order=tc_ord_map[letter]) for letter in ta_letters]
sorted_ta_letters_list = sorted(ta_letters, key=lambda ta_ch: ta_ch.order)
sorted_ta_str = "".join(map(lambda ta_ch: ta_ch.letter, sorted_ta_letters_list))
return sorted_ta_str
if __name__ == "__main__":
with open("letters.txt") as fp:
tc = fp.read()
tc = list(filter(None, tc.split("\n")))
tc_ord_map = {letter:i for i, letter in enumerate(tc, start=128)}
# considering ascii values too
# https://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html
tc_ord_map.update({chr(i): i for i in range(32, 126)})
# FROM HERE
eesan = "ஈசன்"
# usage
sorted_eesan = sort_tamil_characters(eesan) # "ஈன்ச"
split_eesan = split_tamil_characters(eesan) # ['ஈ', 'ச', 'ன்']
print(list(eesan), split_eesan)
# ['ஈ', 'ச', 'ன', '்'] ['ஈ', 'ச', 'ன்']
ord_sort_str = lambda x: "".join(sorted(x))
# comparisons of ordinary python utf8 based sort against the tamil natural ut8 based sort
print(ord_sort_str(eesan), sorted_eesan)
# ஈசன் ஈன்ச
# works on sentences too, but prefer to split, sort and stitch it back
mudhal_kural = "அகர முதல எழுத்தெல்லாம் ஆதி பகவன் முதற்றே உலகு"
print(ord_sort_str(mudhal_kural), sort_tamil_characters(mudhal_kural))
# அஆஉஎகககதததததனபமமமரறறலலலலழவாிுுுுெே்்்்் அஆஉஎகககுதததிதெத்ன்பமுமும்ரறேற்லலலால்ழுவ
mythology_characters = [
"பிள்ளையார்",
"முருகன்",
"சிவன்",
"பார்வதி",
"கிருஷ்ணர்",
"கோபாலன்",
"கோவிந்தன்",
"கோகுலன்",
"கர்ணன்",
"கௌரவர்",
"கல்கி",
]
for myth_char in mythology_characters:
print(ord_sort_str(myth_char), sort_tamil_characters(myth_char))
# பயரளளாிை்் ர்ள்பியாளை
# கனமருு் ன்கமுரு
# சனவி் ன்சிவ
# தபரவாி் ர்திபாவ
# கணரரஷிு்் ர்ஷ்கிணரு
# கனபலாோ் ன்கோபால
# கதநனவிோ்் ந்ன்கோதவி
# ககனலுோ் ன்குகோல
# கணனர்் ர்ன்கண
# கரரவௌ் ர்கௌரவ
# ககலி் ல்ககி
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment