Skip to content
This repository was archived by the owner on Mar 31, 2020. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
a1cd5ef
Update README.md
Feb 22, 2019
163aaf3
Update README.md
Feb 22, 2019
d78531f
Added "[flake8]"
Feb 23, 2019
48cd97c
Added an ignore for a file added by the Pycharm interpreter
Feb 23, 2019
7b3901a
Added design document pdf to show how I see the project. Please comme…
jeepitou Feb 23, 2019
5b4e9d8
Basic structure for the contact class created.
mireglo Feb 23, 2019
19d384b
Modified the Contact.change_note method, since the code was the exact…
jeepitou Feb 23, 2019
32caa8e
Added the functionality for the change methods to act as remove metho…
mireglo Feb 23, 2019
6d7eaee
Created basic layout for the GUI; somewhat unfinished
Feb 23, 2019
833d90a
Changed position of settings button
Feb 23, 2019
2a093b1
Began implementing Contact Class & New Contact Page
Feb 24, 2019
00ea0cd
Elaborated on New Contact page; still unable to submit contact properly
Feb 24, 2019
7eca444
Added preview field for new contact page; added information field for…
Feb 24, 2019
94e34cf
Added preview field for new contact page; added information field for…
Feb 24, 2019
80a2a4a
Updated docstrings for each page
Feb 24, 2019
4e6852b
Updated docstrings for each page
Feb 24, 2019
ff4bf33
Testing implementations of ttk.Notebook
Feb 24, 2019
d53702b
Testing implementations of ttk.Notebook
Feb 24, 2019
132ae9a
Added title & icon
Feb 24, 2019
0b42d76
Updated docstrings
Feb 25, 2019
d7bb6f2
Made progress on creating contacts
Feb 25, 2019
68d54ac
Updated docstrings
Feb 25, 2019
b766e20
- Added a __str__ method to Contact class for debugging.
jeepitou Feb 25, 2019
4a5cfb4
Merge branch 'Testing-Tkinter-Notebooks'
Feb 25, 2019
1a8b6dd
Updated UI to use ttk.Notebook; added Icon & Title
Feb 25, 2019
5940528
Window size is set; added TODO; fixed spacing of some buttons
Feb 25, 2019
76ec824
Implemented load/save/delete functions
Feb 26, 2019
0edf797
Delete __init__.py
Feb 26, 2019
420cb5a
Implemented load/save/delete functions
Feb 26, 2019
772dd0f
- Added a __str__ method to Contact class for debugging.
jeepitou Feb 26, 2019
5c489e6
- Created PhoneNumber class, we now have a working rotary phone!
jeepitou Feb 26, 2019
9c88e13
Merge branch 'master' of https://github.com/patrick-yeadon/code-jam-4
Feb 26, 2019
41af7ea
Updated PhoneCanvas; Updated docstrings & show_info formatting in Con…
Feb 26, 2019
bf0571e
New Contact page preview now works, updated docstrings
Feb 27, 2019
9cb2210
Documented PhoneCanvas class
jeepitou Feb 27, 2019
3088436
Adjusted the AddPhoneNumberInter to make it a bit prettier
jeepitou Feb 27, 2019
2093772
Optimized the rotary phone. Added a timer to make the animation more …
jeepitou Feb 27, 2019
aa8e7b9
Merge pull request #1 from patrick-yeadon/optimizing_rotary_phone
jeepitou Feb 27, 2019
7d1cd52
Remove unused print statement.
jeepitou Feb 27, 2019
cce3349
New Contact page preview now works, updated docstrings
Feb 27, 2019
e1ad50d
Merge branch 'master' of https://github.com/patrick-yeadon/code-jam-4
Feb 27, 2019
75dfa6e
Modified PhoneNumberInput, user can not longer start dragging the but…
jeepitou Feb 28, 2019
129b766
Started work on Akinator-style letter guesser; created list of words/…
Feb 28, 2019
f1c3ee7
Merge branch 'master' of https://github.com/patrick-yeadon/code-jam-4
Feb 28, 2019
b57bc18
Documented AddPhoneNumberInter.
jeepitou Feb 28, 2019
18d0772
Documented PhoneNumberLabel.
jeepitou Feb 28, 2019
7dba1a1
Made the base spinning wheel. It spins and decelerate until it's comp…
jeepitou Feb 28, 2019
9507cc3
Spinning wheel is working. Need to make it a bit prettier and add a m…
jeepitou Feb 28, 2019
cb41c78
LetterGuesser Demo can guess your letter correctly!
Feb 28, 2019
0d06357
Merge branch 'master' of https://github.com/patrick-yeadon/code-jam-4
Feb 28, 2019
fd13908
Added a few notes to the demo
Feb 28, 2019
864ab5a
Optimized letter_guesser
Feb 28, 2019
fa49471
Optimized letter_guesser even more
Mar 1, 2019
9721bbc
Updated notes for Demo
Mar 1, 2019
36435a3
Added a erase command to spinning wheel to allow showing it and drawi…
jeepitou Mar 1, 2019
c685e49
Fully implemented WheelSpinner!
jeepitou Mar 1, 2019
87262e4
Merge pull request #20 from patrick-yeadon/implementing_wheel_spinner
jeepitou Mar 1, 2019
675710a
Fully implemented rotary phone number.
jeepitou Mar 1, 2019
ecb5049
Merge pull request #21 from patrick-yeadon/implementing_rotating_phone
jeepitou Mar 1, 2019
7b8edbd
Optimized a bit the AlphabetGuesser
jeepitou Mar 1, 2019
f708dc6
Made a very basic interface for the alphabet guesser. It needs to be …
jeepitou Mar 1, 2019
2feab1a
Updated the look of AlphabetGuesser; updated a few minor formatting e…
Mar 1, 2019
d6a4c83
Fixed the AlphabetGuesserInter to have the letters_input show.
jeepitou Mar 2, 2019
21cf61b
Modified the letter field to scroll on its own (not with the contact …
jeepitou Mar 2, 2019
12e4a5c
Updated the look of AlphabetGuesser
Mar 2, 2019
dd7790b
Added the randomized alphabetical order. It's awesome.
jeepitou Mar 2, 2019
d1487ea
Merge remote-tracking branch 'origin/master'
jeepitou Mar 2, 2019
5934133
Implemented AlphabetGuesser.
jeepitou Mar 2, 2019
ac6cbcd
Cleaned a bit of code. Time to go to bed.
jeepitou Mar 2, 2019
3eb9a82
Fixed a few bugs here and there, fixed some PEP8 violations
Mar 2, 2019
ad261de
Fixed file loading; now using 'pipenv run start' to run the program
Mar 2, 2019
8658be4
Updated formatting to fit linting; oh boy we should have been aware o…
Mar 3, 2019
14d5f47
Update README.md
Mar 3, 2019
f882864
Update README.md
Mar 3, 2019
1ecd91a
Modified the code so that pipenv run start generates the pickle. Modi…
jeepitou Mar 3, 2019
2fa3536
Linted the formatting.
jeepitou Mar 3, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[flake8]
max-line-length=100
application_import_names=projectt
ignore=P102,B311,W503,E226,S311,W504,F821
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,6 @@ venv.bak/

# mypy
.mypy_cache/

# Ignores for Pycharm Interpreter
.idea/
6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added Design document/Design document.pdf
Binary file not shown.
3 changes: 2 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ flake8 = "*"
python_version = "3.7"

[scripts]
lint = "python -m flake8"
start = "python -m project"
lint = "python -m flake8"
12 changes: 6 additions & 6 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 14 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,26 @@ You should be using [Pipenv](https://pipenv.readthedocs.io/en/latest/). Take a l

# Project Information

`# TODO`
Team: Durable Drills

## Description

`# TODO`
Keep track of your contact information using the Durable Drills Contact Manager™.

## Setup & Installation

`# TODO`
Assuming you are using pipenv, "pipenv run start" should make the program work!

## How do I use this thing?

`# TODO`
Using the Contact Manager is simple:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've written documentation, which is great!

- To load in your current contacts, press 'Load Contacts' in the 'View Contacts' tab
- To save your current list of contacts, press 'Save Contacts'
- To view the information of a specific contact, select that contact and press 'Show Info', then spin the Wheel™ to determine what info you can see
- To delete a specific contact, select that contact then press 'Delete'

- To create a new contact, go to the 'New Contact' tab and enter your contacts information:
- For text entries, like the contact Name, Address, Email, and Notes, answer the questions provided by the EntryBot3000™
- For numerical entries, like the Phone Number, use the provided rotary phone, then select the type of phone number: Personal, Work, or Home.
- For all entries, you need to press the accompanying 'Add' button to add that information to the preview window; when the preview looks the way you want it, press 'Submit to Contacts'.
- To clear all entries, press 'Clear'
156 changes: 156 additions & 0 deletions project/AlphabetGuesser/AlphabetGuesserInter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import tkinter as tk
from tkinter import N, S, E, W
from random import randint
from project.AlphabetGuesser.letter_guesser import LetterGuesser


class AlphabetGuesserInter(tk.Frame):

def __init__(self, master, current_entry, *args, **kwargs):
super().__init__(master, *args, **kwargs)
self.master = master
self.letter_guesser = LetterGuesser()

self.current_entry = current_entry
self.current_entry_label = None
self.letters_input = None
self.header = None
self.description = None
self.title_label = None
self.current_letter_id = 1
self.question_label = None
self.current_word = None
self.button_1 = None
self.button_2 = None
self.submit_button = None

self.__letter_found = False

self.create()

def create(self):
self.header = tk.Label(self, text="EntryBot 3000", font="Calibri 20")
self.description = tk.Label(self, text="The latest in typing technology since 700 B.C\n\n",
font="Calibri 10")

self.title_label = tk.Label(self,
text="You are entering {} {}:\nAnswer the questions below to"
"fill out the entry\n"
.format(self.get_prefix(self.current_entry),
self.current_entry),
font="Calibri 11")
self.question_label = tk.Label(self,
text="Is your {} character contained in the phrase :"
"".format(self.complete_number(self.current_letter_id)),
font="Calibri 11")

self.current_word = tk.Label(self, font="Calibri 18", relief="sunken")
self.update_current_asked_word()

self.button_1 = tk.Button(self, command=lambda: self.send_answer(self.button_1['text']))
self.button_2 = tk.Button(self, command=lambda: self.send_answer(self.button_2['text']))
self.button_1.config(font="Calibri 15")
self.button_2.config(font="Calibri 15")
self.randomize_buttons()

self.current_entry_label = tk.Label(self, text=self.current_entry + " :", font="Calibri 12")
self.letters_input = tk.Label(self, relief="sunken", font="Calibri 15")

self.submit_button = tk.Button(self, text="Submit", font="Calibri 15",
command=lambda: self.submit())

self.header.grid(row=0, column=0, columnspan=2, sticky=N + S + E + W)
self.description.grid(row=1, column=0, columnspan=2, sticky=N + S + E + W)

self.title_label.grid(column=0, row=2, columnspan=2, sticky=N + S + E + W)
self.question_label.grid(column=0, row=3, columnspan=2, sticky=N + S + E + W)
self.current_word.grid(column=0, row=4, columnspan=2, padx=10, pady=10,
sticky=N + S + E + W)

self.button_1.grid(column=0, row=5, sticky=N + S + E + W)
self.button_2.grid(column=1, row=5, sticky=N + S + E + W)

self.current_entry_label.grid(column=0, row=6, columnspan=2, sticky=N + S + E + W)
self.letters_input.grid(column=0, row=7, columnspan=2, padx=10, sticky=N + S + E + W)
self.submit_button.grid(column=0, row=8, columnspan=2, padx=10, pady=10,
sticky=N + S + E + W)

self.grid(row=0, column=0)

def update_current_asked_word(self):
self.current_word['text'] = '"' + self.letter_guesser.request_word() + '"'

def send_answer(self, answer):
if self.__letter_found and answer == "Yes":
self.current_letter_id += 1
if self.question_label['text'] == "I found your character! Continue?":
self.question_label['text'] = "Is your {} character contained in the phrase :"\
"".format(self.complete_number(self.current_letter_id))
self.restart_letter_guesser()
return
elif self.__letter_found and answer == "No":
# Return the current output and go back to the main window
self.submit()
return
self.letter_guesser.answer(self.current_word['text'], answer)
self.randomize_buttons()

print(self.letter_guesser.possible_characters)
if len(self.letter_guesser.possible_characters) == 1:
self.letter_found()
else:
self.update_current_asked_word()

def letter_found(self):
self.question_label['text'] = "I found your character! Continue?"
self.current_word['text'] = self.letter_guesser.possible_characters[0].upper()
if len(self.letters_input['text']) == 0 or self.letters_input['text'][-1] == " ":
self.letters_input['text'] += self.letter_guesser.possible_characters[0].upper()
else:
self.letters_input['text'] += self.letter_guesser.possible_characters[0]
self.__letter_found = True

def randomize_buttons(self):
if randint(0, 1) == 1:
self.button_1['text'] = 'Yes'
self.button_2['text'] = 'No'
else:
self.button_1['text'] = 'No'
self.button_2['text'] = 'Yes'

def get_answer(self):
return self.letters_input['text']

def submit(self):
self.master.event_generate("<<Info Submitted>>")
print("Submitted")

@staticmethod
def get_prefix(word):
if word[0] in ['A', 'E', 'I', 'O', 'U']:
return 'an'
return 'a'

@staticmethod
def complete_number(number):
if number == 1:
return '1st'
elif number == 2:
return '2nd'
elif number == 3:
return '3rd'
else:
return str(number) + 'th'

def restart_letter_guesser(self):
self.letter_guesser.__init__()
self.update_current_asked_word()
self.__letter_found = False


if __name__ == '__main__':
root = tk.Tk()
root.geometry("300x400")
root.resizable(False, False)
a = AlphabetGuesserInter(root, "Name", width=300, height=500)
root.mainloop()
30 changes: 30 additions & 0 deletions project/AlphabetGuesser/create_dictionary.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import pickle


def create_dictionary() -> None:
"""
Reads each word from a file with the format of words.txt & determines what letters comprise each
word; saved into a dictionary in the following format:
{'apple': [a, e, l, p], 'banana': [a, b, n], ...etc}
Finally, the created dictionary is saved as a pickle
:return: None
"""
dictionary = {}
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '@', '.', '-', ' ', '?', '!']
with open('project/Alphabetguesser/words.txt') as f:
for word in f:
word = word[:len(word) - 1]
letters = []
for letter in alphabet:
if letter in word:
letters.append(letter)
dictionary[word] = letters
f.close()
with open("project/AlphabetGuesser/words_pickle", 'wb') as outfile:
pickle.dump(dictionary, outfile)


if __name__ == '__main__':
create_dictionary()
115 changes: 115 additions & 0 deletions project/AlphabetGuesser/letter_guesser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import pickle
import random


class LetterGuesser:
"""
LetterGuesser:

=== Public Attributes ===
dictionary
possible_characters

=== Methods === request_word: returns a random word from the dictionary
remove_possible_letters: removes all characters from possible_characters that are not
contained in the given word/phrase remove_possible_words: removes all words/phrases from
dictionary that contain none of the characters in the given word/phrase
contains_none_letters: Returns True only if none the letters in word_2 are contained in word_1
answer: Handles the user's answer of either "Yes" or "No"
"""
def __init__(self):
self.dictionary = None
self.possible_characters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '@', '.', '-',
' ', '?', '!']
with open("project/alphabetguesser/words_pickle", "rb") as openfile:
self.dictionary = pickle.load(openfile)
openfile.close()

def answer(self, requested_word, answer):
"""
Handles the user's answer for a given word
:param requested_word: The context of the user's answer
:param answer: string that should be either "Yes" or "No"; the program will not respond to
anything else
:return: None
"""
self.remove_possible_letters(requested_word, answer)
self.remove_possible_words()

def request_word(self) -> str:
words = list(self.dictionary.keys())
random.shuffle(words)
for word in words:
if self.find_ratio_of_remaining_letter_in_word(word) > 30:
return word
return random.choice(words)

def remove_possible_letters(self, word, answer) -> None:
characters_to_delete = []
for character in self.possible_characters:
if character not in word and answer == "Yes":
characters_to_delete.append(character)
elif character in word and answer == "No":
characters_to_delete.append(character)
for character in characters_to_delete:
self.possible_characters.remove(character)

def remove_possible_words(self) -> None:
words_to_delete = []
for elem in self.dictionary:
if self.contains_none_letters(elem, self.possible_characters) or \
self.contains_all_letters(self.possible_characters, elem):
words_to_delete.append(elem)
# if a word contains none of the possible letters, remove it
for elem in words_to_delete:
del self.dictionary[elem]

def find_ratio_of_remaining_letter_in_word(self, word):
i = 0
for letter in self.possible_characters:
if letter in word:
i += 1

return i/len(word)*100

@staticmethod
def contains_none_letters(word_1, word_2) -> bool:
for letter in word_1:
if letter in word_2:
return False
return True

@staticmethod
def contains_all_letters(word_1, word_2) -> bool:
for letter in word_1:
if letter not in word_2:
return False
return True


if __name__ == '__main__':
"""
This is a simple demo showing how the letter guesser should be implemented
"""

guesser = LetterGuesser()
question_num = 1
print('Pick a character, any character; keep it in mind as you answer these questions!\n')
while True:
word = guesser.request_word()
yes_no = input('Question #{0}:\nIs your character in the word/phrase:\n{1}\n(Yes/No):'
.format(question_num, word))
if yes_no == "Quit":
break
question_num += 1
guesser.answer(word, yes_no)
print('Possible characters:', guesser.possible_characters)
print('Words left to pick from:', len(list(guesser.dictionary)))
if len(guesser.possible_characters) == 1:
print('The character you want is \'{0}\''.format(guesser.possible_characters[0]))
break
if len(guesser.possible_characters) < 1:
print('A mistake has been made; try again')
break
Loading