# remaining words. See --mode=PRECOMPUTE for how to populate.
self.position_hash = {}
filename = config.config['hash_file']
- if filename is not None and file_utils.file_is_readable(filename):
+ if filename is not None and file_utils.is_readable(filename):
logger.debug(f'Initializing position hash from {filename}...')
with open(filename, 'r') as rf:
for line in rf:
# All legal solutions pre-sorted by length.
self.all_possible_solutions_by_length = defaultdict(list)
filename = config.config['solutions_file']
- if filename is not None and file_utils.file_is_readable(filename):
+ if filename is not None and file_utils.is_readable(filename):
logger.debug(f'Initializing valid solution word list from {filename}...')
with open(filename) as rf:
for word in rf:
# All legal guesses pre-sorted by length.
self.all_possible_guesses_by_length = defaultdict(list)
filename = config.config['guesses_file']
- if filename is not None and file_utils.file_is_readable(filename):
+ if filename is not None and file_utils.is_readable(filename):
logger.debug(f'Initializing legal guess word list from {filename}...')
with open(filename) as rf:
for word in rf:
def get_max_letter_population() -> Dict[Letter, int]:
filename = config.config['solutions_file']
max_letter_population_per_word: Dict[Letter, int] = defaultdict(int)
- if filename is not None and file_utils.file_is_readable(filename):
+ if filename is not None and file_utils.is_readable(filename):
logger.debug(
'Figuring out all letters\' max frequency in the solution space...'
)
if line_transformers is not None:
for x in line_transformers:
xforms.append(x)
- if not file_is_readable(filename):
+ if not is_readable(filename):
raise Exception(f"{filename} can't be read.")
with open(filename) as rf:
for line in rf:
Returns:
True if filename exists and is a normal file.
- See also :meth:`create_path_if_not_exist`, :meth:`file_is_readable`.
+ See also :meth:`create_path_if_not_exist`, :meth:`is_readable`.
>>> does_file_exist(__file__)
True
return os.path.exists(filename) and os.path.isfile(filename)
-def file_is_readable(filename: str) -> bool:
+def is_readable(filename: str) -> bool:
"""Is the file readable?
Args:
True if the file exists, is a normal file, and is readable
by the current process. False otherwise.
- See also :meth:`does_file_exist`, :meth:`file_is_writable`,
- :meth:`file_is_executable`.
+ See also :meth:`does_file_exist`, :meth:`is_writable`,
+ :meth:`is_executable`.
"""
- return does_file_exist(filename) and os.access(filename, os.R_OK)
+ return os.access(filename, os.R_OK)
-def file_is_writable(filename: str) -> bool:
+def is_writable(filename: str) -> bool:
"""Is the file writable?
Args:
True if file exists, is a normal file and is writable by the
current process. False otherwise.
- See also :meth:`file_is_readable`, :meth:`does_file_exist`.
+ See also :meth:`is_readable`, :meth:`does_file_exist`.
"""
- return does_file_exist(filename) and os.access(filename, os.W_OK)
+ return os.access(filename, os.W_OK)
-def file_is_executable(filename: str) -> bool:
+def is_executable(filename: str) -> bool:
"""Is the file executable?
Args:
True if file exists, is a normal file and is executable by the
current process. False otherwise.
- See also :meth:`does_file_exist`, :meth:`file_is_readable`,
- :meth:`file_is_writable`.
+ See also :meth:`does_file_exist`, :meth:`is_readable`,
+ :meth:`is_writable`.
"""
- return does_file_exist(filename) and os.access(filename, os.X_OK)
+ return os.access(filename, os.X_OK)
def does_directory_exist(dirname: str) -> bool:
filename = cls.get_filename()
if cls.should_we_load_data(filename):
logger.debug("Attempting to load state from %s", filename)
- assert file_utils.file_is_readable(filename)
+ assert file_utils.is_readable(filename)
import pickle
from pyutils.files import file_utils
cfg = config.add_commandline_args(
- f'Unscrambler base library ({__file__})', 'A fast word unscrambler.'
+ f"Unscrambler base library ({__file__})", "A fast word unscrambler."
)
cfg.add_argument(
"--unscrambler_default_indexfile",
fprint_mask = (2**fprint_bits - 1) << letters_bits
fprint_feature_bit = {
- 'e': 0,
- 'i': 2,
- 'a': 4,
- 'o': 6,
- 'r': 8,
- 'n': 10,
- 't': 12,
- 's': 14,
- 'l': 16,
- 'c': 18,
- 'u': 20,
- 'p': 22,
- 'm': 24,
- 'd': 26,
- 'h': 28,
- 'y': 30,
- 'g': 32,
- 'b': 34,
- 'f': 36,
- 'v': 38,
- 'k': 40,
- 'w': 42,
- 'z': 44,
- 'x': 46,
- 'q': 48,
- 'j': 50,
+ "e": 0,
+ "i": 2,
+ "a": 4,
+ "o": 6,
+ "r": 8,
+ "n": 10,
+ "t": 12,
+ "s": 14,
+ "l": 16,
+ "c": 18,
+ "u": 20,
+ "p": 22,
+ "m": 24,
+ "d": 26,
+ "h": 28,
+ "y": 30,
+ "g": 32,
+ "b": 34,
+ "f": 36,
+ "v": 38,
+ "k": 40,
+ "w": 42,
+ "z": 44,
+ "x": 46,
+ "q": 48,
+ "j": 50,
}
letter_sigs = {
- 'a': 1789368711,
- 'b': 3146859322,
- 'c': 43676229,
- 'd': 3522623596,
- 'e': 3544234957,
- 'f': 3448207591,
- 'g': 1282648386,
- 'h': 3672791226,
- 'i': 1582316135,
- 'j': 4001984784,
- 'k': 831769172,
- 'l': 1160692746,
- 'm': 2430986565,
- 'n': 1873586768,
- 'o': 694443915,
- 'p': 1602297017,
- 'q': 533722196,
- 'r': 3754550193,
- 's': 1859447115,
- 't': 1121373020,
- 'u': 2414108708,
- 'v': 2693866766,
- 'w': 748799881,
- 'x': 2627529228,
- 'y': 2376066489,
- 'z': 802338724,
+ "a": 1789368711,
+ "b": 3146859322,
+ "c": 43676229,
+ "d": 3522623596,
+ "e": 3544234957,
+ "f": 3448207591,
+ "g": 1282648386,
+ "h": 3672791226,
+ "i": 1582316135,
+ "j": 4001984784,
+ "k": 831769172,
+ "l": 1160692746,
+ "m": 2430986565,
+ "n": 1873586768,
+ "o": 694443915,
+ "p": 1602297017,
+ "q": 533722196,
+ "r": 3754550193,
+ "s": 1859447115,
+ "t": 1121373020,
+ "u": 2414108708,
+ "v": 2693866766,
+ "w": 748799881,
+ "x": 2627529228,
+ "y": 2376066489,
+ "z": 802338724,
}
self.words = []
filename = Unscrambler.get_indexfile(indexfile)
- with open(filename, 'r') as rf:
+ with open(filename, "r") as rf:
lines = rf.readlines()
for line in lines:
line = line[:-1]
- (fsig, word) = line.split('+')
+ (fsig, word) = line.split("+")
isig = int(fsig, 16)
self.sigs.append(isig)
self.words.append(word)
The current indexfile location
"""
if indexfile is None:
- if 'unscrambler_default_indexfile' in config.config:
- indexfile = config.config['unscrambler_default_indexfile']
+ if "unscrambler_default_indexfile" in config.config:
+ indexfile = config.config["unscrambler_default_indexfile"]
assert type(indexfile) == str
else:
indexfile = "/usr/share/dict/sparse_index"
else:
- assert file_utils.file_is_readable(indexfile), f"Can't read {indexfile}"
+ assert file_utils.is_readable(indexfile), f"Can't read {indexfile}"
return indexfile
# 52 bits
@staticmethod
def repopulate(
- dictfile: str = '/usr/share/dict/words',
- indexfile: str = '/usr/share/dict/sparse_index',
+ dictfile: str = "/usr/share/dict/words",
+ indexfile: str = "/usr/share/dict/sparse_index",
) -> None:
"""
Repopulates the indexfile.
seen = set()
with open(dictfile, "r") as f:
for word in f:
- word = word.replace('\n', '')
+ word = word.replace("\n", "")
word = word.lower()
sig = Unscrambler.compute_word_sig(word)
logger.debug("%s => 0x%x", word, sig)
words_by_sigs[sig] += f",{word}"
else:
words_by_sigs[sig] = word
- with open(indexfile, 'w') as f:
+ with open(indexfile, "w") as f:
for sig in sorted(words_by_sigs.keys()):
word = words_by_sigs[sig]
- print(f'0x{sig:x}+{word}', file=f)
+ print(f"0x{sig:x}+{word}", file=f)
def lookup(self, word: str, *, window_size: int = 5) -> Dict[str, bool]:
"""Looks up a potentially scrambled word optionally including near