473,386 Members | 1,997 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Constructor problem

I'm writing a simple class to represent a deck of cards. Here is the
stripped down version. Notice classes Deck and Deck2. Class Deck works,
Deck2 does not. My thinking is that it should be more efficient (a la
Deck2) to pre-create the list, and then modify it, rather than appending
Cards as in Deck.

# --------------------snip--------------
class Card:
def __init__(self, rank=0, suit=0):
self.rank=rank
self.suit=suit

def __repr__(self):
r = "A23456789TJQK"[self.rank]
s = "SHCD"[self.suit]
return r+s
class Deck:
def __init__(self):
self.deck = []
for r in range(13):
for s in range(4):
self.deck.append(Card(r,s))

class Deck2:
def __init__(self):
self.deck = 52 * [Card()]
n = 0
for r in range(13):
for s in range(4):
self.deck[n].rank = r
self.deck[n].suit = s
n = n + 1
a = Deck()
print "A --> ", a.deck
b = Deck2()
print "B --> ", b.deck
# ------------snap---------------------

Deck A looks right, 52 cards, one of each. Deck B, on the other hand, is
52 of the same card, all rank 12, suit 3.

What am I missing???

Thanks!
Nick.
Jul 18 '05 #1
5 1575
Nick wrote:
class Deck2:
def __init__(self):
self.deck = 52 * [Card()]


Here you are creating a single Card instance and putting the same object
into a list 52 times. Each slot in the list points to the same object.

Another lesson to take away from this: Don't optimize prematurely. The
simplest implementation should be fine unless proven otherwise via
profiling.

--
Robert Kern
rk***@ucsd.edu

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter
Jul 18 '05 #2
"Nick" <me*************@hotmail.com> wrote in message
news:41**********@alt.athenanews.com...
I'm writing a simple class to represent a deck of cards. Here is the
stripped down version. Notice classes Deck and Deck2. Class Deck works,
Deck2 does not. My thinking is that it should be more efficient (a la
Deck2) to pre-create the list, and then modify it, rather than appending
I strongly suspect premature optimization here.
Cards as in Deck.

# --------------------snip--------------
class Card:
def __init__(self, rank=0, suit=0):
self.rank=rank
self.suit=suit

def __repr__(self):
r = "A23456789TJQK"[self.rank]
s = "SHCD"[self.suit]
return r+s
class Deck:
def __init__(self):
self.deck = []
for r in range(13):
for s in range(4):
self.deck.append(Card(r,s))

class Deck2:
def __init__(self):
self.deck = 52 * [Card()]
This creates a list of 52 references to the card created by Card().
n = 0
for r in range(13):
for s in range(4):
self.deck[n].rank = r
self.deck[n].suit = s
n = n + 1
a = Deck()
print "A --> ", a.deck
b = Deck2()
print "B --> ", b.deck
# ------------snap---------------------

Deck A looks right, 52 cards, one of each. Deck B, on the other hand, is
52 of the same card, all rank 12, suit 3.

What am I missing???

Thanks!
Nick.


How about a list comprehension?

class Deck3:
def __init__(self):
self.deck = [Card(r, s) for s in range(4) for s in range(13)]

Jul 18 '05 #3
Nick wrote:
I'm writing a simple class to represent a deck of cards. Here is the
stripped down version. Notice classes Deck and Deck2. Class Deck works,
Deck2 does not. My thinking is that it should be more efficient (a la
Deck2) to pre-create the list, and then modify it, rather than appending
Cards as in Deck.

# --------------------snip--------------
class Card:
def __init__(self, rank=0, suit=0):
self.rank=rank
self.suit=suit

def __repr__(self):
r = "A23456789TJQK"[self.rank]
s = "SHCD"[self.suit]
return r+s
class Deck:
def __init__(self):
self.deck = []
for r in range(13):
for s in range(4):
self.deck.append(Card(r,s))

