Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

1. Modify the Deck class to keep track of the current size of the deck using an

ID: 3750283 • Letter: 1

Question

1. Modify the Deck class to keep track of the current size of the deck using

an instance variable. Does this change the run-time efficiency of the size
operation? Do a bit of research to answer this question.
2. Look into the functions provided by the Python random module to simplify
the shuffling code in the Deck class.
3. Suppose we want to be able to place cards back into a deck. Modify the Deck
class to include the operations addTop, addBottom, and addRandom (the last
one inserts the card at a random location in the deck).

Explanation / Answer

Please let me know if you have any doubts or you want me to modify the code. And if you find this code useful then don't forget to rate my answer as thumps up. Thank you! :)


# Deck.py

from random import randrange
import random
from Card import Card


class Deck(object):
    # ------------------------------------------------------------

    def __init__(self):

        """post: Creates a 52 card deck in standard order"""
        size = 0 # Variable to give current size
        cards = []
        for suit in Card.SUITS:
            for rank in Card.RANKS:
                cards.append(Card(rank, suit))
                size += 1 # Keep track of size
        self.cards = cards

    # ------------------------------------------------------------

    def size(self):

        """Cards left
        post: Returns the number of cards in self"""

        # return len(self.cards)
        return self.size

    # ------------------------------------------------------------

    def deal(self):

        """Deal a single card
        pre: self.size() > 0
        post: Returns the next card, and removes it from self.card if
        the deck is not empty, otherwise returns False"""

        if self.size() > 0:
            return self.cards.pop()
        else:
            return False

    # ------------------------------------------------------------

    def shuffle(self):

        """Shuffles the deck
        post: randomizes the order of cards in self"""

        '''n = self.size()
        cards = self.cards
        for i, card in enumerate(cards):
            pos = randrange(i, n)
            cards[i] = cards[pos]
            cards[pos] = card
        '''

        random.shuffle(self.cards) # Shuffling list with random.shuffle() function

    def addTop(self, card):
        self.cards = self.cards + [card] # Adding card at the top i.e. as the last element

    def addBottom(self, card):
        self.cards = [card] + self.cards # Add element at the first position

    def addRandom(self, card):
        # Adding card at randomly selected positionwith the help of slicing
        pos = randrange(range(self.size()))
        self.cards = self.cards[1: pos] + [card] + self.cards[pos:]


Question 1:

Even after tracking the size of the deck with a variable, it does not change the run-time efficiency of the size operation because the complexity of len() function always O(1) and returning self.size is also O(1).

Question 2:

To shuffle a list of objects, we can use random.shuffle(list).

Question 3:

Functions have been written with the help of list operations.