+
+Discussion 7: Object-Oriented Programming
+
+
+
+
+ - disc07.pdf
+
+
+
+
+ If there are fewer than 3 people in your group, feel free to merge your group with another group in the room.
+ +Now switch to Pensieve:
+ +-
+
- Everyone: Go to pensieve.co, log in with your @berkeley.edu email, and enter your group number (which was in the email that assigned you to this lab). +
Once you're on Pensieve, you don't need to return to this page; Pensieve has all the same content (but more features). If for some reason Penseive doesn't work, return to this page and continue with the discussion.
+ + +Getting Started
+ + +Say your name and something you've +practiced for a while, such as playing an instrument, juggling, or martial arts. +Did you discover any common interests among your group members?
+ + +Object-Oriented Programming
+ + +A productive approach to defining new classes is to determine what instance +attributes each object should have and what class attributes each class should +have. First, describe the type of each attribute and how it will be used, then +try to implement the class's methods in terms of those attributes.
+ + +Q1: Keyboard
+ + +Overview: A keyboard has a button for every letter of the alphabet. When a
+button is pressed, it outputs its letter by calling an output
function (such
+as print
). Whether that letter is uppercase or lowercase depends on how many
+times the caps lock key has been pressed.
First, implement the Button
class, which takes a lowercase letter
(a
+string) and a one-argument output
function, such as Button('c', print)
.
The press
method of a Button
calls its output
attribute (a function) on
+its letter
attribute: either uppercase if caps_lock
has been pressed an odd
+number of times or lowercase otherwise. The press
method also increments
+pressed
and returns the key that was pressed. Hint: 'hi'.upper()
evaluates
+to 'HI'
.
Second, implement the Keyboard
class. A Keyboard
has a dictionary called
+keys
containing a Button
(with its letter
as its key) for each letter in
+LOWERCASE_LETTERS
. It also has a list of the letters typed
, which may be
+a mix of uppercase and lowercase letters.
The type
method takes a string word
containing only lowercase letters. It
+invokes the press
method of the Button
in keys
for each letter in word
,
+which adds a letter (either lowercase or uppercase depending on caps_lock
) to
+the Keyboard
's typed
list. Important: Do not use upper
or letter
in
+your implementation of type
; just call press
instead.
Read the doctests and talk about:
+ +-
+
- Why it's possible to press a button repeatedly with
.press().press().press()
.
+ - Why pressing a button repeatedly sometimes prints on only one line and sometimes + prints multiple lines. +
- Why
bored.typed
has 10 elements at the end.
+
Discussion Time: Before anyone types anything, have a conversation
+describing the type of each attribute and how it will be used. Start with
+Button
: how will letter
and output
be used? Then discuss Keyboard
: how
+will typed
and keys
be used? How will new letters be added to the list
+called typed
each time a Button
in keys
is pressed? Call the staff if
+you're not sure! Once everyone understands the answers to these questions, you
+can try writing the code together.
LOWERCASE_LETTERS = 'abcdefghijklmnopqrstuvwxyz'
+
+class CapsLock:
+ def __init__(self):
+ self.pressed = 0
+
+ def press(self):
+ self.pressed += 1
+
+class Button:
+ """A button on a keyboard.
+
+ >>> f = lambda c: print(c, end='') # The end='' argument avoids going to a new line
+ >>> k, e, y = Button('k', f), Button('e', f), Button('y', f)
+ >>> s = e.press().press().press()
+ eee
+ >>> caps = Button.caps_lock
+ >>> t = [x.press() for x in [k, e, y, caps, e, e, k, caps, e, y, e, caps, y, e, e]]
+ keyEEKeyeYEE
+ >>> u = Button('a', print).press().press().press()
+ A
+ A
+ A
+ """
+ caps_lock = CapsLock()
+
+ def __init__(self, letter, output):
+ assert letter in LOWERCASE_LETTERS
+ self.letter = letter
+ self.output = output
+ self.pressed = 0
+
+ def press(self):
+ """Call output on letter (maybe uppercased), then return the button that was pressed."""
+ self.pressed += 1
+ if self.caps_lock.pressed % 2 == 1:
+ self.output(self.letter.upper())
+ else:
+ self.output(self.letter)
+ return self
+
+
+ self.letter
is always lowercase, use self.letter.upper()
to produce the uppercase version.
+caps_lock
has been pressed is either
+self.caps_lock.pressed
or Button.caps_lock.pressed
.
+output
attribute is a function that can be called:
+self.output(self.letter)
or self.output(self.letter.upper())
. You do not
+need to return the result.
+class Keyboard:
+ """A keyboard.
+
+ >>> Button.caps_lock.pressed = 0 # Reset the caps_lock key
+ >>> bored = Keyboard()
+ >>> bored.type('hello')
+ >>> bored.typed
+ ['h', 'e', 'l', 'l', 'o']
+ >>> bored.keys['l'].pressed
+ 2
+
+ >>> Button.caps_lock.press()
+ >>> bored.type('hello')
+ >>> bored.typed
+ ['h', 'e', 'l', 'l', 'o', 'H', 'E', 'L', 'L', 'O']
+ >>> bored.keys['l'].pressed
+ 4
+ """
+ def __init__(self):
+ self.typed = []
+ self.keys = {c: Button(c, self.typed.append) for c in LOWERCASE_LETTERS}
+
+ def type(self, word):
+ """Press the button for each letter in word."""
+ assert all([w in LOWERCASE_LETTERS for w in word]), 'word must be all lowercase'
+ for w in word:
+ self.keys[w].press()
+
+
+ self.keys = {c: Button(c, ...) for c in LETTERS}
.
+The call to Button
should take c
and an output function that appends to self.typed
, so that every time
+one of these buttons is pressed, it appends a letter to self.typed
.
+press
method of self.key[w]
for each w
in word
. It should be
+the case that when you call press
, the Button
is already set up (in the
+Keyboard.__init__
method) to output to the typed
list of this Keyboard
.
+Description Time: Describe how new letters are added to
+typed
each time a Button
in keys
is pressed. Instead of just reading
+your code, say what it does (e.g., "When the button of a keyboard is pressed ...").
+One short sentence is enough to describe how new letters are added to typed
.
Document the Occasion
+ + +Please all fill out the attendance form (one submission per person per week).
+ + +