revealOptions | ||
---|---|---|
|
- A text editor
- Terminal
- Python 3
- Installation guide
- If you don't have this installed, you can use repl.it for today
Girl Develop It is here to provide affordable and accessible programs to learn software through mentorship and hands-on instruction.
Some "rules":
- We are here for you!
- Every question is important
- Help each other
- Have fun
- Who are you?
- What do you hope to get out of the class?
- What music did you listen to today?
- Object-oriented programming (OOP)
- Handling errors
- Modules and packages
- Using 3rd party packages
- How the web works
- Automated testing
- Building a web app with Python
- A dash of NLP
When programs get large, we need a way to organize our code...
Group properties and behavior into logical units
- classes: The blueprints that create...
- instances: The real objects.
Photo credit: Wikimedia Commons
Classes implement...
- methods: The behavior that instances will have (
refuel
,setSpeed
) - attributes: The properties that instances will have (
fuel
,maxspeed
)
Photo credit: David Guo
Note: What are the properties of this marker? ...color... What are its behaviors? ...writes... We could have a Marker class, and each of these individual marker is a marker instance.
class DryEraseMarker:
def __init__(self, color):
self.color = color
def write(self, text):
return self.color + ': ' + text
blue_marker = DryEraseMarker(color='blue')
print(blue_marker.write('hi')) # => 'blue: hi'
red_marker = DryEraseMarker(color='red')
print(red_marker.write('bye')) # => 'red: bye'
Create a file called marker.py
and add the following code:
class DryEraseMarker:
def __init__(self, color):
self.color = color
__init__
is a special method for initializing instancesself
is the instance we're initializing- This is where we set attributes
Now write the following code:
class DryEraseMarker:
def __init__(self, color):
self.color = color
blue_marker = DryEraseMarker(color='blue')
print(blue_marker.color)
- Now we're instantiating a
Marker
- Try creating multiple instances
- Try changing an attribute of a marker
class DryEraseMarker:
def __init__(self, color):
self.color = color
blue_marker = DryEraseMarker(color='blue')
print(blue_marker.color) # => 'blue'
my_multi_color_marker = DryEraseMarker(color='red')
my_multi_color_marker.color = 'green'
print(my_multi_color_marker.color) # => 'green'
Now change your file to have the following:
class DryEraseMarker:
def __init__(self, color):
self.color = color
def write(self, text):
return self.color + ': ' + text
blue_marker = DryEraseMarker(color='blue')
print(blue_marker.color)
print(blue_marker.write('hi'))
write
is an instance methodself
is the instance calling the method
class DryEraseMarker:
def __init__(self, color):
self.color = color
def write(self, text):
return self.color + ': ' + text
blue_marker = DryEraseMarker(color='blue')
print(blue_marker.color)
print(blue_marker.write('hi')) # => 'blue: hi'
- Instantiate another
DryEraseMarker
and callwrite
with some text
class DryEraseMarker:
def __init__(self, color):
self.color = color
def write(self, text):
return self.color + ': ' + text
blue_marker = DryEraseMarker(color='blue')
print(blue_marker.color)
print(blue_marker.write('hi')) # => 'blue: hi'
red_marker = DryEraseMarker(color='red')
red_marker.write('bye') # => 'red: bye'
Process by which a "child" class derives data and behavior of a parent class
Photo credit: baseread.com
Note: The Vehicle class will have methods like move and steer. Because WheeledVehicle inherits from Vehicle, it doesn't need to implement those.
How can we represent other types of writing implements?
NOTE: Diagram class's suggestions on whiteboard
Create a file called writing.py
and add the following code:
class WritingImplement:
def __init__(self, color):
self.color = color
def write(self, text):
return self.color + ': ' + text
class DryEraseMarker(WritingImplement):
def erase(self):
return ''
DryEraseMarker
inherits fromWritingImplement
- What
attributes
does a DryEraseMarker have? What behaviors? - Try instantiating a DryEraseMarker again and calling
write
anderase
on it
class WritingImplement:
def __init__(self, color):
self.color = color
def write(self, text):
return self.color + ': ' + text
class DryEraseMarker(WritingImplement):
def erase(self):
return ''
blue_marker = DryEraseMarker(color='blue')
print(blue_marker.write('hi')) # => 'blue: hi'
print(blue_marker.erase()) # => ''
A DryEraseMarker
is a WritingImplement
class WritingImplement:
def __init__(self, color):
self.color = color
def write(self, text):
return self.color + ': ' + text
class EraseableWritingImplement(WritingImplement):
def erase(self):
return ''
class DryEraseMarker(EraseableWritingImplement):
def uncap(self):
return 'popped the cap off..'
class Pen(WritingImplement):
pass
Copy the following code:
class WritingImplement:
def __init__(self, color):
self.color = color
def write(self, text):
return self.color + ': ' + text
class EraseableWritingImplement(WritingImplement):
def erase(self):
return ''
class DryEraseMarker(EraseableWritingImplement):
def uncap(self):
return 'popped the cap off..'
How would you implement a pencil?
class Pencil(EraseableWritingImplement):
def sharpen(self):
return 'super sharp!'
A subclass can override the behavior of a superclass
A subclass can override the behavior of a superclass
class BoldMarker(WritingImplement):
# Override WritingImplement's write() method
def write(self, text):
# We call super() to get the parent
# class's method
ret = super().write(text) # => 'black: hi'
# Then we modify the return value of
# the parent class
return ret.upper()
bold_marker = BoldMarker('black')
print(bold_marker.write('hi')) # => BLACK: HI
- instance variable (you've seen this): specific to an instance
- color of a dry erase marker
- class variable: specific to a class, shared by all instances
- brand of dry erase markers
class DryEraseMarker(WritingImplement):
brand = 'Expo'
blue_marker = DryEraseMarker('red')
green_marker = DryEraseMarker('green')
# instance variables differ
blue_marker.color != green_marker.color # => True
# class variables are shared
blue_marker.brand == green_marker.brand # => True
Add a class variable to one or more of the classes you've written.
This is open-ended. Think: what properties should be shared among all instances of a class?
POINTED = 0
CHISEL = 1
class DryEraseMarker(WritingImplement):
label = 'low odor; dry erase'
tip = CHISEL
POINTED = 0
CHISELED = 1
class DryEraseMarker(WritingImplement):
label = 'low odor; dry erase'
tip = CHISELED
if blue_marker.tip == 0:
print('pointy')
else:
print('chisely')
# More readable
if blue_marker.tip == POINTED:
print('pointy')
else:
print('chisely')
- Sometimes errors are expected
- Need a way to do something when an error occurs
open('doesnotexist.txt')
# FileNotFoundError: [Errno 2] No such file or directory: 'doesnotexist.txt'
Handling the error:
try:
open('doesnotexist.txt')
except FileNotFoundError:
print('File does not exist.')
print('But the show must go on...')
- Sometimes we want our programs to raise an error
- Enforces contraints
- Use the
raise
keyword
raise Exception('some useful error message')
class WritingImplement:
def __init__(self, color):
if not isinstance(color, str):
raise TypeError('color must be a string')
self.color = color
# this will crash! (and that's a good thing)
bad_pen = WritingImplement(color=42)
# TypeError: color must be a string
Copy the following into your program:
class WritingImplement:
def __init__(self, color):
if not isinstance(color, str):
raise TypeError('color must be a string')
self.color = color
- Write code to create a
WritingImplement
calledpen
- Pass a
bool
as the color - Handle the TypeError and print
"No pen, no problem"
Extra credit:
- Instead of printing when a TypeError occurs, instantiate the pen
again, passing
"black"
as the color. then write"back in black"
with thepen
try:
pen = WritingImplement(color=True)
except TypeError:
print('No pen, no problem')
try:
pen = WritingImplement(color=True)
except TypeError:
pen = WritingImplement(color='black')
print(pen.write('back in black'))
- OOP helps us organize programs
- Groups data (attributes) and behavior (methods) into classes
- Classes are blueprints that create instances
- Inheritance allows child classes to derive data and behavior of a parent class
try/except
for handling errors,raise
for raising errors
- https://jeffknupp.com/blog/2014/06/18/improve-your-python-python-classes-and-object-oriented-programming/
- http://greenteapress.com/thinkpython/html/thinkpython016.html