Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Carmen and Nina - C18 Cheetahs #78

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# AdaGrams

#Pair Plan!
Learning styles: We both learn by doing. Once we learn a concept, we learn by applying.
Prefer receiving feedback like: Upfront, honest, straightforward
Communication skills we want to improve: Communicating ideas more, speaking up more
After Tuesday afternoon co-working, we'll check in about progress and sync up schedules if needed and consider office hours if need. If we're really stuck or struggling then we should ask for help!
Comment on lines +3 to +7

Choose a reason for hiding this comment

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

Fantastic plan!


## Skills Assessed

- Following directions and reading comprehension
Expand Down
123 changes: 119 additions & 4 deletions adagrams/game.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,126 @@
import random

def draw_letters():
pass
# Import random - assign the randomized number to the index
# "bag" of letters will be a dictionary as shown below
# hand will be a list
# | A : 9 | N : 6 |
# | B : 2 | O : 8 |
# | C : 2 | P : 2 |
# | D : 4 | Q : 1 |
# | E : 12 | R : 6 |
# | F : 2 | S : 4 |
# | G : 3 | T : 6 |
# | H : 2 | U : 4 |
# | I : 9 | V : 2 |
# | J : 1 | W : 2 |
# | K : 1 | X : 1 |
# | L : 4 | Y : 2 |
# | M : 2 | Z : 1 |
bag_of_letters_dict = {
'A': 9,
'B': 2,
'C': 2,
'D': 4,
'E': 12,
'F': 2,
'G': 3,
'H': 2,
'I': 9,
'J': 1,
'K': 1,
'L': 4,
'M': 2,
'N': 6,
'O': 8,
'P': 2,
'Q': 1,
'R': 6,
'S': 4,
'T': 6,
'U': 4,
'V': 2,
'W': 2,
'X': 1,
'Y': 2,
'Z': 1
}
bag_of_letters_list = []
for key, value in bag_of_letters_dict.items():
for letter in range(value):
bag_of_letters_list.append(key)
Comment on lines +49 to +51

Choose a reason for hiding this comment

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

Great way to generate the bag of letters!


hand = []

while len(hand) < 10:
for letter in bag_of_letters_list:
hand.append(letter)
letter_of_index = bag_of_letters_list.index(letter)
bag_of_letters_list.pop(letter_of_index)
break
return hand
Comment on lines +55 to +61

Choose a reason for hiding this comment

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

This is really close to a working solution, but it will always produce the same list of letters (['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B']). The primary issue is that there is no randomization in this solution. The while loop will run 10 times, and each time through the loop, the inner loop runs once. The inner loop will start with the first letter in bag_of_letters_list, append that letter to hand, remove the letter from the list, and then break out of the inner loop. This has the effect of appending the first letter from the list 10 times, which results in a hand of 9 'A's and 1 'B'.
To generate a random hand of letters, instead of the for loop on line 56, you could use something like random.randint(0,len(bag_of_letters)) to pick a random index in the list. The letter at that index would be added to the hand and then removed from bag_of_letters_list with pop. (random.randint)


def uses_available_letters(word, letter_bank):
pass
true_false = []
word = word.upper()
word_list = []

for letter in word:
word_list.append(letter)
if letter in letter_bank and word_list.count(letter) == letter_bank.count(letter):

Choose a reason for hiding this comment

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

This passes our tests, but there is a bug here. If letter_bank has multiple copies of the same letter, even if all of those letters are used in the word, the first time this loop tests one of those letters, this conditional will be False, because the count in word_list will be less than the count in letter_bank. Consider this examples:

  • word = "dog" and letter_bank = ['d', 'o', 'o', 'g', 'x', 'x', 'x', 'x', 'x', 'x']. The second iteration through this loop, 'o' will be added to word_list, but there will only be one 'o' in word list, so the count here will not be equal.
    Changing the conditional to <= would fix this issue, because then it would be checking if there are enough letters in letter_bank, rather than the exact same number.
