koch-method-real-words/mk_lessons.py

72 wiersze
2.6 KiB
Python

import random
import re
def filter_initial(letters, wordlist):
regexp = re.compile(f"[{''.join(letters)}]+")
return [w for w in wordlist if regexp.fullmatch(w)]
def filter(new_letter, old_letters, wordlist):
regexp = re.compile(f"[{''.join(old_letters)}]*{new_letter}[{new_letter}{''.join(old_letters)}]*")
return [w for w in wordlist if regexp.fullmatch(w)]
class WordLottery:
"""This word lottery makes it 20 x less probable
to again draw a word that had already been drawn previously."""
def __init__(self, words):
self.words = words.copy()
self.sub = None
def add(self, word):
self.words.append(word)
def lots(self):
if self.sub:
return len(self.words) + self.sub.lots() / 20
else:
return len(self.words)
def draw(self):
lots = self.lots()
r = random.random()
if r * lots < len(self.words):
draw_i = random.randrange(0, len(self.words))
result_word = self.words[draw_i]
del self.words[draw_i:draw_i+1]
if not self.sub:
self.sub = WordLottery([result_word])
else:
self.sub.add(result_word)
return result_word
else:
if self.sub:
return self.sub.draw()
else:
raise RuntimeError("This was not supposed to happen. r: {r}, lots: {lots}, self.words: {len(self.words}.")
def write_words(filtered, outdir, outname, words_per_lesson, blanks):
lottery = WordLottery(filtered)
with open(f"{outdir}/{outname}", "w") as out:
for _ in range(0, words_per_lesson):
out.write(lottery.draw())
out.write(blanks)
out.write("\n")
def mk_lessons(wordlist, learn_order, outdir, words_per_lesson = 50, blanks=" "):
for lesson_name in learn_order.keys():
if "new_letter" in learn_order[lesson_name]:
old_letters = learn_order[lesson_name]['old_letters']
new_letter = learn_order[lesson_name]['new_letter']
filtered = filter(new_letter, old_letters, wordlist)
else:
letters = learn_order[lesson_name]['letters']
filtered = filter_initial(letters, wordlist)
if "new_words" in learn_order[lesson_name]:
if learn_order[lesson_name]["new_words"] != len(filtered):
raise RuntimeError(f"Lesson {lesson_name}: Wrong word count should: {learn_order[lesson_name]['new_words']} is: {len(filtered)}.")
for i in range(0, 10):
write_words(filtered, outdir, f"{lesson_name}_{i}.txt", words_per_lesson, blanks)