[Tutor] list of objects?

James Reynolds eire1130 at gmail.com
Tue Nov 15 15:28:30 CET 2011


On Tue, Nov 15, 2011 at 8:40 AM, Elwin Estle <chrysalis_reborn at yahoo.com>wrote:

> I am attempting to write a text based spider solitaire game.  I have  a
> pretty simple card class, and a deck class, which has a list of card
> objects, which are shuffled, then individual elements are put into
> self.dealt, which is a 'list of lists' when the cards are dealt.
>
> I am trying to control the visibility of the cards.  There is a small
> "for" loop in the "deal" method of the deck class, this is intended to
> toggle the visibility of four of the cards.  It does that just fine, but
> for some reason, it seems to be randomly toggling the visibility of other
> cards in the self.dealt list and I am thoroughly confused as to why that
> is.  Is it something to do with the way objects are referenced?  Is my list
> of card objects a bad way to approach this?
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>
>


A few thoughts first:

class Card(object):

    def __init__(self):
        self.value = ''
        self.display = 'X'

I would change the above to:

class Card(object):

    def __init__(self, value):
        self.value = value
        self.display = 'X'

(because you always have a card with a value)

Which allows you to save a line here:

        for value in values:
            card = Card(value)
            card_list.append(card)

like that

Another idea would be to use "extend" here:

        values = []

        for i in range(1, 11):
            values.append(str(i))

        values.append('J')
        values.append('Q')
        values.append('K')

So, you would do something like this instead:

        mylist = range(1, 11)
        mylist.extend(['J', 'Q', 'K'])

        for i in mylist:
            values.append(str(i))

What extend does is it extends one list with another list.

Also, you can build the string conversion into the card class:

Further saving you the above loop:

class Card(object):

    def __init__(self, value):
        self.value = str(value)
        self.display = 'X'

and then in the create_cards def:

        mylist = range(1, 11)
        mylist.extend(['J', 'Q', 'K'])

#        for i in mylist:
#            values.append(str(i))

        for value in mylist:
            card = Card(value)
            card_list.append(card)


(as an aside, I'm not sure why you do this:

        card_list = card_list * 8

if you need two decks, I think you should have a variable like 4*decks so
you can shuffle the right amount of decks)

I don't think you need to shuffle twice here (which in turn calls into
question why you need a separate method, but maybe you were going to build
on it - i do that all the time):

    def shuffle(self):
        random.shuffle(self.cards)
        #random.shuffle(self.cards)


Now onto your question:

You can see that there are four card values that are shown visible in any
given run. There are always four values and they are always random from run
to run.

If you comment out this loop

#        for index, card in enumerate(self.dealt[5]):
#            print index, card
#            self.dealt[5][index].display  = self.dealt[5][index].value

You won't get that anymore.

If you want to control whether to display any particular card or not, I
would add a variable to the display_cards method:

    def display_cards(self, display = True):

        for row in self.dealt:
            for card in row:
                if display:
                    print '%5s ' % card.display,
                else:
                    print '%5s ' % card.value,
            print ''

Or you can add another value to the card class, if you want to control the
display of cards on a unique basis:

class Card(object):

    def __init__(self, value):
        self.value = str(value)
        self.display = 'X'
        self.display_or_value = True

then you can change your method above to be:

    def display_cards(self):

        for row in self.dealt:
            for card in row:
                if card.display_or_value:
                    print '%5s ' % card.display,
                else:
                    print '%5s ' % card.value,
            print ''


Long story short, if I wanted to control the visibility of any card, I
would do it within the Card class (since presumably that is an attribute of
any given card - think about it in real life, a card can be up, or a card
can be down, yet it still retains its other properties, like color, value,
creases, etc)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20111115/90eef3f8/attachment-0001.html>


More information about the Tutor mailing list