Suggested change
if letter in letter_bank and word_list.count(letter) == letter_bank.count(letter):
if letter in letter_bank and word_list.count(letter) <= letter_bank.count(letter):

true_false.append(True)
else:
true_false.append(False)
Comment on lines +72 to +73

Choose a reason for hiding this comment

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

There is a possible short circuit here. If the code ever reaches this point, the word is not valid, so it's possible to just return False here, rather than continuing to check all of the letters.

Suggested change
else:
true_false.append(False)
else:
return False

if False in true_false:
return False
else:
return True

def score_word(word):
pass
scoreboard = {
1 : "A, E, I, O, U, L, N, R, S, T",
2 : "D, G",
3 : "B, C, M, P",
4 : "F, H, V, W, Y",
5 : "K",
8 : "J, X",
10 : "Q, Z"
}
word = word.upper()
#- If the length of the word is 7, 8, 9, or 10,
# then the word gets an additional 8 points
score = 0
for letter in word:
for key, value in scoreboard.items():
if letter in value:
score += key

Choose a reason for hiding this comment

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

This is nominally an O(n) solution, but only because the inner loop is not growing in relation to the input size. For every letter in word, this solution will have to loop through all of the letters in scoreboard in order to find the right key-value pair. This doesn't take advantage of dictionary lookup as an O(1) operation. Using a scoreboard dictionary where each letter is a key and the value is the point value would result in a more efficient solution, because then there would be no need for an inner loop (scoreboard[letter] would return the value for the letter). In the worst case scenario, if all of the letters of word are 'Z', the inner loop in this solution will have to do 26 comparison operations, but if scoreboard is set up as {'A':1, 'B':3 ... 'Z':10}, the inner loop is not needed and there's only one operation needed to find the value for the letter.

if len(word) > 6:
score += 8
return score



def get_highest_word_score(word_list):
pass
tuple = ()
winner_score = 0
word_score = {}
winner_word = ''
for word in word_list:
word_score[word] = score_word(word)

Choose a reason for hiding this comment

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

👍

for key, value in word_score.items():
if value > winner_score:
winner_score = value
winner_word = key
if value == winner_score:
if len(key) < len(winner_word):
winner_word = key

tuple = (winner_word, winner_score)

Choose a reason for hiding this comment

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

Great progress on this wave! This algorithm works well to find the top score when there are no ties.

return tuple
# winner = ()
# word_score = {}
# for word in word_list:
# word_score[word] = score_word(word)
# for key, value in word_score.items():
# winner + max(value),key
# return winner
3 changes: 3 additions & 0 deletions tests/test_wave_01.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@
'Z': 1
}

#@pytest.mark.skip
def test_draw_letters_draws_ten():
# Arrange/Act
letters = draw_letters()

# Assert
assert len(letters) == 10

#@pytest.mark.skip
def test_draw_letters_is_list_of_letter_strings():
# Arrange/Act
letters = draw_letters()
Expand All @@ -49,6 +51,7 @@ def test_draw_letters_is_list_of_letter_strings():
assert type(elem) == str
assert len(elem) == 1

#@pytest.mark.skip
def test_letter_not_selected_too_many_times():

for i in range(1000):
Expand Down
5 changes: 5 additions & 0 deletions tests/test_wave_02.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from adagrams.game import uses_available_letters

#@pytest.mark.skip
def test_uses_available_letters_true_word_in_letter_bank():
# Arrange
letters = ["D", "O", "G", "X", "X", "X", "X", "X", "X", "X"]
Expand All @@ -13,6 +14,7 @@ def test_uses_available_letters_true_word_in_letter_bank():
# Assert
assert is_valid == True

#@pytest.mark.skip
def test_uses_available_letters_false_word_in_letter_bank():
# Arrange
letters = ["D", "O", "X", "X", "X", "X", "X", "X", "X", "X"]
Expand All @@ -24,6 +26,7 @@ def test_uses_available_letters_false_word_in_letter_bank():
# Assert
assert is_valid == False

