Skip to content

Commit

Permalink
tutors refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
baverman committed Jan 28, 2011
1 parent 9fdda82 commit fa39848
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 45 deletions.
45 changes: 8 additions & 37 deletions typetrainer/run.py
Expand Up @@ -2,66 +2,37 @@ def run():
import sys
from optparse import OptionParser

from typetrainer.generator import make_char_chain, generate_word


parser = OptionParser(usage="usage: %prog [options] file_with_words")
parser.add_option("-t", "--tutor", dest="tutor", default='en.basic',
help="Tutor maker to use (en.basic, ru.basic)", metavar="tutor")

options, args = parser.parse_args()

def get_chains(tutor, filename):
if not args:
parser.error('You should specify file with words to process')

def get_filler(tutor, filename):
package_name = 'typetrainer.tutors.' + tutor
try:
__import__(package_name)
except ImportError:
parser.error("Can't fint [%s] tutor" % tutor)
parser.error("Can't find [%s] tutor" % tutor)

pkg = sys.modules[package_name]

try:
words = list(pkg.split_to_words(open(filename).read().decode('utf-8')))
return pkg.get_filler(open(filename).read().decode('utf-8'), None)
except IOError:
parser.error("Can't read %s" % filename)

first, other = make_char_chain(words, 3)
lengths = list(pkg.make_lengths_seq(words))

return first, other, lengths

if not args:
parser.error('You should specify file with words to process')

first, other, lengths = get_chains(options.tutor, args[0])
parser.error("Can't read [%s]" % filename)

filler = get_filler(options.tutor, args[0])

import gtk
import random
import itertools
import collections

from typetrainer.ui import idle
from typetrainer.ui.main import Main
from typetrainer.ui.kbd import n130_keyboard, KeyboardDrawer

old_generated = collections.deque([], 100)

def filler():
pos = random.randint(0, len(lengths) - 1)
left = itertools.islice(lengths, pos, None)
right = itertools.islice(lengths, 0, pos)

for t, l in itertools.cycle(itertools.chain(left, right)):
if t == 'w':
word = generate_word(first, other, l, 3)
if word in old_generated:
word = generate_word(first, other, l, 3)
old_generated.append(word)
yield word
else:
yield l

app = Main(filler, KeyboardDrawer(n130_keyboard))
app.window.show()
idle(app.fill)
Expand Down
26 changes: 26 additions & 0 deletions typetrainer/tutors/common.py
@@ -0,0 +1,26 @@
import random
import collections
import itertools

from typetrainer.generator import make_char_chain, generate_word

class Filler(object):
def __init__(self, words, make_lengths_seq):
self.first, self.other = make_char_chain(words, 3)
self.lengths = list(make_lengths_seq(words))
self.old_generated = collections.deque([], 100)

def __iter__(self):
pos = random.randint(0, len(self.lengths) - 1)
left = itertools.islice(self.lengths, pos, None)
right = itertools.islice(self.lengths, 0, pos)

for t, l in itertools.cycle(itertools.chain(left, right)):
if t == 'w':
word = generate_word(self.first, self.other, l, 3)
if word in self.old_generated:
word = generate_word(self.first, self.other, l, 3)
self.old_generated.append(word)
yield word
else:
yield l
7 changes: 6 additions & 1 deletion typetrainer/tutors/en/basic.py
@@ -1,4 +1,5 @@
import re
from ..common import Filler

def make_lengths_seq(words):
for t, w in words:
Expand All @@ -21,4 +22,8 @@ def split_to_words(text):
for s in syms:
yield 's', s

yield 's', ' '
yield 's', ' '

def get_filler(text, options):
words = list(split_to_words(text))
return Filler(words, make_lengths_seq)
8 changes: 6 additions & 2 deletions typetrainer/tutors/ru/basic.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-

import re
from ..common import Filler

def make_lengths_seq(words):
for t, w in words:
Expand All @@ -23,4 +23,8 @@ def split_to_words(text):
for s in syms:
yield 's', s

yield 's', ' '
yield 's', ' '

def get_filler(text, options):
words = list(split_to_words(text))
return Filler(words, make_lengths_seq)
12 changes: 7 additions & 5 deletions typetrainer/ui/main.py
Expand Up @@ -7,7 +7,7 @@

RHITM_ERROR_THRESHOLD = 1.7
RHITM_ERROR_FACTOR = 3.0
ERROR_SINK_VALUE = 3.0
ERROR_SINK_VALUE = 2.0
TYPO_ERROR_FACTOR = 5.0

def attach_glade(obj, filename, *names):
Expand Down Expand Up @@ -56,7 +56,7 @@ def fill(self):
text = ''
d = entry.get_layout_offsets()[0] * 2

for w in self.filler():
for w in self.filler:
text += w

entry.set_text(text)
Expand Down Expand Up @@ -115,15 +115,17 @@ def collect_typo_errors(self, typed):

def add_error(self, pos, typed, idx, wfactor):
char = self.totype_text[pos]
if char == ' ':
return

def weight_func(key):
return 1.0/self.totype_text.count(char)

if typed[idx][0] and pos > 0 and self.totype_text[pos-1] != ' ':
key = self.totype_text[pos-1:pos+1]
self.errors[key] += weight_func(key)*wfactor
else:
key = self.totype_text[pos]

key = self.totype_text[pos]
self.errors[key] += weight_func(key)*wfactor

def sink_errors(self):
Expand All @@ -146,7 +148,7 @@ def on_type_entry_activate(self, *args):
self.collect_rhitm_errors(self.typed_chars)
self.collect_typo_errors(self.typed_chars)

#print sorted((r for r in self.errors.iteritems()), key=lambda r:r[1], reverse=True)[:5]
print sorted((r for r in self.errors.iteritems()), key=lambda r:r[1], reverse=True)[:5]
#print self.totype_text

self.accuracy_lb.set_text(
Expand Down

0 comments on commit fa39848

Please sign in to comment.