class Deck2:
def __init__(self):
self.deck = 52 * [Card()]
n = 0
for r in range(13):
for s in range(4):
self.deck[n].rank = r
self.deck[n].suit = s
n = n + 1
a = Deck()
print "A --> ", a.deck
b = Deck2()
print "B --> ", b.deck
# ------------snap---------------------

Deck A looks right, 52 cards, one of each. Deck B, on the other hand, is
52 of the same card, all rank 12, suit 3.

What am I missing???

Thanks!
Nick.


self.deck = 52 * [Card()]

Problem is with this line. It doesn't do what you want.

Try this from interpreter prompt:

class card:
pass

deck=52*[card()]
id(deck[0])
id(deck[1])
....

You will notice that all 52 entries in the list point
to the same instance of the card class.

As far as performance is concerned you are doing what
is commonly called as premature optimization. I set
up a loop and complete deck creation takes only 0.00015
seconds (that's 0.15 milliseconds) on my machine. I
wouldn't worry about optimizing this part of the program.

-Larry
Jul 18 '05 #4
Nick <me*************@hotmail.com> wrote:
...
I'm writing a simple class to represent a deck of cards. Here is the
stripped down version. Notice classes Deck and Deck2. Class Deck works,
Deck2 does not. My thinking is that it should be more efficient (a la
Deck2) to pre-create the list, and then modify it, rather than appending
Cards as in Deck.


Everybody's accusing you of premature optimization, and they have a
point, but, there IS a very simple approach that's fast and useful
(particularly in Python 2.4 -- if you're interested in performance, get
and use 2.4 beta 1 *NOW*!!!-): a list comprehension:

self.deck = [Card(r, s) for r in xrange(13) for s in xrange(4)]
Alex
Jul 18 '05 #5
Nick wrote:
I'm writing a simple class to represent a deck of cards. Here is the
stripped down version. Notice classes Deck and Deck2. Class Deck works,
Deck2 does not. My thinking is that it should be more efficient (a la
Deck2) to pre-create the list, and then modify it, rather than appending
Cards as in Deck.

Thanks for the replies... I smack my head in dismay.

Jul 18 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Lefevre | last post by:
Hello I recently had troubles with a class inheritance hierarchy. I solved it, but it didn't satisfied me. I found the solution using this forum :) Actualy i found the following message...
11
by: Amadrias | last post by:
Hi all, I am using a class to transport some data over the network. I then added the attribute to the class. My problem is that this class is part of a framework and that I do not want...
6
by: Nafai | last post by:
Hello. I want to do something like this: class A { // It's virtual protected: float* data; int n; public: A(int a); virtual float* createData(); //...
19
by: Martin Oddman | last post by:
Hi, I have a compiling problem. Please take a look at the code below. I have an application that is built upon three tiers: one data tier (Foo.DataManager), one business tier (Foo.Kernel) and...
45
by: Ben Blank | last post by:
I'm writing a family of classes which all inherit most of their methods and code (including constructors) from a single base class. When attempting to instance one of the derived classes using...
23
by: TarheelsFan | last post by:
What happens whenever you throw an exception from within a constructor? Does the object just not get instantiated? Thanks for replies.
74
by: Zytan | last post by:
I have a struct constructor to initialize all of my private (or public readonly) fields. There still exists the default constructor that sets them all to zero. Is there a way to remove the...
22
by: clicwar | last post by:
A simple program with operator overloading and copy constructor: #include <iostream> #include <string> using namespace std; class Vector { private: float x,y; public: Vector(float u, float...
13
by: JD | last post by:
Hi, My associate has written a copy constructor for a class. Now I need to add an operator = to the class. Is there a way to do it without change her code (copy constructor) at all? Your help...
9
by: Morten Lemvigh | last post by:
Is it possible to pass a pointer to a constructor or a class definition as argument to a function? Maybe in a way similar to passing function pointers...? The function should construct a number...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.