#@pytest.mark.skip
def test_uses_available_letters_false_word_overuses_letter():
# Arrange
letters = ["A", "X", "X", "X", "X", "X", "X", "X", "X", "X"]
Expand All @@ -35,6 +38,7 @@ def test_uses_available_letters_false_word_overuses_letter():
# Assert
assert is_valid == False

#@pytest.mark.skip
def test_uses_available_letters_does_not_change_letter_bank():
# Arrange
letters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
Expand All @@ -48,6 +52,7 @@ def test_uses_available_letters_does_not_change_letter_bank():
assert is_valid == True
assert letters == letters_copy

#@pytest.mark.skip
def test_uses_available_letters_ignores_case():
# Arrange
letters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
Expand Down
4 changes: 4 additions & 0 deletions tests/test_wave_03.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,26 @@

from adagrams.game import score_word

# @pytest.mark.skip
def test_score_word_accurate():
# Assert
assert score_word("A") == 1
assert score_word("DOG") == 5
assert score_word("WHIMSY") == 17

# @pytest.mark.skip
def test_score_word_accurate_ignores_case():
# Assert
assert score_word("a") == 1
assert score_word("dog") == 5
assert score_word("wHiMsY") == 17

# @pytest.mark.skip
def test_score_zero_for_empty():
# Assert
assert score_word("") == 0

# @pytest.mark.skip
def test_score_extra_points_for_seven_or_longer():
# Assert
assert score_word("XXXXXXX") == 64
Expand Down
7 changes: 7 additions & 0 deletions tests/test_wave_04.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from adagrams.game import score_word, get_highest_word_score

#@pytest.mark.skip
def test_get_highest_word_score_accurate():
# Arrange
words = ["X", "XX", "XXX", "XXXX"]
Expand All @@ -14,6 +15,7 @@ def test_get_highest_word_score_accurate():
assert best_word[0] == "XXXX"
assert best_word[1] == 32

#@pytest.mark.skip
def test_get_highest_word_score_accurate_unsorted_list():
# Arrange
words = ["XXX", "XXXX", "XX", "X"]
Expand All @@ -25,6 +27,7 @@ def test_get_highest_word_score_accurate_unsorted_list():
assert best_word[0] == "XXXX"
assert best_word[1] == 32

#@pytest.mark.skip
def test_get_highest_word_tie_prefers_shorter_word():
# Arrange
words = ["MMMM", "WWW"]
Expand All @@ -38,6 +41,7 @@ def test_get_highest_word_tie_prefers_shorter_word():
assert best_word[0] == "WWW"
assert best_word[1] == 12

@pytest.mark.skip
def test_get_highest_word_tie_prefers_shorter_word_unsorted_list():
# Arrange
words = ["WWW", "MMMM"]
Expand All @@ -51,6 +55,7 @@ def test_get_highest_word_tie_prefers_shorter_word_unsorted_list():
assert best_word[0] == "WWW"
assert best_word[1] == 12

@pytest.mark.skip
def test_get_highest_word_tie_prefers_ten_letters():
# Arrange
words = ["AAAAAAAAAA", "BBBBBB"]
Expand All @@ -62,6 +67,7 @@ def test_get_highest_word_tie_prefers_ten_letters():
assert best_word[0] == "AAAAAAAAAA"
assert best_word[1] == 18

@pytest.mark.skip
def test_get_highest_word_tie_prefers_ten_letters_unsorted_list():
# Arrange
words = ["BBBBBB", "AAAAAAAAAA"]
Expand All @@ -73,6 +79,7 @@ def test_get_highest_word_tie_prefers_ten_letters_unsorted_list():
assert best_word[0] == "AAAAAAAAAA"
assert best_word[1] == 18

@pytest.mark.skip
def test_get_highest_word_tie_same_length_prefers_first():
# Arrange
words = ["AAAAAAAAAA", "EEEEEEEEEE"]
Expand Down