Alex Lee
Alex Lee

Reputation: 33

Inheritances and overloading methods

I've created a class called Card, which takes a number and gives the following output depending on the methods called:

class Card:

def __init__(self, number):
    self.number = number

def suit(self):
    if self.number in range(0, 13):
        return 0
    elif self.number in range(13, 26):
        return 1
    elif self.number in range(26, 39):
        return 2
    elif self.number in range(39, 52):
        return 3

def rank(self):
    if self.number in range(0, 13):
        return self.number
    elif self.number in range(13, 26):
        return self.number - 13
    elif self.number in range(26, 39):
        return self.number - 26
    elif self.number in range(39, 52):
        return self.number - 39

def points(self):
    if self.number in (12,25,38,51):
        return 4
    elif self.number in (11,24,37,50):
        return 3
    elif self.number in (10,23,36,49):
        return 2
    elif self.number in (9,22,35,48):
        return 1
    else:
        return 0
def __repr__(self):
    ranks = ['2','3','4','5','6','7','8','9','10','J','Q','K','A']

    if self.number in range(0, 13):
        return ranks[self.number] + '\u2663'

    elif self.number in range(13, 26):
        return ranks[self.number - 13] + '\u2666'

    elif self.number in range(26, 39):
        return ranks[self.number - 26] + '\u2665'

    elif self.number in range(39, 52):
        return ranks[self.number - 39] + '\u2660'

def __lt__(self,other):
    if str(self.rank) < str(other.rank):
        return True
    else:
        return False

* any tips on making the code better are appreciated

Now I have to write a class called BlackjackCard with Card class inherited:

class BlackjackCard(Card):

def __init__(self, number):
    Card.__init__(self, number)

def points(self):

    if self.rank == 12:
        return 11
    elif self.rank in (11,10,9):
        return 10
    elif self.rank < 11:
        return self.rank

I am trying to overload the method points() by rewriting but I can't seem to implement self.rank from class Card. When I assign y = BlackjackCard(38) and executey.points(), it gives me a type error: unorderable types: method() < int().

What am I doing wrong here?

Upvotes: 0

Views: 65

Answers (2)

TheBlackCat
TheBlackCat

Reputation: 10298

Ignacio's answer is the right one (using property), but in terms of improving your code in general, a few suggestions.

First, instead of if foo in range(a, b):, you can just do if a <= foo < b: But in your case, you can simplify this further using math. The suit is just floor(number/13), or more simply number//13. Similarly, the rank is the the remainder of number/13, the modulo of 13, which is number%13.

Second, rather than re-calculate everything every time, you can re-use the result of one method in another. For example, you re-calculate the suit in __repr__.

Finally, boolean tests in python, like x < y, resolve to True or False. So rather than return True if the test passes and False if it doesn't, you can just return the result of the test exactly.

Also, I don't think you want to return the str of the rank in __lt__, but rather the numerical rank.

So here is my improved version:

class Card:
    def __init__(self, number):
        self.number = number

    @property
    def suit(self):
        return self.number // 13

    @property
    def rank(self):
        return self.number % 13

    @property
    def points(self):
        return max(0, self.rank-8)

    @property
    def suit_str(self):
        suits = ['\u2663', '\u2666', '\u2665', '\u2660']
        return suites[self.suit]

    @property
    def rank_str(self):
        ranks = {9: 'J', 10: 'Q', 11: 'K', 12: 'A'}
        return ranks.get(self.rank, str(self.rank+2))

    def __repr__(self):
        return self.rank_str+self.suit_str

    def __lt__(self, other):
        return self.rank < other.rank

Upvotes: 0

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798606

self.rank is a method. Either call it by adding parens (self.rank()), or convert it into a property.

Upvotes: 2

Related Questions