Skip to content

Commit

Permalink
Fixed letters to only accept alpha characters, and convert them to up…
Browse files Browse the repository at this point in the history
…per case.

Made app load GUI and push it to screen before loading letters, to give a smoother load-up experience. Also added logic to disable all controls on the screen during loading / processing, to further make it clear when the app is working.
Finally, went through and fixed some formatting issues that were bugging me.
The diff on this commit is a mess because I didn't do this in stages like a good programmer would.
  • Loading branch information
Levtastic committed Nov 28, 2016
1 parent 2e1b8af commit 50ed4a5
Showing 1 changed file with 94 additions and 66 deletions.
160 changes: 94 additions & 66 deletions countdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,115 +5,143 @@
import collections
import webbrowser


class Countdown():
def __init__(self):
with open(self._resource_path('words.txt')) as f:
words = [word.strip().lower() for word in f.readlines()]

self.words = dict(zip(words, [collections.Counter(word) for word in words]))

app_name = 'Countdown Tool'

app_name = 'Countdown'

self.root = root = tk.Tk()
root.title(app_name)
root.geometry('345x315')
root.minsize(345, 315)
self._layout(root)
root.iconbitmap(self._resource_path('icon.ico'))


root.after_idle(self._load_words)

root.mainloop()


def _resource_path(self, relative):
if getattr(sys, 'frozen', False):
basedir = sys._MEIPASS
else:
basedir = os.path.dirname(__file__)

return os.path.join(basedir, relative)

def _load_words(self):
self.root.config(cursor='wait')
self._set_all_states(tk.DISABLED)
self.root.update()

with open(self._resource_path('words.txt')) as f:
words = [word.strip().lower() for word in f.readlines()]

self.words = dict(zip(words, [collections.Counter(word) for word in words]))

self.root.config(cursor='')
self._set_all_states(tk.NORMAL)

def _set_all_states(self, state, widget=None):
if widget is None:
widget = self.root

if 'state' in widget.config():
widget.configure(state=state)
return

for child in widget.winfo_children():
self._set_all_states(state, child)

def _layout(self, root):
layoutFont = tkFont.Font(size = 18, weight = 'bold')
resultsFont = tkFont.Font(size = 12)
layoutFont = tkFont.Font(size=18, weight='bold')
resultsFont = tkFont.Font(size=12)

f = ttk.Frame(root)
f.pack(side = tk.TOP, fill = tk.X)

l = ttk.Label(f, text = 'Letters:', font = layoutFont)
l.pack(side = tk.TOP, anchor = tk.W)

eLetters = tk.Entry(f, font = layoutFont, validate = 'key')
vcmd = eLetters.register(self.validate_input)
eLetters.config(validatecommand = (vcmd, '%d', '%S'))
eLetters.pack(side = tk.TOP, fill = tk.X, expand = True)
f.pack(side=tk.TOP, fill=tk.X)

l = ttk.Label(f, text='Letters:', font=layoutFont)
l.pack(side=tk.TOP, anchor=tk.W)

sv = tk.StringVar()
sv.trace('w', lambda name, index, mode, sv=sv: self._on_text_changed(sv))
eLetters = tk.Entry(f, textvariable=sv, font=layoutFont, validate='key')
vcmd = eLetters.register(self._validate_input)
eLetters.config(validatecommand=(vcmd, '%d', '%S'))
eLetters.pack(side=tk.TOP, fill=tk.X, expand=True)
eLetters.bind('<Control-a>', self._select_all)
eLetters.focus()
bCalculate = tk.Button(f, text = 'Calculate', font = layoutFont)
bCalculate.pack(side = tk.TOP, anchor = tk.W, fill = tk.X, expand = True)
l = ttk.Label(f, text = 'Results:', font = layoutFont)
l.pack(side = tk.TOP, anchor = tk.W)

bCalculate = tk.Button(f, text='Calculate', font=layoutFont)
bCalculate.pack(side=tk.TOP, anchor=tk.W, fill=tk.X, expand=True)

l = ttk.Label(f, text='Results:', font=layoutFont)
l.pack(side=tk.TOP, anchor=tk.W)

f = ttk.Frame(root)
f.pack(side = tk.TOP, fill = tk.BOTH, expand = True)
sb = ttk.Scrollbar(f, orient = tk.VERTICAL)
lResults = tk.Listbox(f, selectmode = tk.EXTENDED, yscrollcommand = sb.set, font = resultsFont)
sb.config(command = lResults.yview)
lResults.pack(side = tk.LEFT, fill = tk.BOTH, expand = True)
sb.pack(side = tk.RIGHT, fill = tk.Y)
f.pack(side=tk.TOP, fill=tk.BOTH, expand=True)

sb = ttk.Scrollbar(f, orient=tk.VERTICAL)
lResults = tk.Listbox(f, selectmode=tk.EXTENDED, yscrollcommand=sb.set, font=resultsFont)
sb.config(command=lResults.yview)
lResults.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
sb.pack(side=tk.RIGHT, fill=tk.Y)

lResults.bind('<Double-Button-1>', self._double_click)

calc = lambda x=None: self._show_results(eLetters, lResults)
bCalculate.configure(command = calc)
bCalculate.configure(command=calc)
eLetters.bind('<Return>', calc)
def validate_input(self, action, key):
if action == '1' and key not in 'abcdefghijklmnopqrstuvwxyz':
return False
return True

def _on_text_changed(self, sv):
sv.set(sv.get().upper())

def _validate_input(self, action, key):
return action != '1' or key.isalpha()

def _select_all(self, event):
event.widget.select_range(0, tk.END)
return 'break'

def _double_click(self, event):
widget = event.widget
selection = widget.curselection()
if not selection:
return

value = widget.get(selection[0]).split(' ', 1)[1]

webbrowser.open('https://www.google.com/search?q=define+' + value, 2)

def _show_results(self, eLetters, lResults):
self.root.config(cursor = 'wait')
self.root.config(cursor='wait')
self._set_all_states(tk.DISABLED)
self.root.update()


lResults.config(state=tk.NORMAL)
lResults.delete(0, 'end')

for result in self._calculate(eLetters.get().strip()):
lResults.insert('end', '(%d) %s' % (len(result), result))

self.root.config(cursor = '')


self.root.config(cursor='')
self._set_all_states(tk.NORMAL)

def _calculate(self, letters):
if not letters:
return []

results = []
letters = collections.Counter(letters.lower())

for word, word_letters in self.words.items():
difference = collections.Counter(letters)
difference.subtract(word_letters)
if not any(val < 0 for val in difference.values()):
results.append(word)

return sorted(results, key = len, reverse = True)

def _resource_path(self, relative):
if getattr(sys, 'frozen', False):
basedir = sys._MEIPASS
else:
basedir = os.path.dirname(__file__)

return os.path.join(basedir, relative)
return sorted(results, key=len, reverse=True)


if __name__ == '__main__':
Countdown()

0 comments on commit 50ed4a5

Please sign in to comment.