new-words

view misc/zubrator.py @ 62:3a61988109a8

grep-sentences.pl: color support
author Igor Chubin <igor@chub.in>
date Fri Nov 04 20:50:49 2011 +0100 (2011-11-04)
parents bf0aa8e3c1ce
children
line source
1 #!/usr/bin/python
3 import random
4 import sys
5 import time
7 # TODO:
8 # * persistent weight dict
9 # * log
10 # * stats (top5, time_total, time_last, correct_answers_rate_total, correct_answers_rate_last)
12 # DONE:
13 # * correct quit (ctrl d)
15 logfile = "/home/igor/Langs/Deutsch/training-scripts/geschlecht/zubrator.log"
17 class _Getch:
18 """Gets a single character from standard input. Does not echo to the
19 screen."""
20 def __init__(self):
21 try:
22 self.impl = _GetchWindows()
23 except ImportError:
24 self.impl = _GetchUnix()
26 def __call__(self): return self.impl()
29 class _GetchUnix:
30 def __init__(self):
31 import tty, sys
33 def __call__(self):
34 import sys, tty, termios
35 fd = sys.stdin.fileno()
36 old_settings = termios.tcgetattr(fd)
37 try:
38 tty.setraw(sys.stdin.fileno())
39 ch = sys.stdin.read(1)
40 finally:
41 termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
42 return ch
45 class _GetchWindows:
46 def __init__(self):
47 import msvcrt
49 def __call__(self):
50 import msvcrt
51 return msvcrt.getch()
54 getch = _Getch()
56 def log_answer(result, question, correct_answer, given_answer):
57 with open(logfile, "a") as f:
58 timestamp = time.strftime("%Y-%m-%d %H:%M")
59 f.write(" ".join([timestamp, result, question, correct_answer, given_answer])+"\n")
62 def color_for_answer(answer):
63 color_table = {
64 'der': 'Blue',
65 'das': 'Green',
66 'die': 'Red',
67 }
68 if not answer in color_table:
69 return 'Normal'
70 else:
71 return color_table[answer]
73 def colorprint(string, color=None):
74 color_table = {
75 'Gray': '\033[1;30m',
76 'Red': '\033[1;31m',
77 'Green': '\033[1;32m',
78 'Yellow': '\033[1;33m',
79 'Blue': '\033[1;34m',
80 'Magenta': '\033[1;35m',
81 'Cyan': '\033[1;36m',
82 'White': '\033[1;37m',
83 'Crimson': '\033[1;38m',
84 'Highlighted_Red': '\033[1;41m',
85 'Highlighted_Green': '\033[1;42m',
86 'Highlighted_Brown': '\033[1;43m',
87 'Highlighted_Blue': '\033[1;44m',
88 'Highlighted_Magenta': '\033[1;45m',
89 'Highlighted_Cyan': '\033[1;46m',
90 'Highlighted_Gray': '\033[1;47m',
91 'Highlighted_Crimson': '\033[1;48m',
92 }
93 normal_color_code = '\033[1;m'
94 if not color or color == 'Normal' or not color in color_table:
95 print string
96 else:
97 print "%s%s%s" % (color_table[color], string, normal_color_code)
99 def wrandom(dict):
100 total = sum(dict.values())
101 n = random.uniform(0, total)
103 for key in sorted(dict.keys()):
104 item = key
105 if n < dict[key]:
106 break
107 n -= dict[key]
109 return item
111 def set_weight(weight, word, new_weight):
112 if len(weight) <= 1:
113 raise Exception("Can't set weight; weight dictionary is too small; need at least two members")
114 sum_before = sum(weight.values())
115 w_before = weight[word]
116 w_after = new_weight
117 delta = (w_after - w_before)*1.0/(len(weight)-1)
118 for k in weight.keys():
119 if k == word:
120 weight[k] = w_after
121 else:
122 weight[k] -= delta
123 sum_after = sum(weight.values())
124 if abs(sum_before-sum_after)> 0.0001:
125 raise Exception("%s != %s ; function set_weight works incorrectly" % (sum_before, sum_after))
126 return weight
128 def print_stats(stats, weight, correct_answer):
129 print "------------------------"
130 print "total questions = %s" % stats['total_questions']
131 print "last questions = %s" % stats['last_questions']
132 print "total errors = %s (%.2f)" % (stats['total_errors'], 1.0*stats['total_errors']/stats['total_questions'])
133 print "last errors = %s (%.2f)" % (stats['last_errors'], 1.0*stats['last_errors']/stats['last_questions'])
134 print "top 5 questions:"
135 for question in sorted(weight.keys(),key=lambda x: weight[x], reverse=True)[:5]:
136 colorprint(
137 " %s %s %5.2f" % (correct_answer[question], question, weight[question]),
138 color_for_answer(correct_answer[question])
139 )
141 print "------------------------"
143 filename = sys.argv[1]
144 correct_answer = {}
145 with open(filename) as f:
146 for line in f.readlines():
147 line = line.rstrip('\n')
148 try:
149 (q, a) = line.split(' ', 1)
150 correct_answer[q] = a
151 except:
152 pass
154 saved_weight = {
155 'Auskunft' : 2,
156 }
158 weight = {}
159 for word in correct_answer.keys():
160 if word in saved_weight:
161 weight[word] = saved_weight[word]
162 else:
163 weight[word] = 1
165 stats = {
166 'total_errors' :0,
167 'last_errors' :0,
168 'total_questions' :0,
169 'last_questions' :0,
170 }
172 while 1:
173 question = wrandom(weight)
174 colorprint(question, 'Yellow')
175 #answer = sys.stdin.readline().rstrip('\n')
176 ch = getch()
177 codes = {
178 'q': 'der',
179 'w': 'das',
180 'e': 'die',
182 'p': 'der',
183 '[': 'das',
184 ']': 'die'
185 }
186 if ch in codes:
187 answer = codes[ch]
188 else:
189 answer = ''
191 if not answer:
192 break
194 result = "OK"
195 if answer != correct_answer[question]:
196 result = "FAIL"
197 colorprint(
198 "%s %s" % (correct_answer[question], question),
199 color_for_answer(correct_answer[question])
200 )
201 weight = set_weight(weight, question, weight[question]*1.5)
202 stats['total_errors'] += 1
203 stats['last_errors'] += 1
204 else:
205 weight = set_weight(weight, question, weight[question]*0.8)
207 log_answer(result, question, correct_answer[question], answer)
209 stats['total_questions'] += 1
210 stats['last_questions'] += 1
212 if stats['last_questions'] == 20:
213 print_stats(stats, weight, correct_answer)
214 stats['last_questions'] = 0
215 stats['last_errors'] = 0
217 print