Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Oct 31st, 2005, 3:31 AM   #1
coldDeath
Expert Programmer
 
coldDeath's Avatar
 
Join Date: Aug 2005
Location: UK
Posts: 862
Rep Power: 4 coldDeath is on a distinguished road
Send a message via AIM to coldDeath Send a message via Yahoo to coldDeath
Neatening some Python code

OK, I wrote a simple script that will deal you some cards.

Basically it takes an argument of how many cards you want to be drawn, and then it shows you those cards. It doesn't draw the same card twice. The cards can be put back into the pack by calling: shuffle().

It works fine, but what i am interested in is shortening the code and making it more efficient.

Here it is:
#! /usr/bin/python

#Card Dealer

import random
class cards:
	def __init__(self):
		self.suits = ["Hearts", "Diamonds", "Spades", "Clubs"]
		self.numbers = ["Ace", 2, 3, 4, 5 , 6, 7, 8, 9, 10, "Jack", "Queen", "King"] 
		self.pack = ["52 Card Pack"]
		for x in self.suits:
			for y in self.numbers:
				z = "%s of %s" % (y, x)
				self.pack.append(z)
		self.shuffle()
	
	def shuffle(self):
		self.choices = [1]
		for n in range(2,53): self.choices.append(n)
		
	def draw_a_card(self):
		a = random.choice(self.choices)
		card_drawn = self.pack[a]
		self.choices.remove(a)
		return card_drawn

	def deal(self, number_of_cards):
		b = self.draw_a_card()
		self.playercards = [b]
		for i in range(1, number_of_cards):
			b = self.draw_a_card()
			self.playercards.append(b)
		print "Your hand: %s" % (self.playercards)
	
newgame = cards()
deal = "y"
while deal == "y":
	newgame.deal(5)
	deal = raw_input("Deal again? (y/n)")

Its about 35 lines without comments. I can't think of any way that i could shorten this code, how would you go about shortening it?
__________________
Join us at #programmingforums @ irc.freenode.net!

My software never has bugs. It just develops random features.
coldDeath is offline   Reply With Quote
Old Oct 31st, 2005, 6:35 AM   #2
Sane
Programming Guru
 
Sane's Avatar
 
Join Date: Apr 2005
Location: Waterloo, Ontario
Posts: 1,869
Rep Power: 5 Sane will become famous soon enough
Send a message via MSN to Sane
I'm rushing to catch the bus right now, but if you wait 2 hours till win my Tech starts, I'll have your answer.

See ya!
Sane is offline   Reply With Quote
Old Oct 31st, 2005, 6:43 AM   #3
coldDeath
Expert Programmer
 
coldDeath's Avatar
 
Join Date: Aug 2005
Location: UK
Posts: 862
Rep Power: 4 coldDeath is on a distinguished road
Send a message via AIM to coldDeath Send a message via Yahoo to coldDeath
ty Sane i'll be on AIM, MSN and IRC. But you coudl post in this topic incase anyone else needs to find this sort of thing in the future. ty.

EDIT: haha you look wackey in your avatar
__________________
Join us at #programmingforums @ irc.freenode.net!

My software never has bugs. It just develops random features.
coldDeath is offline   Reply With Quote
Old Oct 31st, 2005, 6:58 AM   #4
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5 Arevos is on a distinguished road
The first thing I'd do to shorten it would be to use list comprehensions:
import random

# (By convention, classes should ideally have their first letter capitalised)
class Cards:
   def __init__(self):
      suits = ["Hearts", "Diamonds", "Spades", "Clubs"]
      numbers = ["Ace"] + range(2, 11) + ["Jack", "Queen", "King"] 
      self.pack = ["%s of %s" % (n, s) for n in numbers for s in suits]
      self.shuffle()
The second thing would be to use random.shuffle to shuffle my cards:
   def shuffle(self):
      random.shuffle(self.pack)
Because I'm shuffling the cards, rather than indexes to the cards, I can shorten draw_a_card, too:
   def draw_a_card(self):
      card = random.choice(self.pack)
      self.pack.remove(card)
      return card
In fact, we can shorted draw_a_card further. In real life, the dealer shuffles, then (usually) deals off the top. Assuming our shuffling is random enough, we can cut this function to:
   def draw_a_card(self):
      return self.pack.pop()
Using list comprehensions, we can cut deal() to one line:
   def deal(self, number_of_cards):
      print "Your hand: %s" % [self.draw_a_card() for i in range(number_of_cards)]
Indeed, we can do away with draw_a_card now, if we wish:
   def deal(self, number_of_cards):
      print "Your hand: %s" % [self.pack.pop() for i in range(number_of_cards)]

