Hey, how's it going? I decided to pick up Python for the heck of it and have been having some trouble creating this Card Deck class. All this class is supposed to do is initialize a deck, and then draw a card at total random:

import random
class CardDeck():
    suit = ["Spades","Clubs","Hearts","Diamonds"]
    number = ["Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King", "Ace"]
       
    def DrawCard():
        randomsuit = random.randrange(0,3)
        randomnumber = random.randrange(0,12)
        print ("You drew the " + number(randomnumber)+ " of " + suit(randomsuit) +"!")

CardDeck.DrawCard()

Each time I try this, the IDLE returns: "NameError: global name 'number' is not defined". Just for kicks, I tried putting the number and suit arrays in the DrawCard() function, and instead I get the error: "TypeError: 'list' object is not callable"

Any advice would be appreciated

Dani AI

Generated

Quick clarifications and a couple of small improvements based on the thread (, , ).

The original errors come from two different causes. A method defined without self cannot access instance attributes by name, so unqualified names like number become unresolved (NameError). A TypeError: 'list' object is not callable is produced by using parentheses instead of square brackets when indexing (e.g. mylist(0) tries to call the list). fixed the __init__/self issue — the next things to watch are index bounds and how cards are drawn.

Prefer random.choice or explicit randrange(len(...)) to avoid off-by-one mistakes: random.randrange(a, b) returns values in [a, b-1]. For a compact class-level approach that doesn’t require instantiation, a classmethod plus random.choice keeps the code short and avoids index maths:

import random

class CardDeck:
    suits = ["Spades","Clubs","Hearts","Diamonds"]
    ranks = ["Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Jack","Queen","King","Ace"]

    @classmethod
    def draw(cls):
        print("You drew the {} of {}!".format(random.choice(cls.ranks), random.choice(cls.suits)))

CardDeck.draw()

For realistic deck behavior (no duplicate draws), build a 52-card list, random.shuffle it once, and pop() to draw cards:

deck = [(r, s) for s in CardDeck.suits for r in CardDeck.ranks]
random.shuffle(deck)
rank, suit = deck.pop()
print("You drew the {} of {}!".format(rank, suit))

Notes: method names are conventionally lowercase with underscores (e.g. draw_card). Do not use self at class scope — self only exists inside instance methods. If calling a method on an instance, instantiate first (or use @classmethod / @staticmethod if calling directly from the class). These small changes cover the thread’s mistakes while preventing off-by-one bugs and duplicate draws.

Recommended Answers

All 7 Replies

Use "self"

import random
class CardDeck(self):
    self.suit = ["Spades","Clubs","Hearts","Diamonds"]
    self.number = ["Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King", "Ace"]
 
    def DrawCard(self):
        randomsuit = random.randrange(0,3)
        randomnumber = random.randrange(0,12)
        print ("You drew the " + self.number[randomnumber]+ " of " + self.suit[randomsuit] +"!")
 
CardDeck.DrawCard()

It's not tested, but should be worked.

Here is a little upgrade to your code.

import random
class Deck():
    def __init__(self):
        self.suit = ["Spades","Clubs","Hearts","Diamonds"]
        self.number = ["Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King", "Ace"]
    def DrawCard(self):
        randomsuit = random.randrange(0,3)
        randomnumber = random.randrange(0,12)
        print ("You drew the " + self.number[randomnumber]+ " of " +    self.suit[randomsuit] +"!") # Use "[]" in stead of "()" when using lists.  

x = Deck() # Create a new "Deck"
x.DrawCard() # Uses DrawCard

A few things to note.
~ Use brackets[] instead of parenthesis() when using lists.
~When defining functions in a class, you must put "self" 1st in the parenthesis.
There are a few other things, but I am not sure how to explain them.

commented: :) +1

Yup, I forgot init in my code. Sorry :)

NameError: name 'self' is not defined

Do I have to declare a fresh object?

Beautiful, I got it. Thanks for your help, fellas!

NameError: name 'self' is not defined

Do I have to declare a fresh object?

How do you get that error? Any one else ever have that error?

How do you get that error? Any one else ever have that error?

My code is not correct, in a previous post saying that I forgot "init".
Your code is correct. :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.