Advanced Python
Projects, Session 6
6.1 | class Deck. Create a class, Deck, which starts with a list of all 52 cards, and allows the user to "pick a card" from the deck, after which the deck will no longer contain the card. The class also allows for shuffling (randomly reordering) of the deck. | ||||||||||||||
This is just a demo, but to test your solution please use the longer example at bottom:
d = Deck() # generates a 52-card deck
card = d.pick() # str, 'Ace of Hearts' (top card)
card2 = d.pick_any() # str, '5 of Clubs' (random card)
d.shuffle() # None (shuffles cards internally)
card3 = d.pick() # str, '9 of Spades' (top card,
# now random because of shuffle)
|
|||||||||||||||
|
|||||||||||||||
Generating the deck as a list of strings can be accomplished with this code. (It is recommended to try this in isolation and view the results before proceeding). This code should be contained within the class (except for imports). (Since the deck is supposed to be created each time you construct a new Deck instance, this code should be in the __init__() method.)
suits = ['Hearts', 'Diamonds', 'Clubs', 'Spades']
ranks = ['Ace', '2', '3', '4', '5', '6', '7', '8',
'9', '10', 'Jack', 'Queen', 'King']
deck = []
for suit in suits:
for rank in ranks:
card = f"{rank} of {suit}"
deck.append(card)
|
|||||||||||||||
The nested 'for' loop means we will see every pair combination from the two lists in the new list. |
|||||||||||||||
Picking the 'top' card can be accomplished by simply popping the first item from the internal list of cards. This removes and returns the first item from the list.
creturs = ['bear', 'vole', 'muskrat', 'bobcat', 'fox']
item = creturs.pop(0) # str, 'bear' (first item)
print(creturs) # ['vole', 'muskrat', 'bobcat', 'fox']
|
|||||||||||||||
|
|||||||||||||||
Picking a random card can be accomplished with the random.choice() function:
import random
fruits = ['apple', 'banana', 'orange', 'pear']
snack = random.choice(fruits) # str, 'orange' (randomly selected)
|
|||||||||||||||
|
|||||||||||||||
'Shuffling' (random reordering) of a list can be accomplished with the random.shuffle() function:
fruits = ['apple', 'banana', 'orange', 'pear']
fruits = random.shuffle(fruits) # ['orange', 'banana', 'pear', 'apple']
# (random order)
|
|||||||||||||||
|
|||||||||||||||
We can remove a particular item from the list using the list .remove() method:
fruits.remove(snack)
print(fruits) # ['banana', 'pear', 'apple']
|
|||||||||||||||
|
|||||||||||||||
print('generating new deck...')
print()
d = Deck()
print('picking card from deck 53 times...')
print()
for i in range(53):
card = d.pick() # should show all cards, in order
print(card) # when all the cards are gone, must return None
if card is not None:
print('error: .pick() must return the None value (not ' +
"string 'None')")
exit()
print()
print('generating a new deck...')
e = Deck()
print('picking first card from new deck...')
print()
ecard = e.pick()
print(ecard) # should show Ace of Hearts
print(); print()
print('picking random card from new deck...')
print()
ecard = e.pick_any()
print(ecard) # should show random card
print(); print()
print('shuffling...')
print()
e.shuffle() # reorder cards internally
print('picking first card from the shuffled deck ...')
print()
ecard = e.pick()
print(ecard) # should show random card
print(); print()
print('attempting to pick from old deck again...')
print()
dcard = d.pick()
print(dcard) # must be None
|
|||||||||||||||
Sample program run:
generating new deck... picking card from deck 53 times... Ace of Hearts 2 of Hearts 3 of Hearts 4 of Hearts 5 of Hearts 6 of Hearts 7 of Hearts 8 of Hearts 9 of Hearts 10 of Hearts Jack of Hearts Queen of Hearts King of Hearts Ace of Diamonds 2 of Diamonds 3 of Diamonds 4 of Diamonds 5 of Diamonds 6 of Diamonds 7 of Diamonds 8 of Diamonds 9 of Diamonds 10 of Diamonds Jack of Diamonds Queen of Diamonds King of Diamonds Ace of Clubs 2 of Clubs 3 of Clubs 4 of Clubs 5 of Clubs 6 of Clubs 7 of Clubs 8 of Clubs 9 of Clubs 10 of Clubs Jack of Clubs Queen of Clubs King of Clubs Ace of Spades 2 of Spades 3 of Spades 4 of Spades 5 of Spades 6 of Spades 7 of Spades 8 of Spades 9 of Spades 10 of Spades Jack of Spades Queen of Spades King of Spades None generating a new deck... picking first card from new deck... Ace of Hearts picking random card from new deck... Queen of Clubs shuffling... picking first card from the shuffled deck ... 6 of Spades attempting to pick from old deck again... None |
|||||||||||||||
|
|||||||||||||||
6.2 | List of a Maximum Size. Create a class, MaxSizeList, that constructs instances that have a list as an attribute (set as an empty list in __init__). The constructor takes an integer as an argument, which becomes the maximum size of the list (stored as a second attribute). | ||||||||||||||
Add a method, push(), which appends a value to the list. However, if the list has already reached its maximum size (as set in the constructor), remove the first element from the list before appending the new element to the list. (You can use the list method pop() with an argument of 0 to remove the first element of the list, or you can use a slice (alist = alist[1:]).) |
|||||||||||||||
Sample code to use the class and expected output:
a = MaxSizeList(3)
b = MaxSizeList(1)
a.push("hey")
a.push("ho")
a.push("let's")
a.push("go")
b.push("hey")
b.push("ho")
b.push("let's")
b.push("go")
print(a.get_list()) # ['ho', "let's", 'go']
print(b.get_list()) # ['go']
|
|||||||||||||||
(hey! ho! let's go! is a reference to a song by the Ramones)
|
|||||||||||||||
print(MaxSizeList.icount) # 2
|
|||||||||||||||
|
|||||||||||||||
EXTRA CREDIT / SUPPLEMENTARY |
|||||||||||||||
6.3 | (extra credit / supplementary) class Text. | ||||||||||||||
class Text reads a file and exposes (i.e., makes available) methods for reading and inspecting the file. The file should be read only once, in the constructor. The methods manipulate the file data as specified, but do not attempt to read the file again. |
|||||||||||||||
t = Text('myfile.txt') # reads entire file into memory
print(t.filename) # myfile.txt
text = t.get_text() # returns entire file as string
bytes = t.get_size() # returns count of characters in file (use len())
words_list = t.get_words() # returns file split into list of words
lines_list = t.get_lines() # returns file as list of lines
found_lines = t.grep('horse') # returns only lines from file that
# contain the search term (use 'in')
word_dict = t.freq() # returns a dict of unique words paired
# with each word's integer frequency
# in the file
# have other ideas for what methods might be useful? include them!
|
|||||||||||||||
|
|||||||||||||||
6.4 | (extra credit / supplementary) Python API for Alpha Vantage. This optional assignment is designed to inspire you to consider how you might design a simplified interface to a service or data source. You may implement the example below, or substitute another file or service that interests you. | ||||||||||||||
The Alphavantage service is relatively easy to use, but it still requires that you remember how the data is structured and to write the necessary JSON or CSV parsing code. If you plan to access the service frequently from a Python program, it's best to write a module of functions, or class of methods, to make access convenient. Sample interface: again, you can design your own interface to whatever service, or part of the AA service, that you choose. You must implement at least two methods. |
|||||||||||||||
ibm = Prices('IBM', '15min', 'abc123') # ticker, interval, API key
print(ibm.symbol) # IBM
print(ibm.interval) # 15min
print(ibm.last_refreshed) # 2020-10-19 20:00:00
print(ibm.last('close')) # 121.8900
print(ibm.series('close')) # ["121.8900", "121.8000", "121.9300" ...]
|
|||||||||||||||
|
|||||||||||||||