Mark February 2016

How to get a retrieve a string from a tuple directly?

class Card:
    def __init__(self, suit):
        self.suit = SUITS[suit]
    SUITS = ("HEARTS", "SPADES", "DIAMONDS", "CLUBS")

Is there anyway to directly access only one of these four values from the tuple and store it? so that i can make a new object of type Card and then set its suit, only to one of the four values in the tuple.

i would like to take a string as the input parameter e.g myCard = Card(HEARTS)

Answers


mhawke February 2016

Within your class you need to prefix SUITS with Card (or self) like this:

class Card:
    def __init__(self, suit):
        self.suit = Card.SUITS[suit]    # N.B. specify the class
    SUITS = ("HEARTS", "SPADES", "DIAMONDS", "CLUBS")

>>> for i in range(len(Card.SUITS)):
...     c = Card(i)
...     print(c.suit)
HEARTS
SPADES
DIAMONDS
CLUBS

I wouldn't bother with validating the suit argument; if an invalid value is supplied Card.SUITS[suit] will raise IndexError if it is out of range, or TypeError if a non-integer argument is supplied. You could catch either exception and raise your own, if you wanted.


keksnicoh February 2016

You can validate against SUITS. If invalid suit given, may you raise a ValueError

class Card:
    SUITS = ("HEARTS", "SPADES", "DIAMONDS", "CLUBS")
    def __init__(self, suit):
        if suit not in self.SUITS:
             raise ValueError('invalid argument suit. must be: {}'.format(
                  ', '.join(self.SUITS)
             ))
        self.suit = suit

One can now create an instance by

burp = Card('SPADES')

Another way could be to use Enum's here:

from enum import Enum
class Suits(Enum):
    HEARTS = 0
    SPADES = 1
    DIAMONDS = 2
    CLUBS = 3

class Card:
    def __init__(self, suit):
        assert(type(suit) is Suits)
        self.suit = suit

snurz = Card(Suits.CLUBS)


Pynchia February 2016

In case you want to assign self.suit to the given name if the value is among the acceptable ones and otherwise assign it to a default value

>>> class Card:
...     SUITS = {"HEARTS", "SPADES", "DIAMONDS", "CLUBS"} # you can still use the tuple if you prefer
...     def __init__(self, suit):
...         self.suit = suit if suit in self.SUITS else 'HEARTS' # default_value
... 
>>> c=Card('abc')
>>> c.suit
'HEARTS'
>>> c=Card('DIAMONDS')
>>> c.suit
'DIAMONDS'

Note: I agree with @keksnicoh's approach (upvoted), which raises an exception.

Another way can be to pass the default value as a parameter as well (explicit is better than implicit, remember?)

>>> class Card:
...     SUITS = ("HEARTS", "SPADES", "DIAMONDS", "CLUBS")
...     def __init__(self, suit, default='HEARTS'):
...         self.suit = suit if suit in self.SUITS else default
... 
>>> c=Card('abc')
>>> c.suit
'HEARTS'
>>> c=Card('abc', 'DIAMONDS')
>>> c.suit
'DIAMONDS'

However, you should still check if the default values is among the possible values and at that point raise and exception (or add it to them, depending on your goals)

Post Status

Asked in February 2016
Viewed 2,113 times
Voted 5
Answered 3 times

Search




Leave an answer