igor@46: #!/usr/bin/python igor@46: igor@46: import random igor@46: import sys igor@46: igor@46: # TODO: igor@46: # * persistent weight dict igor@46: # * log igor@46: # * stats (top5, time_total, time_last, correct_answers_rate_total, correct_answers_rate_last) igor@46: igor@46: # DONE: igor@46: # * correct quit (ctrl d) igor@46: igor@46: def color_for_answer(answer): igor@46: color_table = { igor@46: 'der': 'Blue', igor@46: 'das': 'Green', igor@46: 'die': 'Red', igor@46: } igor@46: if not answer in color_table: igor@46: return 'Normal' igor@46: else: igor@46: return color_table[answer] igor@46: igor@46: def colorprint(string, color=None): igor@46: color_table = { igor@46: 'Gray': '\033[1;30m', igor@46: 'Red': '\033[1;31m', igor@46: 'Green': '\033[1;32m', igor@46: 'Yellow': '\033[1;33m', igor@46: 'Blue': '\033[1;34m', igor@46: 'Magenta': '\033[1;35m', igor@46: 'Cyan': '\033[1;36m', igor@46: 'White': '\033[1;37m', igor@46: 'Crimson': '\033[1;38m', igor@46: 'Highlighted_Red': '\033[1;41m', igor@46: 'Highlighted_Green': '\033[1;42m', igor@46: 'Highlighted_Brown': '\033[1;43m', igor@46: 'Highlighted_Blue': '\033[1;44m', igor@46: 'Highlighted_Magenta': '\033[1;45m', igor@46: 'Highlighted_Cyan': '\033[1;46m', igor@46: 'Highlighted_Gray': '\033[1;47m', igor@46: 'Highlighted_Crimson': '\033[1;48m', igor@46: } igor@46: normal_color_code = '\033[1;m' igor@46: if not color or color == 'Normal' or not color in color_table: igor@46: print string igor@46: else: igor@46: print "%s%s%s" % (color_table[color], string, normal_color_code) igor@46: igor@46: def wrandom(dict): igor@46: total = sum(dict.values()) igor@46: n = random.uniform(0, total) igor@46: igor@46: for key in sorted(dict.keys()): igor@46: item = key igor@46: if n < dict[key]: igor@46: break igor@46: n -= dict[key] igor@46: igor@46: return item igor@46: igor@46: def set_weight(weight, word, new_weight): igor@46: if len(weight) <= 1: igor@46: raise Exception("Can't set weight; weight dictionary is too small; need at least two members") igor@46: sum_before = sum(weight.values()) igor@46: w_before = weight[word] igor@46: w_after = new_weight igor@46: delta = (w_after - w_before)*1.0/(len(weight)-1) igor@46: for k in weight.keys(): igor@46: if k == word: igor@46: weight[k] = w_after igor@46: else: igor@46: weight[k] -= delta igor@46: sum_after = sum(weight.values()) igor@46: if abs(sum_before-sum_after)> 0.0001: igor@46: raise Exception("%s != %s ; function set_weight works incorrectly" % (sum_before, sum_after)) igor@46: return weight igor@46: igor@46: def print_stats(stats, weight, correct_answer): igor@46: print "------------------------" igor@46: print "total questions = %s" % stats['total_questions'] igor@46: print "last questions = %s" % stats['last_questions'] igor@46: print "total errors = %s (%.2f)" % (stats['total_errors'], 1.0*stats['total_errors']/stats['total_questions']) igor@46: print "last errors = %s (%.2f)" % (stats['last_errors'], 1.0*stats['last_errors']/stats['last_questions']) igor@46: print "top 5 questions:" igor@46: for question in sorted(weight.keys(),key=lambda x: weight[x], reverse=True)[:5]: igor@46: colorprint( igor@46: " %s %s %5.2f" % (correct_answer[question], question, weight[question]), igor@46: color_for_answer(correct_answer[question]) igor@46: ) igor@46: igor@46: print "------------------------" igor@46: igor@46: filename = sys.argv[1] igor@46: correct_answer = {} igor@46: with open(filename) as f: igor@46: for line in f.readlines(): igor@46: line = line.rstrip('\n') igor@46: try: igor@46: (q, a) = line.split(' ', 1) igor@46: correct_answer[q] = a igor@46: except: igor@46: pass igor@46: igor@46: saved_weight = { igor@46: 'Auskunft' : 2, igor@46: } igor@46: igor@46: weight = {} igor@46: for word in correct_answer.keys(): igor@46: if word in saved_weight: igor@46: weight[word] = saved_weight[word] igor@46: else: igor@46: weight[word] = 1 igor@46: igor@46: stats = { igor@46: 'total_errors' :0, igor@46: 'last_errors' :0, igor@46: 'total_questions' :0, igor@46: 'last_questions' :0, igor@46: } igor@46: igor@46: while 1: igor@46: question = wrandom(weight) igor@46: colorprint(question, 'Yellow') igor@46: answer = sys.stdin.readline().rstrip('\n') igor@46: if not answer: igor@46: break igor@46: if answer != correct_answer[question]: igor@46: colorprint( igor@46: "%s %s" % (correct_answer[question], question), igor@46: color_for_answer(correct_answer[question]) igor@46: ) igor@46: weight = set_weight(weight, question, weight[question]*1.5) igor@46: stats['total_errors'] += 1 igor@46: stats['last_errors'] += 1 igor@46: else: igor@46: weight = set_weight(weight, question, weight[question]*0.8) igor@46: igor@46: stats['total_questions'] += 1 igor@46: stats['last_questions'] += 1 igor@46: igor@46: if stats['last_questions'] == 20: igor@46: print_stats(stats, weight, correct_answer) igor@46: stats['last_questions'] = 0 igor@46: stats['last_errors'] = 0 igor@46: igor@46: print igor@46: