shuang_pin_tutorial 1.1.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e4a10efd89f18dd8b4cd10dd74e7f3fcda75c89765b7fadea755e17f560b3847
4
+ data.tar.gz: f88c8a9c0a893c4d89247cd79d90147444a61d4c73386d57324d96cb891c59ad
5
+ SHA512:
6
+ metadata.gz: f710a194ea96bae7d148e17017fef7c0514a7fc2ab3d15b832a7788775838cf3815ea23d38cf405f17b8c53fc68789b9d68ff0e96ab1d64d46016eea1ad760d1
7
+ data.tar.gz: 69b963816a2c38794280ee9882de3d8200543d3222de3f7c8320102803f6a72edd17f853868196e986b8bdd0ab8c012c00274623f96cdd7d7a69803b374482ac
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 David N
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # 幫助你快速學習雙拼 —— 微軟雙拼(繁體中文版)
2
+
3
+ ### 程序簡介:
4
+
5
+ 一個萌妹子風格的輸入法學習套件,參考新華字典的設定,每次隨機出現出合理的拼音組合。<br>
6
+ 根據輸出的拼音組合中打出對應的雙拼,每個字用空格隔開,按 Enter 提交,輸入 ```exit``` 提交或者按下 Ctrl+c 退出練習。
7
+
8
+ 快速學習雙拼 程序畫面:\
9
+ ![image][shuang_pin_tutorial_console]
10
+
11
+ 微軟雙拼鍵盤方案圖:\
12
+ ![image][shuang_pin_keyboard]
13
+
14
+ <br>另外,[參考文件夾][folder_img]中附上:
15
+
16
+ * [普通話聲韻配合表][pthtable]
17
+ * [漢語拼音與通用拼音對照表][shuang_pin_200_words_sample]
18
+ * [雙拼鍵盤口訣][shuang_pin_keyboard_quote]
19
+ * [速成雙拼需學200字][zhuyin_pinyin_conversion_table]
20
+
21
+ ---
22
+
23
+ ### 執行步驟:
24
+
25
+ 如果沒有安裝 Ruby 的情況下,需要先[安裝 Ruby][rubychina_install_ruby]。
26
+
27
+ 安裝與運行:
28
+ ```bash
29
+ gem install shuang_pin_tutorial # 透過 Gem 安裝學習雙拼套件
30
+
31
+ shuang_pin_tutorial # 運行套件
32
+ ```
33
+
34
+ [shuang_pin_tutorial_console]: ./img/shuang_pin_tutorial_console.png "shuang pin tutorial console"
35
+ [shuang_pin_keyboard]: ./img/shuang_pin_keyboard.png "shuang pin keyboard"
36
+ [rubychina_install_ruby]: https://ruby-china.org/wiki/install_ruby_guide "ruby-china install ruby method"
37
+
38
+ [folder_img]: https://github.com/jsdnhk/shuang-pin-tutorial-tw/tree/master/ref
39
+ [pthtable]: ./ref/PTHtable_cuhk.pdf
40
+ [shuang_pin_200_words_sample]: ./ref/shuang_pin_200_words_sample.txt
41
+ [shuang_pin_keyboard_quote]: ./ref/shuang_pin_keyboard_quote.txt
42
+ [zhuyin_pinyin_conversion_table]: ./ref/zhuyin_pinyin_conversion_table.pdf
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ STDOUT.sync = true
5
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
6
+
7
+ require 'shuang_pin_tutorial'
8
+
9
+ main = ShuangPinTutorial::Main.new()
10
+ main.run()
@@ -0,0 +1,264 @@
1
+ # encoding: UTF-8
2
+
3
+ module ShuangPinTutorial
4
+ class Data
5
+ # 聲母列表 23 個 + 一個特殊的聲母 o 用來輸入單音節的韻母字
6
+ SHENG_MU = {
7
+ # 雙唇、齒唇音
8
+ b: "ㄅ", p: "ㄆ", m: "ㄇ", f: "ㄈ",
9
+ # 舌尖中音
10
+ d: "ㄉ", t: "ㄊ", n: "ㄋ", l: "ㄌ",
11
+ # 舌根音
12
+ g: "ㄍ", k: "ㄎ", h: "ㄏ",
13
+ # 舌面前音
14
+ j: "ㄐ", q: "ㄑ", x: "ㄒ",
15
+ # 舌尖後音
16
+ zh: "ㄓ", ch: "ㄔ", sh: "ㄕ", r: "ㄖ",
17
+ # 舌尖前音
18
+ z: "ㄗ", c: "ㄘ", s: "ㄙ",
19
+ # 無聲母
20
+ y: "ㄧ", w: "ㄨ", o: ""
21
+ }
22
+
23
+ # 韻母列表 35 個
24
+ YUN_MU = {
25
+ # 開口呼
26
+ a: "ㄚ", o: "ㄛ", e: "ㄜ", er: "ㄦ",
27
+ ai: "ㄞ", ei: "ㄟ", ao: "ㄠ", ou: "ㄡ",
28
+ an: "ㄢ", en: "ㄣ", ang: "ㄤ", eng: "ㄥ",
29
+ # 齊齒呼
30
+ i: "ㄧ", ia: "ㄧㄚ", ie: "ㄧㄝ", iao: "ㄧㄠ",
31
+ iu: "ㄧㄡ", ian: "ㄧㄢ", in: "ㄧㄣ", iang: "ㄧㄤ",
32
+ ing: "ㄧㄥ",
33
+ # 合口呼
34
+ u: "ㄨ", ua: "ㄨㄚ", uo: "ㄨㄛ", uai: "ㄨㄞ",
35
+ ui: "ㄨㄟ", uan: "ㄨㄢ", un: "ㄨㄣ", uang: "ㄨㄤ",
36
+ ong: "ㄨㄥ",
37
+ # 撮口呼
38
+ ü: "ㄩ", üe: "ㄩㄝ", üan: "ㄩㄢ", ün: "ㄩㄣ",
39
+ iong: "ㄩㄥ"
40
+ }
41
+
42
+ =begin
43
+ 'y' and 'w' is not included because 'ㄧ' and 'ㄨ' are already
44
+ mapped to 'i' and 'u'
45
+ "ㄧ": "y", "ㄨ": "w",
46
+ =end
47
+
48
+ # 聲母對應合法的韻母組合
49
+ LEGAL_COMPOSITE = {
50
+ :b => %w(a ai an ang ao ei en eng i ian iao ie in ing o u),
51
+ :p => %w(a ai an ang ao ei en eng i ian iao ie in ing o ou u),
52
+ :m => %w(a ai an ang ao e ei en eng i ian iao ie in ing iu o ou u),
53
+ :f => %w(a an ang ei en eng o ou u),
54
+ :d => %w(a ai an ang ao e ei eng i ian iao ie ing iu ong ou u uan ui un uo),
55
+ :t => %w(a ai an ang ao e eng i ian iao ie ing ong ou u uan ui un uo),
56
+ :n => %w(a ai an ang ao e ei en eng i ian iang iao ie in ing iu ong u uan uo ü üe),
57
+ :l => %w(a ai an ang ao e ei eng i ia ian iang iao ie in ing iu ong ou u uan un uo ü üe),
58
+ :g => %w(a ai an ang ao e ei en eng ong ou u ua uai uan uang ui un uo),
59
+ :k => %w(a ai an ang ao e en eng ong ou u ua uai uan uang ui un uo),
60
+ :h => %w(a ai an ang ao e ei en eng ong ou u ua uai uan uang ui un uo),
61
+ :j => %w(i ia ian iang iao ie in ing iu u üe üan ün iong), # ü as u
62
+ :q => %w(i ia ian iang iao ie in ing iu u üe üan ün iong), # ü as u
63
+ :x => %w(i ia ian iang iao ie in ing iu u üe üan ün iong), # ü as u
64
+ :zh => %w(a ai an ang ao e ei en eng i ong ou u ua uai uan uang ui un uo),
65
+ :ch => %w(a ai an ang ao e en eng i ong ou u uai uan uang ui un uo),
66
+ :sh => %w(a ai an ang ao e ei en eng i ou u ua uai uan uang ui un uo),
67
+ :r => %w(an ang ao e en eng i ong ou u uan ui un uo),
68
+ :z => %w(a ai an ang ao e ei en eng i ong ou u uan ui un uo),
69
+ :c => %w(a ai an ang ao e en eng i ong ou u uan ui un uo),
70
+ :s => %w(a ai an ang ao e en eng i ong ou u uan ui un uo),
71
+ :y => %w(a an ang ao e i in ing ong ou u üan üe ün), # ü as u
72
+ :w => %w(a ai an ang ei en eng o u),
73
+ :o => %w(a o e an ao ai ei en eng er ang ou)
74
+ }
75
+
76
+ # 普通話聲韻配合表
77
+ SHENG_YUN_WORD_TABLE = {
78
+ :b => {:a=>"巴", :o=>"玻", :ai=>"白", :ei=>"杯", :ao=>"包", :an=>"般", :en=>"奔", :ang=>"幫", :eng=>"崩", :i=>"逼", :ie=>"別", :iao=>"標", :ian=>"邊", :in=>"濱", :ing=>"冰", :u=>"不"},
79
+ :p => {:a=>"趴", :o=>"坡", :ai=>"拍", :ei=>"培", :ao=>"拋", :ou=>"剖", :an=>"潘", :en=>"噴", :ang=>"旁", :eng=>"烹", :i=>"批", :ie=>"撇", :iao=>"飄", :ian=>"篇", :in=>"拼", :ing=>"乒", :u=>"鋪"},
80
+ :m => {:a=>"媽", :o=>"摸", :e=>"麼", :ai=>"埋", :ei=>"眉", :ao=>"貓", :ou=>"謀", :an=>"蠻", :en=>"悶", :ang=>"忙", :eng=>"盟", :i=>"迷", :ie=>"滅", :iao=>"苗", :iu=>"謬", :ian=>"棉", :in=>"民", :ing=>"明", :u=>"木"},
81
+ :f => {:a=>"發", :o=>"佛", :ei=>"飛", :ou=>"否", :an=>"翻", :en=>"分", :ang=>"方", :eng=>"風", :u=>"夫"},
82
+ :d => {:a=>"搭", :e=>"得", :ai=>"呆", :ei=>"得", :ao=>"刀", :ou=>"兜", :an=>"單", :ang=>"當", :eng=>"登", :i=>"低", :ie=>"爹", :iao=>"雕", :iu=>"丟", :ian=>"顛", :ing=>"㆜", :u=>"都", :uo=>"多", :ui=>"堆", :uan=>"端", :un=>"蹲", :ong=>"東"},
83
+ :t => {:a=>"他", :e=>"特", :ai=>"胎", :ao=>"滔", :ou=>"偷", :an=>"攤", :ang=>"湯", :eng=>"疼", :i=>"梯", :ie=>"貼", :iao=>"挑", :ian=>"㆝", :ing=>"聽", :u=>"禿", :uo=>"脫", :ui=>"推", :uan=>"團", :un=>"吞", :ong=>"通"},
84
+ :n => {:a=>"拿", :e=>"訥", :ai=>"奶", :ei=>"內", :ao=>"腦", :an=>"南", :en=>"嫩", :ang=>"囊", :eng=>"能", :i=>"泥", :ie=>"捏", :iao=>"鳥", :iu=>"牛", :ian=>"年", :in=>"您", :iang=>"娘", :ing=>"寧", :u=>"奴", :uo=>"挪", :uan=>"暖", :ong=>"農", :ü=>"女", :üe=>"虐"},
85
+ :l => {:a=>"拉", :e=>"勒", :ai=>"來", :ei=>"累", :ao=>"老", :ou=>"樓", :an=>"蘭", :ang=>"郎", :eng=>"冷", :i=>"黎", :ia=>"倆", :ie=>"列", :iao=>"了", :iu=>"流", :ian=>"連", :in=>"林", :iang=>"涼", :ing=>"零", :u=>"爐", :uo=>"鑼", :uan=>"亂", :un=>"輪", :ong=>"龍", :ü=>"呂", :üe=>"略"},
86
+ :g => {:a=>"嘎", :e=>"哥", :ai=>"該", :ei=>"給", :ao=>"高", :ou=>"溝", :an=>"甘", :en=>"根", :ang=>"剛", :eng=>"更", :u=>"姑", :ua=>"瓜", :uo=>"鍋", :uai=>"拐", :ui=>"規", :uan=>"關", :un=>"滾", :uang=>"光", :ong=>"工"},
87
+ :k => {:a=>"咖", :e=>"科", :ai=>"開", :ao=>"考", :ou=>"口", :an=>"刊", :en=>"肯", :ang=>"康", :eng=>"坑", :u=>"枯", :ua=>"誇", :uo=>"闊", :uai=>"快", :ui=>"虧", :uan=>"寬", :un=>"昆", :uang=>"筐", :ong=>"空"},
88
+ :h => {:a=>"哈", :e=>"喝", :ai=>"海", :ei=>"黑", :ao=>"好", :ou=>"後", :an=>"寒", :en=>"很", :ang=>"杭", :eng=>"哼", :u=>"呼", :ua=>"花", :uo=>"火", :uai=>"懷", :ui=>"灰", :uan=>"歡", :un=>"婚", :uang=>"荒", :ong=>"轟"},
89
+ :j => {:i=>"基", :ia=>"家", :ie=>"街", :iao=>"交", :iu=>"究", :ian=>"堅", :in=>"今", :iang=>"江", :ing=>"京", :u=>"居", :üe=>"決", :üan=>"捐", :ün=>"軍", :iong=>"窘"},
90
+ :q => {:i=>"欺", :ia=>"搯", :ie=>"切", :iao=>"敲", :iu=>"秋", :ian=>"千", :in=>"親", :iang=>"腔", :ing=>"清", :u=>"區", :üe=>"缺", :üan=>"圈", :ün=>"群", :iong=>"窮"},
91
+ :x => {:i=>"希", :ia=>"瞎", :ie=>"些", :iao=>"消", :iu=>"休", :ian=>"先", :in=>"新", :iang=>"香", :ing=>"星", :u=>"虛", :üe=>"靴", :üan=>"宣", :ün=>"詢", :iong=>"兄"},
92
+ :zh => {:a=>"渣", :e=>"遮", :i=>"知", :ai=>"窄", :ei=>"這", :ao=>"招", :ou=>"周", :an=>"沾", :en=>"真", :ang=>"張", :eng=>"爭", :u=>"珠", :ua=>"抓", :uo=>"桌", :uai=>"拽", :ui=>"追", :uan=>"專", :un=>"準", :uang=>"裝", :ong=>"㆗"},
93
+ :ch => {:a=>"插", :e=>"車", :i=>"吃", :ai=>"拆", :ao=>"超", :ou=>"抽", :an=>"攙", :en=>"陳", :ang=>"昌", :eng=>"稱", :u=>"初", :uo=>"戳", :uai=>"揣", :ui=>"吹", :uan=>"穿", :un=>"春", :uang=>"窗", :ong=>"充"},
94
+ :sh => {:a=>"沙", :e=>"奢", :i=>"詩", :ai=>"篩", :ei=>"誰", :ao=>"燒", :ou=>"收", :an=>"山", :en=>"伸", :ang=>"傷", :eng=>"生", :u=>"書", :ua=>"刷", :uo=>"說", :uai=>"衰", :ui=>"水", :uan=>"栓", :un=>"順", :uang=>"雙"},
95
+ :r => {:e=>"熱", :i=>"日", :ao=>"繞", :ou=>"柔", :an=>"然", :en=>"㆟", :ang=>"讓", :eng=>"扔", :u=>"如", :uo=>"若", :ui=>"瑞", :uan=>"軟", :un=>"潤", :ong=>"榮"},
96
+ :z => {:a=>"雜", :e=>"則", :i=>"資", :ai=>"災", :ei=>"賊", :ao=>"遭", :ou=>"鄒", :an=>"咱", :en=>"怎", :ang=>"髒", :eng=>"增", :u=>"租", :uo=>"昨", :ui=>"最", :uan=>"鑽", :un=>"尊", :ong=>"宗"},
97
+ :c => {:a=>"擦", :e=>"測", :i=>"雌", :ai=>"猜", :ao=>"曹", :ou=>"湊", :an=>"參", :en=>"岑", :ang=>"倉", :eng=>"層", :u=>"粗", :uo=>"錯", :ui=>"催", :uan=>"篡", :un=>"村", :ong=>"聰"},
98
+ :s => {:a=>"撒", :e=>"色", :i=>"私", :ai=>"腮", :ao=>"搔", :ou=>"搜", :an=>"㆔", :en=>"森", :ang=>"桑", :eng=>"僧", :u=>"蘇", :uo=>"索", :ui=>"雖", :uan=>"酸", :un=>"孫", :ong=>"鬆"},
99
+ :y => {:i=>"衣", :a=>"呀", :e=>"耶", :ao=>"腰", :ou=>"優", :an=>"煙", :in=>"因", :ang=>"央", :ing=>"英", :u=>"迂", :üe=>"約", :üan=>"冤", :ün=>"暈", :ong=>"庸"},
100
+ :w => {:u=>"烏", :a=>"蛙", :o=>"窩", :ai=>"歪", :ei=>"威", :an=>"彎", :en=>"溫", :ang=>"汪", :eng=>"翁"},
101
+ :o => {:a=>"啊", :o=>"喔", :e=>"鵝", :er=>"兒", :ai=>"哀", :ei=>"欸", :ao=>"熬", :ou=>"歐", :an=>"安", :en=>"恩", :ang=>"昂", :eng=>"鞥"}
102
+ }
103
+
104
+ # 每個按鍵對應的雙拼表
105
+ VALID_COMPOSITE = {
106
+ :Q => %w(q iu),
107
+ :W => %w(w ia ua),
108
+ :E => %w(e),
109
+ :R => %w(r uan üan er),
110
+ :T => %w(t ue üe),
111
+ :Y => %w(y uai), #also accept ü, but by 'v' button in general
112
+ :U => %w(u sh),
113
+ :I => %w(i ch),
114
+ :O => %w(o uo),
115
+ :P => %w(p un ün),
116
+ :A => %w(a),
117
+ :S => %w(s ong iong),
118
+ :D => %w(d uang iang),
119
+ :F => %w(f en),
120
+ :G => %w(g eng),
121
+ :H => %w(h ang),
122
+ :J => %w(j an),
123
+ :K => %w(k ao),
124
+ :L => %w(l ai),
125
+ :';' => %w(ing),
126
+ :Z => %w(z ei),
127
+ :X => %w(x ie),
128
+ :C => %w(c iao),
129
+ :V => %w(zh ui ü),
130
+ :B => %w(b ou),
131
+ :N => %w(n in),
132
+ :M => %w(m ian),
133
+ }
134
+
135
+ def initialize()
136
+ SHENG_MU.freeze
137
+ YUN_MU.freeze
138
+ LEGAL_COMPOSITE.freeze
139
+ SHENG_YUN_WORD_TABLE.freeze
140
+ VALID_COMPOSITE.freeze
141
+ end
142
+
143
+ # 提取隨機文字部分
144
+ def get_rand_sheng_yun_sym()
145
+ sheng = SHENG_MU.keys.sample.to_sym
146
+ yun = LEGAL_COMPOSITE[sheng].sample.to_sym
147
+ [sheng, yun]
148
+ end
149
+
150
+ def get_sheng_yun_zy(sheng, yun)
151
+ sheng_zy = SHENG_MU[sheng.to_sym].to_s.strip
152
+ yun_zy = YUN_MU[yun.to_sym].to_s.strip
153
+ [sheng_zy, yun_zy]
154
+ end
155
+
156
+ def get_zy(sheng, yun) #sheng, yun: sym
157
+ shengyun = get_sy(sheng, yun)
158
+ sheng_zy, yun_zy = get_sheng_yun_zy(sheng, yun)
159
+ case shengyun # special cases for zhuyin required to fine-adjust
160
+ when 'zhi'
161
+ SHENG_MU[:zh]
162
+ when 'chi'
163
+ SHENG_MU[:ch]
164
+ when 'shi'
165
+ SHENG_MU[:sh]
166
+ when 'ri'
167
+ SHENG_MU[:r]
168
+ when 'zi'
169
+ SHENG_MU[:z]
170
+ when 'ci'
171
+ SHENG_MU[:c]
172
+ when 'si'
173
+ SHENG_MU[:s]
174
+ when 'yu', 'yü'
175
+ YUN_MU[:ü]
176
+ when 'yuan', 'yüan'
177
+ YUN_MU[:üan]
178
+ when 'yue', 'yüe'
179
+ YUN_MU[:üe]
180
+ when 'yun', 'yün'
181
+ YUN_MU[:ün]
182
+ when 'yong'
183
+ YUN_MU[:iong]
184
+ when 'ju', 'jü', 'qu', 'qü', 'xu', 'xü'
185
+ (SHENG_MU[sheng] + YUN_MU[:ü]).chars.uniq.join
186
+ else
187
+ (sheng_zy + yun_zy).chars.uniq.join
188
+ end
189
+ end
190
+
191
+ def get_sy(sheng, yun) #sheng, yun: sym
192
+ (sheng.to_s.strip + yun.to_s.strip).sub(/^o/,'')
193
+ end
194
+
195
+ def get_cw(sheng, yun) #sheng, yun: sym
196
+ cw = SHENG_YUN_WORD_TABLE.fetch(sheng.to_sym).fetch(yun.to_sym) rescue puts("內部錯誤:資料中查無此字 【#{sheng}#{yun}】")
197
+ cw ||= ''
198
+ end
199
+
200
+ # 計算拼音輸入碼答案部分
201
+ # recursive way
202
+ def get_correct_keys(input_pinyin)
203
+ return get_correct_keys_helper(input_pinyin, 2)
204
+ end
205
+
206
+ def get_correct_keys_helper(input_pinyin, output_keys)
207
+ press_keys = nil
208
+ input_pinyin = input_pinyin.downcase.strip
209
+ if output_keys == 0
210
+ return press_keys.to_s
211
+ elsif output_keys == 1
212
+ VALID_COMPOSITE.each do |key, value|
213
+ press_keys = key.to_s if value.include?(input_pinyin)
214
+ break if press_keys
215
+ end
216
+ return press_keys.to_s
217
+ elsif output_keys == 2
218
+ if LEGAL_COMPOSITE[:o].include?(input_pinyin) # 韻母單音節字
219
+ press_keys = 'O' + get_correct_keys_helper(input_pinyin, 1)
220
+ elsif input_pinyin.start_with?('zh', 'ch', 'sh')
221
+ press_keys = get_correct_keys_helper(input_pinyin[0,2], 1) + get_correct_keys_helper(input_pinyin[2..input_pinyin.length], 1)
222
+ else
223
+ press_keys = get_correct_keys_helper(input_pinyin[0,1], 1) + get_correct_keys_helper(input_pinyin[1..input_pinyin.length], 1)
224
+ end
225
+ else
226
+ raise(RangeError, '未需支援兩個以上拼音碼')
227
+ end
228
+ press_keys.to_s
229
+ end
230
+
231
+ =begin
232
+ # iterative way
233
+ def get_correct_keys(input_pinyin)
234
+ press_keys=''
235
+ input_pinyin = input_pinyin.downcase.strip
236
+ if LEGAL_COMPOSITE[:o].include?(input_pinyin)
237
+ # 韻母單音節字
238
+ press_keys << 'O'
239
+ get_a_press_key(input_pinyin, press_keys) # yun only
240
+ return press_keys
241
+ end
242
+
243
+ if input_pinyin.start_with?('zh', 'ch', 'sh')
244
+ get_a_press_key(input_pinyin[0,2], press_keys) # sheng
245
+ get_a_press_key(input_pinyin[2,input_pinyin.length], press_keys) # yun
246
+ else
247
+ get_a_press_key(input_pinyin[0,1], press_keys) # sheng
248
+ get_a_press_key(input_pinyin[1,input_pinyin.length], press_keys) # yun
249
+ end
250
+
251
+ press_keys
252
+ end
253
+
254
+ def get_a_press_key(word, press_keys)
255
+ VALID_COMPOSITE.each do |key, value|
256
+ if value.include?(word)
257
+ press_keys << key.to_s
258
+ break
259
+ end
260
+ end
261
+ end
262
+ =end
263
+ end
264
+ end
@@ -0,0 +1,136 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'date'
4
+ require_relative 'data'
5
+
6
+ module ShuangPinTutorial
7
+ INT_WORDS_DISPLAYED = 6
8
+ STR_TIPS_SEPARATOR='———'
9
+ IS_ENABLE_TIPS = true
10
+ IS_DISPLAY_ZHUYIN = true
11
+ IS_DISPLAY_CWORD = true
12
+
13
+ class Handler
14
+ def initialize()
15
+ end
16
+
17
+ def start()
18
+ # 初始化
19
+ @sp_data = Data.new()
20
+ @words_counts = [0, 0, 0]
21
+ @start_time = DateTime.now
22
+ @end_time = nil
23
+ puts "歡迎使用 快速學習雙拼 -- 微軟雙拼(繁體中文版)!要好好練習哦!(#{VERSION} 版)"
24
+ puts "要輸入下面中文字對應雙拼字碼哦!使用空格隔開,要休息請輸入 'exit' 或按 Ctrl+c 吧!\n"
25
+ # looping
26
+ while true
27
+ result = get_question_lines
28
+ result_words = result[0]
29
+ result_display = result[1]
30
+ print "\n#{result_display.join("\n")}\n"
31
+
32
+ input_answers = gets
33
+
34
+ if input_answers.respond_to?(:to_str)
35
+ raise(Interrupt, "用戶退出") if input_answers.strip.downcase == 'exit'
36
+ eval_result(input_answers, result_words)
37
+ end
38
+ end
39
+ end
40
+
41
+ def get_words_showlines(num = INT_WORDS_DISPLAYED, display_delim: "|") # return [words(str), [display line(s)]]
42
+ result = []
43
+ display = []
44
+ display_py = []
45
+ display_zy = []
46
+ display_cw = []
47
+ num.times do
48
+ sheng, yun = @sp_data.get_rand_sheng_yun_sym()
49
+ shengyun = @sp_data.get_sy(sheng, yun)
50
+ zy = @sp_data.get_zy(sheng, yun)
51
+ cw = @sp_data.get_cw(sheng, yun)
52
+ result.push(shengyun)
53
+ display_py.push(shengyun + "\t")
54
+ display_zy.push(zy + "\t")
55
+ display_cw.push(cw + "\t")
56
+ end
57
+ display << display_py.join(display_delim)
58
+ display << display_zy.join(display_delim) if IS_DISPLAY_ZHUYIN
59
+ display << display_cw.join(display_delim) if IS_DISPLAY_CWORD
60
+ [result.join(" "), display]
61
+ end
62
+
63
+ def eval_result(input_answer, result_words)
64
+ # 尋找打錯了的字
65
+ incorrect = {}
66
+ correct = 0
67
+ is_all_finished = input_answer.split.length >= result_words.split.length
68
+ input_answer.split.each_with_index do |input_keys, index|
69
+ break if index >= result_words.split.length # ignore the extra input part
70
+
71
+ if input_keys.length != 2
72
+ incorrect[index + 1] = "#{input_keys}: 雙拼只能由兩個字母組合而成!"
73
+ next
74
+ end
75
+
76
+ res = result_words.split[index]
77
+ right_answer = @sp_data.get_correct_keys(res)
78
+ unless right_answer.casecmp(input_keys.to_s) == 0
79
+ incorrect[index + 1] = "#{input_keys}: 不能得到 #{res} 哦!或許你可以試試 #{right_answer}"
80
+ else
81
+ correct += 1
82
+ end
83
+ end
84
+
85
+ # 編出成績
86
+ @words_counts[0] += result_words.split.length
87
+ @words_counts[1] += correct
88
+ @words_counts[2] += result_words.split.length - correct
89
+
90
+ if !is_all_finished
91
+ puts "你好像寫不齊哦!共有:#{result_words.split.length},已輸入:#{input_answer.split.length}"
92
+ elsif incorrect.length == 0
93
+ puts '恭喜你全對耶!'
94
+ end
95
+ incorrect.each { |key, value| puts "#{key}) 錯誤 => #{value}"}
96
+ end
97
+
98
+ def get_question_lines
99
+ result = get_words_showlines
100
+ result_words = result[0]
101
+ result_display = result[1]
102
+ result_tips = []
103
+ if IS_ENABLE_TIPS
104
+ result_words.split.each { |res| result_tips.push(@sp_data.get_correct_keys(res)) }
105
+ result_display[0] = "#{result_display[0]} #{STR_TIPS_SEPARATOR} 【#{result_tips.join(" ")}】"
106
+ end
107
+ result
108
+ end
109
+
110
+ def get_total_time_str
111
+ @end_time = DateTime.now
112
+ @total_time = ((@end_time - @start_time) * 24 * 60 * 60).to_i
113
+ str_total_time_s = Time.at(@total_time).utc.strftime("%S").gsub(/^0/, '')
114
+ str_total_time_m = Time.at(@total_time).utc.strftime("%M").gsub(/^0/, '')
115
+ str_total_time_h = Time.at(@total_time).utc.strftime("%H").gsub(/^0+/, '')
116
+ str_total_time =
117
+ case @total_time
118
+ when 0...60
119
+ "#{str_total_time_s} 秒"
120
+ when 60...3600
121
+ "#{str_total_time_m} 分 #{str_total_time_s} 秒"
122
+ else
123
+ "#{str_total_time_h} 小時 #{str_total_time_m} 分 #{str_total_time_s} 秒"
124
+ end
125
+ str_total_time
126
+ end
127
+
128
+ def get_total_words_result
129
+ percent_correctness = @words_counts[0].to_f != 0 ? (@words_counts[1].to_f/@words_counts[0].to_f) * 100 : 0
130
+ str_output = ""
131
+ str_output += "共有字數: #{@words_counts[0]} 字;正確字數: #{@words_counts[1]} 字;錯誤字數: #{@words_counts[2]} 字" + "\n"
132
+ str_output += "總正確率: #{percent_correctness.round(2)} %"
133
+ str_output
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: UTF-8
3
+
4
+ require_relative 'handler'
5
+
6
+ module ShuangPinTutorial
7
+ class Main
8
+ def initialize()
9
+ @is_run_success = true
10
+ @obj_tutorial = nil
11
+ end
12
+
13
+ def run()
14
+ @obj_tutorial = Handler.new()
15
+ @obj_tutorial.start()
16
+ rescue Interrupt => ir
17
+ $stdout.puts('累了就該休息一下吧!')
18
+ rescue Exception => ex
19
+ $stderr.puts('執行時發生錯誤哦,信息在下面:')
20
+ $stderr.puts(ex.message)
21
+ $stderr.puts(ex.backtrace)
22
+ @is_run_success = false
23
+ ensure
24
+ $stdout.puts('訓練時間:')
25
+ $stdout.puts(@obj_tutorial.get_total_time_str)
26
+ $stdout.puts('成果統計:')
27
+ $stdout.puts(@obj_tutorial.get_total_words_result)
28
+ $stdout.puts('要努力學習哦,感謝使用!')
29
+ exit(@is_run_success)
30
+ end
31
+ end
32
+ end
33
+
34
+ if __FILE__ == $0 # for test-run use
35
+ main = ShuangPinTutorial::Main.new()
36
+ main.run()
37
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # $LOAD_PATH.unshift __dir__ # For use/testing when no gem is installed
4
+
5
+ # Require all of the Ruby files in the given directory.
6
+ def require_all(path)
7
+ glob = File.join(__dir__, path, "*.rb")
8
+ Dir[glob].sort.each do |f|
9
+ require f
10
+ end
11
+ end
12
+
13
+ module ShuangPinTutorial
14
+ MODULE = "ShuangPinTutorial"
15
+ NAME = "shuang_pin_tutorial"
16
+ VERSION = "1.1.1"
17
+
18
+ autoload(:Main, "#{NAME}/main")
19
+ autoload(:Handler, "#{NAME}/handler")
20
+ autoload(:Data, "#{NAME}/data")
21
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shuang_pin_tutorial
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.1
5
+ platform: ruby
6
+ authors:
7
+ - David N
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-02-25 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: An interesting, featured tutorial application for practicing Microsoft
14
+ Shuang Pin input method.
15
+ email: dn@jsdn.hk
16
+ executables:
17
+ - shuang_pin_tutorial
18
+ extensions: []
19
+ extra_rdoc_files:
20
+ - README.md
21
+ - LICENSE
22
+ files:
23
+ - LICENSE
24
+ - README.md
25
+ - exe/shuang_pin_tutorial
26
+ - lib/shuang_pin_tutorial.rb
27
+ - lib/shuang_pin_tutorial/data.rb
28
+ - lib/shuang_pin_tutorial/handler.rb
29
+ - lib/shuang_pin_tutorial/main.rb
30
+ homepage: https://github.com/jsdnhk/shuang_pin_tutorial
31
+ licenses:
32
+ - MIT
33
+ metadata:
34
+ source_code_uri: https://github.com/jsdnhk/shuang_pin_tutorial
35
+ changelog_uri: https://github.com/jsdnhk/shuang_pin_tutorial/CHANGELOG.md
36
+ documentation_uri: https://github.com/jsdnhk/shuang_pin_tutorial/README.md
37
+ post_install_message: Welcome using Microsoft Shuang Pin tutorial!
38
+ rdoc_options:
39
+ - "--charset=UTF-8"
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 2.4.0
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: 2.7.0
52
+ requirements: []
53
+ rubygems_version: 3.1.2
54
+ signing_key:
55
+ specification_version: 4
56
+ summary: A tutorial application for Microsoft Shuang Pin input method.
57
+ test_files: []