-
Notifications
You must be signed in to change notification settings - Fork 0
/
voldemot_utils.py
106 lines (90 loc) · 4.22 KB
/
voldemot_utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
"""
voldemot_utils
Helper functions for voldemot package
"""
import asyncio
def readDictionary(filename):
""" reads words line by line from a file and returns them in a list """
wordFile = open(filename, "r")
wordList = [word.rstrip().lower() for word in wordFile if "'" not in word]
wordFile.close()
return wordList
def wordIsPresent(word, soup):
""" checks if the word can be assembled with the characters in the soup """
for letter in soup:
word = word.replace(letter, "", 1)
return not word
def getWordList(dictFileName, letters):
""" returns a list of words found in the letters string using the dictionary in the filename """
return [word for word in readDictionary(dictFileName) if wordIsPresent(word, letters)]
def getRootWords(dictionary, letters):
""" returns valid words from a dictionary """
return [k for k, v in dictionary.items() if wordIsPresent(k, letters)]
def getWordsEqualTo(wordList, targetLength):
""" return list of words of a specified length in the list """
return [word for word in wordList if len(word) == targetLength]
def getWordsUnder(wordList, targetLength):
""" return list of words of a specified length in the list """
return [word for word in wordList if len(word) < targetLength]
def printProgressBar(iteration, total, suffix='',
decimals=1, length=100, fill='█'):
"""
Call in a loop to create terminal progress bar
@params:
iteration - Required : current iteration (Int)
total - Required : total iterations (Int)
prefix - Optional : prefix string (Str)
suffix - Optional : suffix string (Str)
decimals - Optional : positive number of decimals in percent complete (Int)
length - Optional : character length of bar (Int)
fill - Optional : bar fill character (Str)
Credit: @greenstick
"""
percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
filledLength = int(length * iteration // total)
progressBar = fill * filledLength + '-' * (length - filledLength)
print(f" |{progressBar}| {percent}% {suffix}", end='\r')
# Print New Line on Complete
if iteration == total:
print()
async def findWordCombinations(wordsFound, letters, wordCount, pauseInterval = 10000, pauseLength = 0.05, verbose = False):
''' find 2+ word combinations '''
fullMatch = []
rootList = getWordsUnder(wordsFound, len(letters) - (wordCount - 2))
tempWords = rootList.copy()
lettersLength = len(letters)
pauseCount = pauseInterval
total = 0
percent = 0
for root in rootList:
# traverse the remainder of the list until it's all gone
prefixList = [root]
for baggageCounter in range(2, wordCount + 1):
newPrefixList = []
for prefix in prefixList:
lastPrefix = prefix.split(' ')[-1]
tempList = tempWords[tempWords.index(lastPrefix):]
collapsedPrefix = prefix.replace(" ", "")
spotsAvailable = lettersLength - len(collapsedPrefix)
if baggageCounter == wordCount:
for tempWord in getWordsEqualTo(tempList, spotsAvailable):
if sorted(collapsedPrefix + tempWord) == sorted(letters):
fullMatch.append(f"{prefix} {tempWord}")
else:
baggageLeft = spotsAvailable - (wordCount - baggageCounter - 1)
for tempWord in getWordsUnder(tempList, baggageLeft):
if wordIsPresent(collapsedPrefix + tempWord, letters):
newPrefixList.append(f"{prefix} {tempWord}")
pauseCount -= 1
if pauseCount == 0:
pauseCount = pauseInterval
await asyncio.sleep(pauseLength)
prefixList = newPrefixList.copy()
tempWords.remove(root)
if verbose:
total += 1
newPercent = int(total * 100 / len(rootList))
if newPercent != percent:
percent = newPercent
printProgressBar(total, len(rootList), length=50)
return fullMatch