Classes in modules

hexusnexus at gmail.com hexusnexus at gmail.com
Thu Apr 3 17:00:54 EDT 2008


Yeah, I was a little embarrassed putting my code up to be examined.
Thanks for the reply.  I typed up some classes, but I seemed to have
run into some more problems.  One of the classes keeps getting an
error that it can't pop from an empty list.  Here's the code so far:



################begin main.py#######look for more comments
#!/usr/bin/python

import random

#structure for holding card data
class Cards(object):
    RANK =
["ace","2","3","4","5","6","7","8","9","10","jack","queen","king"]
    SUIT = ["spades","clubs","hearts","diamonds"]
    def __init__(self,rank,suit):
        self.rank = rank
        self.suit = suit
        self.name = "%s of %s" % (Cards.RANK[self.rank],
Cards.SUIT[self.suit])

#deck functions
class Deck(object):
    def __init__(self):
        self.deck = []
        for i in range(52):
            self.deck.append(Cards(i % 13, i / 13))
    def shuffle(self):
        random.seed()
        random.shuffle(self.deck)
    def draw(self):             #This is where my (first) problem
arises, though there may be more
        return self.deck.pop()  #IndexError: pop from empty list
    def size(self):
        return len(self.deck)
#Note: if anyone can find more errors in my code thus far, feel free
to criticize
#it's been a while since I've practised any OOP

#hand functions
class Hand(object):
    def __init__(self):
        self.cards = []
    def pull(self, pos=0):
        return self.cards.pop(pos)
    def size(self):
        return len(self.cards)
    def put(self,crd):
        self.cards.append(crd)
    def cards(self):
        return self.cards
    def orgcards(self):  #organizes cards, 2's to aces, trumps last
        begin,end=0,0
        for i in range(len(self.cards)-1):
            for j in range(len(self.cards)-1):
                if self.cards[j] > self.cards[j+1]:
                    temp = self.cards[j+1]
                    self.cards[j+1] = self.cards[j]
                    self.cards[j] = temp

        for i in range(len(self.cards)):
            for j in range(len(self.cards)-1):
                if self.cards[j]%13==0 and self.cards[j]/
13==self.cards[j+1]/13:
                    temp=self.cards[j+1]
                    self.cards[j+1]=self.cards[j]
                    self.cards[j]=temp

        for i in range(len(self.cards)-1,-1,-1):
            if self.cards[i]/13==Stock.trump():
                end=i
                break

        if end>0:
            end=0

        for i in range(end,-1,-1):
            if self.cards[i]/13==Stock.trump():
                begin=i
                break

        m=self.cards-1
        for j in range(end,begin,-1):
            l=0
            k=j
            while True:
                l=k+1
                if l > m:
                    break
                temp = self.cards[l]
                self.cards[l]=self.cards[k]
                self.cards[k]=temp
                k=l
            m-=1

        if self.cards<13:
            for i in range(len(self.cards)-1):
                for j in range(len(self.cards)-1):
                    if self.cards[j] == -1:
                        temp=self.cards[j+1]
                        self.cards[j+1]=self.cards[j]
                        self.cards[j]=temp
        return self.cards


class Stock(Hand): #the stock class, slightly modified from Hand
    def __init__(self):
        self.cards = []
        self.y = -1
        self.cards.extend(Deck.deck)
    def showtrump(self):
        if self.y < 0:
            self.y = self.cards[25]
        return self.y



class Game(object):  #the main game class
    def __init__(self):
        self.deck = Deck()
        self.deck.shuffle()
        self.player = Hand()
        self.computer = Hand()
        for i in range(self.deck.size()):
            self.player.put(self.deck.draw())
            self.computer.put(self.deck.draw())
        self.stock = Stock()
        print self.stock.showtrump()

mygame = Game()

#########################################################

If anyone can take a look at this and tell me where I went wrong, I'd
really appreciate it.  I'm using Python v2.5.

