2 Commits

  1. 36
      candidate_cache.py
  2. 1
      dictionary.py
  3. 28
      main.py

36
candidate_cache.py

@ -0,0 +1,36 @@
import itertools
from dictionary import Dictionary, DICTS
def make_key(dictionary_name, letters):
return (dictionary_name, frozenset(letters))
def candidates(letters, dictionary: Dictionary, min=2):
permutations = itertools.chain.from_iterable(
map(lambda r: itertools.permutations(letters, r), range(min, len(letters) + 1))
)
return dictionary.filter(map("".join, permutations))
class CandidateCache:
def __init__(self, maxsize=5):
self.maxsize = maxsize
self.cache = {}
self.keys = []
def get(self, dictionary_name, letters):
key = make_key(dictionary_name, letters)
try:
return self.cache[key]
except KeyError:
data = candidates(letters, DICTS[dictionary_name])
self.create(key, data)
return data
def create(self, key, data):
if len(self.keys) > self.maxsize:
key = self.keys.pop()
del self.cache[key]
self.keys.insert(0, key)
self.cache[key] = data

1
dictionary.py

@ -54,3 +54,4 @@ class Dictionary:
DEFAULT = Dictionary(default_load_future)
ALTERNATE = Dictionary(alternate_load_future)
DICTS = {"default": DEFAULT, "alt": ALTERNATE}

28
main.py

@ -1,19 +1,18 @@
#!/usr/bin/python3
from string import ascii_lowercase
import argparse
import itertools
import os
import re
import cmd2
from dictionary import DEFAULT, ALTERNATE
from candidate_cache import CandidateCache
from dictionary import DICTS
from word_remove_dialog import RemoveWordsActivity
LOWERCASE = set(ascii_lowercase)
DICTS = {"default": DEFAULT, "alt": ALTERNATE}
# argparsers
dictionary_manage_parser = argparse.ArgumentParser()
commands = dictionary_manage_parser.add_mutually_exclusive_group(required=True)
@ -47,16 +46,6 @@ commands.add_argument(
)
def candidates(letters, min=2):
possibilities = []
for length in range(min, len(letters) + 1):
for comb in itertools.combinations(letters, length):
for perm in itertools.permutations(comb):
word = "".join(perm)
possibilities.append(word)
return possibilities
class MainLoop(cmd2.Cmd):
"""Loop for wordscape commands
@ -69,7 +58,7 @@ class MainLoop(cmd2.Cmd):
self.excludes = set()
self.hidden = set()
self.init_letters(input("Enter letters: "))
self._candidates = None
self.cache = CandidateCache()
super().__init__()
def init_letters(self, letters):
@ -78,17 +67,14 @@ class MainLoop(cmd2.Cmd):
letters = letters.lower()
self.letters = [l for l in letters if l in LOWERCASE]
self.prompt = MainLoop.prompt.format(", ".join(self.letters))
self._candidates = None
@property
def candidates(self):
if self._candidates is None:
self._candidates = candidates(self.letters)
return self._candidates
return self.cache.get(self.dict, self.letters)
def filter(self, regex):
matching_pattern = filter(regex.match, self.candidates)
return DICTS[self.dict].filter(matching_pattern)
return set(filter(regex.match, self.candidates))
@cmd2.with_argparser(dictionary_manage_parser)
def do_dict(self, args):

Loading…
Cancel
Save