{ "cells": [ { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from pathlib import Path\n", "import re, sqlite3\n", "from collections import defaultdict" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# ~4800 commonly used chars from 常用國字標準字體表\n", "common = Path('common.txt').read_text('utf-8').strip()\n", "\n", "# ~6300 less common chars from 次常用國字標準字體表\n", "lessCommon = Path('lessCommon.txt').read_text('utf-8').strip()\n", "\n", "# your custom add-on chars, eg. 粵語用字\n", "addon = Path('add_on_char.txt').read_text('utf-8').splitlines()\n", "\n", "# combine ordered list from above\n", "chars = list(common) + addon + list(lessCommon)\n", "\n", "# rare chars with same input code with others, to be removed from the final character list\n", "duplicated_code = Path('duplicated_code.txt').read_text('utf-8').splitlines()\n", "\n", "# chars from 教育部 - 字頻表排序\n", "char_rank = Path('char_rank.txt').read_text('utf-8').splitlines()\n" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# dict with input code for all chars\n", "with open('char_db.csv') as f:\n", " input_dict = dict(line.strip().split(',') for line in f)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# pioritize charaters with 教育部 - 字頻表排序\n", "for char in char_rank:\n", " if char not in chars:\n", " print(char, 'not exsit')\n", " chars.remove(char)\n", "\n", "ranked_chars = char_rank + chars " ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "# remove rare chars having duplicated input code with others\n", "for char in duplicated_code:\n", " if char in ranked_chars:\n", " ranked_chars.remove(char)\n", " else:\n", " print(char, ' not in ranked_chars')" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "# make sure all chars have input code\n", "if chars_not_found := [char for char in ranked_chars if not input_dict.get(char)]:\n", " raise f\"chars not having input code: {chars_not_found}\"" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "# header of final character list\n", "header = '''%gen_inp\n", "%ename cangjie\n", "%cname 倉頡輸入法\n", "%selkey 1234567890\n", "%keyname begin\n", "a 日\n", "b 月\n", "c 金\n", "d 木\n", "e 水\n", "f 火\n", "g 土\n", "h 竹\n", "i 戈\n", "j 十\n", "k 大\n", "l 中\n", "m 一\n", "n 弓\n", "o 人\n", "p 心\n", "q 手\n", "r 口\n", "s 尸\n", "t 廿\n", "u 山\n", "v 女\n", "w 田\n", "x 難\n", "y 卜\n", "z 重\n", "[ 「\n", "] 」\n", "; ;\n", "' 、\n", "\\ \\n", ", ,\n", ". 。\n", "! !\n", ": :\n", "/ ?\n", "%keyname end\n", "%chardef begin\n", ", ,\n", "! !\n", ": :\n", ". 。\n", "/ ?\n", "// /\n", ".. .\n", "... …\n", "' 、\n", "; ;\n", "\\ \\n", "[ 「\n", "[ 『\n", "[ (\n", "[ 〈\n", "[ 《\n", "] 」\n", "] 』\n", "] )\n", "] 〉\n", "] 》\n", "'''" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "footer = '\\n%chardef end'" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "# create main body of the final character list from `ranked_chars`\n", "body = '\\n'.join(input_dict[char].lower() + ' ' + char for char in ranked_chars)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "# generate final character list\n", "with open('dime_cangjie.txt', mode='w', encoding='utf-8') as f:\n", " f.writelines(header + body +footer)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "11047" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# total number of chars in the final character list\n", "len(ranked_chars)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## show chars with more then one output\n", "\n", "base on the follow results, you may:\n", "\n", "- adjust `duplicated_code.txt` to remove unwanted chars\n", "- adjust `char_rank.txt` to re-order the output when more then one candidates" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "SU 己 已\n", "YOLN 刻 劇\n", "DHE 皮 板\n", "OJ 什 午\n", "OGE 雙 隻\n", "MNP 死 恐\n", "JD 未 宋\n", "WD 果 困\n", "EHSK 激 淚\n", "YRBU 亮 毫\n", "YHMBC 顏 頻\n", "TW 曲 苗\n", "DTMC 橫 棋\n", "OPBUC 貨 貸\n", "GRTR 喜 嘉\n", "EMHF 源 鴻\n", "RRIK 哭 獸\n", "QOMR 拾 捨\n", "SIP 忍 慰\n", "GIKS 勢 劫\n", "MGOK 致 玫\n", "NO 久 欠\n", "A 日 曰\n", "MBUC 貢 頁\n", "KN 九 夷\n", "HND 朵 梨\n", "QHLO 抓 掀\n", "TCNO 歉 欺\n", "EJMC 演 濱\n", "RC 只 叭\n", "PA 旨 旬\n", "HPA 昏 筍\n", "ANAU 晚 冕\n", "HS 戶 乍\n", "MRNO 歌 砍\n", "TWK 奠 茵\n", "NBG 角 墮\n", "OKR 知 佑\n", "DBDB 棘 棗\n", "IPP 態 庇\n", "FBOK 敞 敝\n", "EOMN 汽 渝\n", "NL 引 弔\n", "ABJJ 暈 暉\n", "HOUFK 徽 黴\n", "BT 冊 皿\n", "AYRF 景 晾\n", "YCK 交 奕\n", "HUP 息 憩\n", "HMNL 郵 邸\n", "TMD 某 芋\n", "SRNL 郡 邵\n", "HTMC 簧 箕\n", "SEB 腎 臀\n", "NI 夕 弘\n", "ARF 照 煦\n", "BM 且 肛\n", "HDLN 利 剁\n", "IRP 感 怠\n", "SHOE 履 屐\n", "HI 鬼 么\n", "SHI 刃 戮\n", "THJD 茱 孽\n", "RAU 吧 邑\n", "ENI 汐 泓\n", "VID 樂 槳\n", "ETMC 淇 潢\n", "BHN 肌 冗\n", "FBR 尚 炯\n", "QSMG 握 擢\n", "PI 勾 勺\n", "OLOK 攸 倏\n", "DYTJ 樟 梓\n", "YVVV 巡 邋\n", "IT 戒 弁\n", "YRU 訕 乩\n", "TVID 藥 孳\n", "ESMG 濯 渥\n", "NBKS 勇 觔\n", "GKLMI 螯 螫\n", "VFHAF 鷥 鸞\n", "YMP 此 忐\n", "HKP 懲 忝\n", "YRPA 詢 詣\n", "KJCC 痲 癲\n", "IPP 態 庇 忒\n", "ROMR 哈 啥\n", "RKS 另 叻\n", "EPD 池 柒\n", "LWB 冑 胄\n", "BUOG 瞿 睢\n", "MGTMC 琪 璜\n", "AFMBC 顯 顥\n", "OM 丘 仝\n", "EMCW 酒 洒\n", "TYTR 菩 蒟\n", "RJBF 嗦 嚓\n", "THON 荇 蘅\n", "TT 井 并\n", "IFP 憑 慼\n", "RJI 戰 戢\n", "DWD 棵 梱\n", "KB 有 冇\n", "K 大 乂\n", "RKI 吰 呔\n", "RSJ 咡 咠\n", "RMCW 哂 唒\n", "RBUC 員 唄\n", "ROIR 嗆 唅\n", "RRRD 噪 喿\n", "RHSK 唳 噭\n", "RTWI 噂 囆\n", "GTWI 墫 壿\n", "SHOD 髹 屧\n", "UOIN 岑 岒\n", "UNMU 峗 峞\n", "IP 弋 庀\n", "PWD 悃 惈\n", "PMRW 匐 愊\n", "WOP 囮 慁\n", "YKP 忞 憝\n", "PHSK 悷 憿\n", "EBP 懣 懘\n", "QIHF 搣 摵\n", "QHSK 捩 撽\n", "QYRN 揨 攍\n", "AYK 旻 旼\n", "AUU 岊 昢\n", "DPI 杓 构\n", "DKN 朹 桋\n", "DNIN 杼 栘\n", "DNHD 楙 楺\n", "DYWV 榱 櫰\n", "YBNO 欳 歊\n", "WPP 毗 毘\n", "OMN 仃 气\n", "EMVM 涇 沍\n", "EKI 汰 汯\n", "ETT 汫 洴\n", "ESMG 濯 渥 洭\n", "EKN 氿 洟\n", "EC 汃 淦\n", "EYRN 瀛 渟\n", "EHNI 汎 渢\n", "JCEGG 窪 漥\n", "EHOO 漇 漎\n", "EOLB 滫 潃\n", "EJJJ 澣 濣\n", "EITC 濂 瀇\n", "EOMB 淪 瀹\n", "ELIM 渱 灗\n", "EMBB 濡 灞\n", "KHHSB 猏 猵\n", "MGOIR 琀 瑲\n", "HOPI 彴 瓝\n", "YBMVN 甋 甗\n", "OMRW 偪 畣\n", "KKB 肴 痏\n", "KMSO 瓿 瘃\n", "KKLU 瓾 痷\n", "KRYE 敧 瘕\n", "KHOK 癥 癓\n", "YMDHE 皻 皽\n", "BUJMC 瞚 矉\n", "HBMR 筒 礐\n", "YPMR 砦 礱\n", "HLLN 劓 笰\n", "HBUU 筧 篹\n", "HJII 篿 簙\n", "HMGN 箌 籈\n", "HSMG 筐 籊\n", "HYHS 舴 籩\n", "PFMBC 熲 顈\n", "BUU 朏 胐\n", "BPR 朐 胊\n", "BLMO 朓 脁\n", "BICE 朘 脧\n", "YVB 肓 膂\n", "TIP 懟 芅\n", "TSP 懃 苨\n", "TKN 艽 荑\n", "TNIN 芧 茤\n", "TOG 茌 萑\n", "THSB 菺 萹\n", "TIHR 葴 蒧\n", "TGGI 葑 蓺\n", "THOO 蓏 蓰\n", "THOO 蓏 蓰 蓯\n", "THDH 菞 蕛\n", "TMNV 蒆 薞\n", "TYRE 蔎 蕸\n", "TMGN 菿 薽\n", "THDV 萎 藒\n", "THAF 蔦 蘤\n", "TWLP 薨 藣\n", "TYRV 藹 蘘\n", "TOMB 菕 蘥\n", "TTCG 蘣 蘳\n", "HYPU 箎 虒\n", "IHHI 蠯 螷\n", "LITMC 蜞 蟥\n", "YIHXO 斔 螤\n", "LIJMC 螾 蠙\n", "YHDV 逶 褎\n", "YRYCB 謫 謪\n", "YRYPM 謔 謯\n", "YPYMR 訾 讋\n", "BHUU 膬 貀\n", "RMHOO 蹤 蹝\n", "JJTGI 轙 轛\n", "HRHPM 錕 迣\n", "HRNL 郈 郜\n", "HUNL 郋 郳\n", "MGNL 郅 鄄\n", "TRNL 鄯 鄀\n", "BCNL 郥 鄍\n", "IBNL 郙 鄘\n", "TMNL 邯 鄞\n", "HDNL 邾 鄡\n", "MRNL 郚 酃\n", "HCNL 鄮 酇\n", "HFD 乎 釆\n", "CNL 弚 鈏\n", "EUC 鎏 鍌\n", "CJMO 錠 鎵\n", "TOG 茌 萑 雈\n", "UOGB 巂 雟\n", "TJMN 苧 靪\n", "TJMU 莞 靰\n", "ORMBC 頷 頜\n", "NUMBC 頠 顄\n", "TBMBC 顢 顜\n", "HRHPM 錕 迣 鬳\n", "OLOF 絛 鯈\n", "NFTWI 鱒 鱴\n", "CHHAF 鵜 鳻\n", "HOHAF 鴔 鴩\n", "YKHAF 鳼 鵁\n", "HRHAF 鵠 鴰\n", "HRHAF 鵠 鴰 鵅\n", "MNHAF 殦 鴷\n", "JVHAF 鴳 鶈\n", "KRHAF 鴐 鵸\n", "RSHAF 鴞 鶚\n", "HUHAF 鶂 鶞\n", "HBHAF 鵳 鶣\n", "JRHAF 鴣 鶷\n", "TTHAF 鵧 鷁\n", "GFHNE 縠 鷇\n", "MBHAF 鴯 鷊\n", "JCHAF 窵 鷏\n", "AVHAF 鶡 鷃\n", "JTCF 騫 鶱\n", "IBHAF 鵏 鷛\n", "SHHAF 鳭 鷚\n", "AVHAF 鶡 鷃 鷐\n", "YKHAF 鳼 鵁 鷟\n", "MJHAF 鳱 鷣\n", "OFHAF 鷦 鷡\n", "HBHAF 鵳 鶣 鷮\n", "YKHAF 鳼 鵁 鷟 鸆\n", "HBHAF 鵳 鶣 鷮 鷽\n", "MBHAF 鴯 鷊 鸍\n", "KKHAF 鷞 鸑\n", "YTHAF 鴗 鸕\n", "YPHAF 鷾 鸗\n", "YPMMF 祡 龒\n" ] } ], "source": [ "tmp = defaultdict(list)\n", "for char in ranked_chars:\n", " code = input_dict[char]\n", " exist_char = tmp.get(code)\n", " arr = tmp[code]\n", " arr.append(char)\n", " if len(arr) > 1:\n", " print(f'{code} {\" \".join(arr)}')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3.10.8 ('base-AKxH9jWp-py3.10')", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.8" }, "vscode": { "interpreter": { "hash": "21665598cd3b8544e7d19a3dc85c067639c90171c4ea0b5cf1485f3de8740121" } } }, "nbformat": 4, "nbformat_minor": 4 }