So, assuming we're not too fussed about shuffling more than once, and assuming we're not worried about exceptions occuring when running out of cards (as in the original code), we can cut the program down to 20 lines:
#! /usr/bin/python
# Card Dealer

import random

class Cards:
   def __init__(self):
      suits = ["Hearts", "Diamonds", "Spades", "Clubs"]
      numbers = ["Ace"] + range(2, 11) + ["Jack", "Queen", "King"]
      self.pack = ["%s of %s" % (n, s) for n in numbers for s in suits]
      random.shuffle(self.pack)
      
   def deal(self, number_of_cards):
      print "Your hand: %s" % [self.pack.pop() for i in range(number_of_cards)]
   
newgame = Cards()
deal = "y"
while deal == "y":
   newgame.deal(5)
   deal = raw_input("Deal again? (y/n)")
Arevos is offline   Reply With Quote
Old Oct 31st, 2005, 7:09 AM   #5
coldDeath
Expert Programmer
 
coldDeath's Avatar
 
Join Date: Aug 2005
Location: UK
Posts: 862
Rep Power: 4 coldDeath is on a distinguished road
Send a message via AIM to coldDeath Send a message via Yahoo to coldDeath
Wow. Arevos thats great!
Thats the exact response i was looking for thanks.

One main thing that got me, was the fact that i didn't think about actually shuffling the pack, but shuffling the indexes.

Its looking pretty good now, tyvm!

EDIT: i've set it to reshuffle when thw number of cards to deal is less than the number of cards left in the pack.
__________________
Join us at #programmingforums @ irc.freenode.net!

My software never has bugs. It just develops random features.

Last edited by coldDeath; Oct 31st, 2005 at 7:18 AM. Reason: typos
coldDeath is offline   Reply With Quote
Old Oct 31st, 2005, 7:30 AM   #6
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5 Arevos is on a distinguished road
Quote:
Originally Posted by coldDeath
EDIT: i've set it to reshuffle when thw number of cards to deal is less than the number of cards left in the pack.
Make sure you repopulate the cards; my code removes cards from the pack, just as a dealer would.

Also, you might want to think about representing the cards as objects, rather than strings:
class Card:
   def __init__(self, suite, number):
      self.suite = suite
      self.number = number

   def __str__(self):
      return "%s of %s" % (self.number, self.suite)
This would give you more control over the deck of cards. e.g.:
remaining_hearts = [card for card in self.pack if card.suite = "Hearts"]
Of course, it depends on how complicated you wish to make your program, and what you're going to use it for.
Arevos is offline   Reply With Quote
Old Oct 31st, 2005, 7:39 AM   #7
coldDeath
Expert Programmer
 
coldDeath's Avatar
 
Join Date: Aug 2005
Location: UK
Posts: 862
Rep Power: 4 coldDeath is on a distinguished road
Send a message via AIM to coldDeath Send a message via Yahoo to coldDeath
I see, i might mess around with that, ty.
__________________
Join us at #programmingforums @ irc.freenode.net!

My software never has bugs. It just develops random features.
coldDeath is offline   Reply With Quote
Old Oct 31st, 2005, 7:55 AM   #8
coldDeath
Expert Programmer
 
coldDeath's Avatar
 
Join Date: Aug 2005
Location: UK
Posts: 862
Rep Power: 4 coldDeath is on a distinguished road
Send a message via AIM to coldDeath Send a message via Yahoo to coldDeath
This may sound a bt newbie-ish, but here goes:

If i was to make the cards into objects, how would i make a list containing each card?

Because i'm not sure how to make an instance of an object from the code without typing out each card, which would mean 52 lines of code just to set up the pack.
__________________
Join us at #programmingforums @ irc.freenode.net!

My software never has bugs. It just develops random features.
coldDeath is offline   Reply With Quote
Old Oct 31st, 2005, 8:37 AM   #9
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5 Arevos is on a distinguished road
Assuming you want a different object for each card, rather than a different class (which might be overkill):
self.pack = [Card(s, n) for n in numbers for s in suites]
Arevos is offline   Reply With Quote
Old Oct 31st, 2005, 8:52 AM   #10
coldDeath
Expert Programmer
 
coldDeath's Avatar
 
Join Date: Aug 2005
Location: UK
Posts: 862
Rep Power: 4 coldDeath is on a distinguished road
Send a message via AIM to coldDeath Send a message via Yahoo to coldDeath
I don't really understand how you could call the __str__ function for each car in the pack.

Say you got dealt a hand of five cards, and they were in a list, how would you print out what each card is?
__________________
Join us at #programmingforums @ irc.freenode.net!

My software never has bugs. It just develops random features.
coldDeath is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 1:56 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC