Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Python Basic Object-Oriented Python Creating a Memory Game Final Product

4 Answers

Asher Orr
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Asher Orr
Python Development Techdegree Graduate 9,086 Points

Hey Ava! I am responding to these 2 questions:

"Now run it again, you will see that there are more rows than needed."

"And there is this problem A4: Add A3: Gum A4: Add A3: Dev"

In your dunder name statement at the end of game.py, try removing these 2 lines of code:

 game.set_cards()
 game.create_grid()

Here's why: you're creating an instance of the Game class, then you're calling the set cards and create_grid methods on the class. Then you call the start_game method after.

if __name__ == '__main__':
  game = Game()
  game.set_cards()
  game.create_grid()
  game.start_game()

Check out your start_game method. It sets the cards and creates the grid for you (you'll see create.grid() and set.cards() inside.)

You have the extra rows and the card issues because you're telling Python to set the cards, create the grid, and then do those steps AGAIN when you call start_game.

Remove those methods from the dunder name function, and you shouldn't have those issues anymore.

Once you do that and run the code again, you'll run into an AttributeError.

Traceback (most recent call last):                                                                             
  File "/home/treehouse/workspace/game.py", line 93, in <module>                                               
    game.start_game()                                                                                          
  File "/home/treehouse/workspace/game.py", line 79, in start_game                                             
    guess1 = self.check_location('first')                                                                      
  File "/home/treehouse/workspace/game.py", line 67, in check_location                                         
    if guess.upper() in self.location:                                                                         
AttributeError: 'Game' object has no attribute 'location

In your check_location function, check out this line:

if guess.upper() in self.location:

The error says that the Game object has no attribute called "location." To see why, look at the init method for your Game class:

class Game:
  def __init__(self):
    self.size = 4
    self.card_options = ["Add", "Boo", "Cat", "Dev", "Egg", "Far", "Gum", "Hut"]
    self.columns = ["A", "B", "C", "D"]
    self.cards = []
    self.locations = []
    for column in self.columns:
      for num in range(1, self.size + 1):
        self.locations.append(f'{column}{num}')

All the locations are going into that self.locations list. As Steven said, it's self.locations (with an S at the end.)

After that fix, you will get this error once you enter the second card.

Traceback (most recent call last):                                                                             
  File "/home/treehouse/workspace/game.py", line 93, in <module>                                               
    game.start_game()                                                                                          
  File "/home/treehouse/workspace/game.py", line 81, in start_game                                             
    if self.check_match(guess1, guess2):                                                                       
  File "/home/treehouse/workspace/game.py", line 56, in check_match                                            
    print(f'{card.location}: {card}')                                                                          
TypeError: __str__ returned non-string (type set)

This is because of your str method in class Card. When you print a value wrapped in curly braces, it won't display properly unless it's formatted with an f-string. Like this:

class Card:

  def __str__(self):
    return f'{self.card}'

You should be all set now. I hope this helps!

Ava Jones
Ava Jones
2,555 Points

Thank you so much, I understood everything

Steven Parker
Steven Parker
218,596 Points

The snapshot is great, but it would also help if you provide a description of what your issue is!

But I did try running it and got this error on line 63: "AttributeError: 'Game' object has no attribute 'location'"

That occurs because the actual attribute is named locations (plural) instead of "location".

Ava Jones
Ava Jones
2,555 Points

Thank you! I will contact you if I need any more help.

Ava Jones
Ava Jones
2,555 Points

Now run it again, you will see that there are more rows than needed

Ava Jones
Ava Jones
2,555 Points

And there is this problem A4: Add A3: Gum A4: Add A3: Dev

Daniel Mula Tarancón
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Daniel Mula Tarancón
Python Development Techdegree Graduate 21,972 Points

Ok Ava Jones... Several things here...

Regarding to the cards.py file this how I fixed it:

class Card:
    def __init__(self, word, location, matched = False):
        self.word = word
        self.location = location
        self.matched = matched

    def __eq__(self, other):
        if self.word == other.word:
            matched = True
        else:
            matched = False
        return matched

    def __str__(self):
        return self.word

As you can see I changed the 'matched' attribute definition. I did it in a way that it will have 'False' as a default value but it will change its value if the app requires so. In your case is always 'False'.

Then as you can verify I changed the eq method just take easy think without considering the syntax: 'if something is something then ... I get this...' You are comparing two things so: 'if something is equal to...'

Alright now the game.py file: (few things here)

1) You just need to write this inside the dunder main:

game = Game() game.start_game()

Since you are already calling all the methods you need inside game.start_game()

2) Inside the 'check_match' method you need to handle a possible IndexError (in case I try to guess A1 and A1 which is not possible).

    def check_match(self, loc1, loc2):
        cards = []
        for card in self.cards:
            if card.location == loc1 or card.location == loc2:
                cards.append(card)
        try:
            if cards[0] == cards[1]:
                cards[0].matched = True
                cards[1].matched = True
                return True
            else:
                for card in cards:
                    print(f'{card.location}: {card}')
                return False
        except IndexError:
            print('You must select a different location please')

I believe that should be enough... Try for yourself and if you require further assistance I'll share the whole solution.

Cheers.

Ava Jones
Ava Jones
2,555 Points

thank you for your time!