[2021 spring] CS61A Lab 8: Midterm Review
Lab08: https://inst.eecs.berkeley.edu/~cs61a/sp21/lab/lab08/#recursion-and-tree-recursion
期中复习,有些内容有点忘了,先写OOP。
Objects
Q6: Keyboard
按照doctest来写就好了,注意typing时调用press。
class Button:
"""
Represents a single button
"""
def __init__(self, pos, key):
"""
Creates a button
"""
self.pos = pos
self.key = key
self.times_pressed = 0
class Keyboard:
"""A Keyboard takes in an arbitrary amount of buttons, and has a
dictionary of positions as keys, and values as Buttons.
>>> b1 = Button(0, "H")
>>> b2 = Button(1, "I")
>>> k = Keyboard(b1, b2)
>>> k.buttons[0].key
'H'
>>> k.press(1)
'I'
>>> k.press(2) #No button at this position
''
>>> k.typing([0, 1])
'HI'
>>> k.typing([1, 0])
'IH'
>>> b1.times_pressed
2
>>> b2.times_pressed
3
"""
def __init__(self, *args):
self.buttons = {}
for i in range(len(args)):
self.buttons[i] = args[i]
def press(self, info):
"""Takes in a position of the button pressed, and
returns that button's output"""
if info in self.buttons:
button = self.buttons[info]
button.times_pressed += 1
return button.key
return ""
def typing(self, typing_input):
"""Takes in a list of positions of buttons pressed, and
returns the total output"""
output = ""
for index in typing_input:
output += self.press(index)
return output
Q7: Bank Account
Account允许客户向账户中存钱,从账户中取钱,查看交易记录,取钱不能超过余额。
交易记录以元组列表的形式储存。
为了__repr__不再计算transaction中的存取款次数,直接初始化两个次数参数。
class Account:
"""A bank account that allows deposits and withdrawals.
It tracks the current account balance and a transaction
history of deposits and withdrawals.
>>> eric_account = Account('Eric')
>>> eric_account.deposit(1000000) # depositing paycheck for the week
1000000
>>> eric_account.transactions
[('deposit', 1000000)]
>>> eric_account.withdraw(100) # make a withdrawal to buy dinner
999900
>>> eric_account.transactions
[('deposit', 1000000), ('withdraw', 100)]
>>> print(eric_account) #call to __str__
Eric's Balance: $999900
>>> eric_account.deposit(10)
999910
>>> eric_account #call to __repr__
Accountholder: Eric, Deposits: 2, Withdraws: 1
"""
interest = 0.02
def __init__(self, account_holder):
self.balance = 0
self.holder = account_holder
"*** YOUR CODE HERE ***"
self.transactions = []
self.deposits = 0
self.withdraws = 0
def deposit(self, amount):
"""Increase the account balance by amount, add the deposit
to the transaction history, and return the new balance.
"""
"*** YOUR CODE HERE ***"
self.balance += amount
self.transactions.append(('deposit', amount))
self.deposits += 1
return self.balance
def withdraw(self, amount):
"""Decrease the account balance by amount, add the withdraw
to the transaction history, and return the new balance.
"""
"*** YOUR CODE HERE ***"
if amount <= self.balance:
self.balance -= amount
self.transactions.append(('withdraw', amount))
self.withdraws += 1
return self.balance
def __str__(self):
"*** YOUR CODE HERE ***"
return f"{self.holder}'s Balance: ${self.balance}"
def __repr__(self):
"*** YOUR CODE HERE ***"
return f"Accountholder: {self.holder}, Deposits: {self.deposits}, Withdraws: {self.withdraws}"
Mutable Lists
Q8: Trade
存在前缀m和n使列表1的前m个元素和列表2的前n个元素和相等,则进行交换。
def trade(first, second):
"""Exchange the smallest prefixes of first and second that have equal sum.
>>> a = [1, 1, 3, 2, 1, 1, 4]
>>> b = [4, 3, 2, 7]
>>> trade(a, b) # Trades 1+1+3+2=7 for 4+3=7
'Deal!'
>>> a
[4, 3, 1, 1, 4]
>>> b
[1, 1, 3, 2, 2, 7]
>>> c = [3, 3, 2, 4, 1]
>>> trade(b, c)
'No deal!'
>>> b
[1, 1, 3, 2, 2, 7]
>>> c
[3, 3, 2, 4, 1]
>>> trade(a, c)
'Deal!'
>>> a
[3, 3, 2, 1, 4]
>>> b
[1, 1, 3, 2, 2, 7]
>>> c
[4, 3, 1, 4, 1]
"""
m, n = 1, 1
equal_prefix = lambda: sum(first[:m]) == sum(second[:n])
while m < len(first) and m < len(second) and not equal_prefix():
if sum(first[:m]) < sum(second[:n]):
m += 1
else:
n += 1
if equal_prefix():
first[:m], second[:n] = second[:n], first[:m]
return 'Deal!'
else:
return 'No deal!'
Q9: Shuffle
洗牌,每次shuffle都将牌组前半部分和后半部分交错
def card(n):
"""Return the playing card numeral as a string for a positive n <= 13."""
assert type(n) == int and n > 0 and n <= 13, "Bad card n"
specials = {1: 'A', 11: 'J', 12: 'Q', 13: 'K'}
return specials.get(n, str(n))
def shuffle(cards):
"""Return a shuffled list that interleaves the two halves of cards.
>>> shuffle(range(6))
[0, 3, 1, 4, 2, 5]
>>> suits = ['♡', '♢', '♤', '♧']
>>> cards = [card(n) + suit for n in range(1,14) for suit in suits]
>>> cards[:12]
['A♡', 'A♢', 'A♤', 'A♧', '2♡', '2♢', '2♤', '2♧', '3♡', '3♢', '3♤', '3♧']
>>> cards[26:30]
['7♤', '7♧', '8♡', '8♢']
>>> shuffle(cards)[:12]
['A♡', '7♤', 'A♢', '7♧', 'A♤', '8♡', 'A♧', '8♢', '2♡', '8♤', '2♢', '8♧']
>>> shuffle(shuffle(cards))[:12]
['A♡', '4♢', '7♤', '10♧', 'A♢', '4♤', '7♧', 'J♡', 'A♤', '4♧', '8♡', 'J♢']
>>> cards[:12] # Should not be changed
['A♡', 'A♢', 'A♤', 'A♧', '2♡', '2♢', '2♤', '2♧', '3♡', '3♢', '3♤', '3♧']
"""
assert len(cards) % 2 == 0, 'len(cards) must be even'
half = _______________
shuffled = []
for i in _____________:
_________________
_________________
return shuffled
交叉append
def shuffle(cards):
assert len(cards) % 2 == 0, 'len(cards) must be even'
half = cards[(len(cards)//2):]
shuffled = []
for i in range(len(half[:])):
shuffled.append(cards[i])
shuffled.append(half[i])
return shuffled
Linked Lists
Q10: Insert
在Link的指定index处插入value。
在当前节点current插入新节点,表示current.rest变为current.rest.rest,current.fisrt = value。使用Link类。
def insert(link, value, index):
"""Insert a value into a Link at the given index.
>>> link = Link(1, Link(2, Link(3)))
>>> print(link)
<1 2 3>
>>> other_link = link
>>> insert(link, 9001, 0)
>>> print(link)
<9001 1 2 3>
>>> link is other_link # Make sure you are using mutation! Don't create a new linked list.
True
>>> insert(link, 100, 2)
>>> print(link)
<9001 1 100 2 3>
>>> insert(link, 4, 5)
Traceback (most recent call last):
...
IndexError: Out of bounds!
"""
"*** YOUR CODE HERE ***"
if index == 0:
link.rest = Link(link.first, link.rest)
link.first = value
elif not link.rest:
raise IndexError('Out of bounds!')
else:
insert(link.rest, value, index - 1)