On Apr 2, 8:41 pm, Dennis Lee Bieber <wlfr... at ix.netcom.com> wrote:
> On Wed, 2 Apr 2008 18:05:38 -0700 (PDT), hexusne... at gmail.com declaimed
> the following in comp.lang.python:
>
>
>
> I've been trying to make  so that I have one class per file for easier
>
>         Unlike Java, which practically mandates the class<=>file format,
> Python is perfectly happy with multiple related classes in one file --
> and often /easier/ to read that way as one is not forced to jump around
> finding dependent files to understand related classes.
>
>
>
> > This has been a recurring problem for me in languages such as C++ and
> > Java.  I'm used to programming in C.
>
>         Please don't be offended, but looking at the specified file... it
> shows...
>
>         Ignoring the language in use, I'd suggest a few studies in software
> design, functional decomposition, data structures, and algorithms... to
> start...
>
>         I lost count of how many times this
>
> >            if rank==0:
> >                 rankstr = "ace"
> >             elif rank==10:
> >                 rankstr = "jack"
> >             elif rank==11:
> >                 rankstr = "queen"
> >             elif rank==12:
> >                 rankstr = "king"
> >             else:
> >                 rankstr=str(rank+1)
>
> appears in the file, but a concept normally emphasized early in a
> programming career is that when you have many identical (or near enough
> that a minor tweak can serve for all) occurrences of the same code, it
> should probably be turned into a function.
>
>         However, this is even better served by usage of data structures...
>
> _RANKS = [      "ace",        "two",        "three",      "four",       "five",
>                                 "six",        "seven",      "eight",      "nine",
>                                 "ten",        "jack",       "queen",      "king"        ]
>
> as a module-wide "constant", and then replace all those if/elif...
> blocks with a simple:
>
>                 rankstr = _RANKS[rank]
>
>         Worse though, your code seems to have used the class keyword just
> for the "see, I used classes" factor, with no logical concept of object
> orientation. Instead you are creating singleton instances that are being
> referenced as global data across the classes...
>
>         A simplistic approach for object orientation is to start with a text
> description of the problem (in this case, a description of how the game
> is played, perhaps). Find the key nouns in that description -- nouns
> often (not always) turn into the classes. Find the verbs in the
> description -- these are possible methods of the most closely related
> noun. Find adjectives -- these may become attributes of the classes.
>
> Generic Card Game:
>         The GAME uses one DECK of 52 playing CARDs (standard arrangement:
> _ranks_ of Ace, 2, ..., 10, Jack, Queen, King, in the _suits_ of Clubs,
> Diamonds, Hearts, Spades). _n_ PLAYERs take turns... The DECK is
> /shuffled/, then CARDs are /dealt/ to each PLAYER, each, in turn,
> /drawing/ one card from the DECK until they have a HAND of m-CARDs.
>
>         As a start (if you want multiple files)...
>
> -=-=-=-=-=-             carddeck.py
> import random
>
> class Card(object):
>         _RANKS = [      "ace",        "two",        "three",      "four",       "five",
>                                         "six",        "seven",      "eight",      "nine",
>                                         "ten",        "jack",       "queen",      "king"        ]
>         _SUITS = [              "spades",     "clubs",      "hearts",     "diamonds"    ]
>
>         def __init__(self, rank, suit):
>                 self.rank = rank
>                 self.suit = suit
>                 self.name = "%s of %s" % (Card._RANKS[self.rank],
>                                                                         Card._SUITS[self.suit])
>
> class Deck(object):
>         def __init__(self):
>                 #       cryptic initialization of 52 cards <G>
>                 #       relies on Python 2.4 or earlier behavior
>                 #       read the documentation for 2.5 or later to determine changes
>                 self._deck = [Card(i % 13, i / 13) for i in range(52)]
>                 self._discards = []
>         def shuffle(self):
>                 self._deck.extend(self._discards)       #combine
>                 self._discards = []
>                 random.shuffle(self._deck)
>         def draw(self):
>                 return self._deck.pop() #returns one card from deck
>         def discard(self, crd):
>                 self._discards.append(crd)      #puts card into discard pile
>
> -=-=-=-=-=-             player.py
> import carddeck #at this point, this may or may not be needed
>
> class Hand(object):
>         def __init__(self):
>                 self._cards = []
>         def pull(self, pos=0):
>                 return self._cards.pop(pos)
>         def size(self):
>                 return len(self._cards)
>         def put(self, crd):
>                 self._cards.append(crd)
>         def cards(self):
>                 return [ crd.name for crd in self._cards]
>
> class Player(object):
>         def __init__(self):
>                 self._hand = Hand()
>         def pull(self, pos=0):
>                 #I'm pulling a "law of demeter" here; player does not
>                 #directly manipulate cards in the hand
>                 return self._hand.pull(pos)
>         def size(self):
>                 return self._hand.size()
>         def put(self, crd):
>                 self._hand.put(crd)
>         def showHand(self):
>                 for crd in self._hand.cards():
>                         print crd
>
> -=-=-=-=-       game.py
> import carddeck
> import player
>
> class Game(object):
>         def __init__(self, numPlayers=2):
>                 self._players = [player.Player() for i in range(numPlayers)
>                 self._deck = carddeck.Deck()
>                 self._deck.shuffle()
>                 for i in range(7):      #assume each player starts with 7 cards
>                         for p in self._players:
>                                 p.put(self._deck.draw())
>
> #       rest left as an exercise for the student...
>
> --
>         Wulfraed        Dennis Lee Bieber               KD6MOG
>         wlfr... at ix.netcom.com                wulfr... at bestiaria.com
>                 HTTP://wlfraed.home.netcom.com/
>         (Bestiaria Support Staff:               web-a... at bestiaria.com)
>                 HTTP://www.bestiaria.com/




More information about the Python-list mailing list