[Tutor] Debugging While Loops for Control

Alan Gauld alan.gauld at btinternet.com
Fri Feb 17 09:24:15 CET 2012


On 17/02/12 03:27, Luke Thomas Mergner wrote:


> In the meantime, and continuing my problem of over-cleverness,

At least you know what your problem is :-)


> Bonus question: when I create a the "def score(self)" in class Hand,
 > should that be an generator?

No.

> And if so where do I go as a newb to understand generators?

The documentation.
Or Google python generator tutorial howto

> I'm really not understanding them yet.

You don't need to for what you are doing.

>  The "x for x in y:" syntax makes it harder to follow for learners,

Read about list comprehensions first.
It helps if you studied sets in math at school. The format is
somewhat like the math notation for defining a set. But FWIW it took me 
a long time to get used to that syntax too.



Some thoughts....

> class Card(object):
> 	def __init__(self):
> 		self.score = self.deal()
> 		
> 	def deal(self):
> 		"""deal a card from 1 to 52 and return it's points"""
> 		return self.getValue(int(math.floor(random.uniform(1, 52))))

I think you only need random.randint(1,52) here. It simplifies it quite 
a lot! But you still have the problem that you might wind up with two 
identical cards! It might be better to create a deck(list) of 52 cards, 
shuffle() them and then pop the value off of that deck.

> 	def getValue(self, card):
> 		"""Converts the values 1 - 52 into a 1 - 13 and returns the correct blackjack score based on remainder."""
> 		if (card % 13 == 0 or card % 13 == 11 or card % 13 == 12):
> 			#Face Cards are 10 points
> 			return 10
> 		elif (card % 13 == 1):
> 			return 11
> 		else:
> 			#Regular cards, return their value
> 			return card % 13

Just calculate the value once rather than doing a mod division each 
time. Much more efficient and easier to read.
  			
> 	def showCard(self):
> 		return repr(self.score)

Why are you using repr? Why not just return the integer value?

> class Hand:
> 	def __init__(self):
> 		self.cards = []
> 		#Add cards this way to avoid duplicates.
> 		for i in range(2):
> 			self.cards.append(Card())

What makes you think it will avoid duplicates? The card values are 
generated at random.
		
> 	def hit(self):
> 		self.cards.append(Card())

> 	def showHand(self):
> 		return self

This seems fairly pointless. If i already have a reference to an object 
why would I call a method that returns what I already have? Maybe 
returning self.cards would make sense. But really the Hand class should 
do whatever is needed to cards so even that doesn't make sense. The only 
thing this could usefully do is pretty print the cards in a formatted 
string.

	
> 	def score(self):
> 		#how do you sum(objects) ???

You could define an __add__() method on your cards so that Card()+Card() 
returns an integer. (Or you could use a generator
here if you really, really wanted to. But the __add__ method
is cleaner IMHO)


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/



More information about the Tutor mailing list