Classes#
Q&A
Q: Why do loops exist?
A: To allow you to repeat code again and again without having to copy + paste very similar code over and over again and change one little bit.
Q: How to know when to use certain methods?
A: The “real” answer is ….you get famililar over time. The answer for when starting out is: if it feels like you’re doing a task that someone else has also probably wanted to do with this variable type (i.e. add something to a list), it’s worth pausing and looking up if there’s already a method to accomplish what you want to do before writing the code yourself. On exams, you need to knowappend()anditems(). All of the others will be described, but you’ll need to know how to then use it.
Q: You mentioned that “my_variable.function_call() acts like function_call(my_variable).” Why do we have methods if they work this way as well?
A: Because methods have the addded feature that they “belong” to an object. This keeps things organized (you’ll see this more today!) and necessitates that they are syntactically distinct (meaningmy_variable.method()vsfunction(my_variable).
Course Announcements
Due this week:
CL5 due Fri
Mid-course survey “due” (for extra credit) Sunday - link also on Canvas assignment
Classes Overview#
Objects
Classes
Attributes
Methods
Instances
__init__
…and f-strings
Objects#
from datetime import date
my_date = date(year=1988, month=9, day=29)
print(my_date)
type(my_date)
Attributes#
Attributes look up & return information about the object.
attributes maintain the object’s state, simply returning information about the object to you
my_date.day
my_date.year
Methods#
These are functions that belong to and operate on the object directly.
methods modify the object’s state
# Method to return what day of the week the date is
my_date.weekday()
my_date.weekday?
Activity: ~Methods~ Objects#
Complete the Google Form questions here: https://forms.gle/xv313353UdSNCVuL8
Feel free to chat with and ask questions of your neighbors!
Objects Summary#
Objects allow for data (attributes) and functions (methods) to be organized together
methods operate on the object type (modify state)
attributes store and return information (data) about the object (maintain state)
dir()returns methods & attributes for an objectSyntax:
obj.method()obj.attribute
dateanddatetimeare two types of objects in Python
dir(my_date)
class#
a blueprint for creating objects
contain attributes & methods
attributes: variables attached to the object
methods: functions attached to the object
review: Dog#
[Note: this is what the textbook/videos walked through in detail.]
class Dog():
# class attribute - value will be the same for every Dog
sound = 'Woof'
# instance attribute
def __init__(self, name, breed):
self.name = name
self.breed = breed
# method
def speak(self, n_times=2):
return self.sound * n_times
# creating an instance
my_dog = Dog('Lexi', 'Italian Greyhound')
# accessing attributes
my_dog.sound
my_dog.name
my_dog.breed
# methods - with default
my_dog.speak()
# method - other value for n_times parameter
my_dog.speak(4)
Code Style: Classes#
CapWords for class names
one blank line between methods/functions
Good Code Style
class MyClass():
def __init__(self, name, email, score):
self.name = name
self.email = email
self.score = score
def check_score(self):
if self.score <= 65:
return self.email
else:
return None
cogs18 = MyClass('shannon', 'sellis@ucsd.edu', 60)
cogs18.check_score()
Code Style to Avoid
class my_class(): # uses snake case for name
def __init__(self, name, email, score):
self.name = name
self.email = email
self.score = score # no blank lines between methods
def check_score(self):
if self.score <= 65:
return self.email
else:
return None
Activity: Instances#
Complete the Google Form questions here: https://forms.gle/BA9zC1zjiviqGHst8
Feel free to chat with and ask questions of your neighbors!
Example: ProfCourses()#
Let’s put a lot of these concepts together in a more complicated example…
What if we wanted some object type that would allow us to keep track of Professor Ellis’ Courses? Well…we’d want this to work for any Professor, so we’ll call it ProfCourses.
We would likely want an object type and then helpful methods that allow us to add a class to the course inventory and to compare between courses.
[This is also worked in the textbook, but was not required reading/discussed in the video.]
class ProfCourses():
# create three instance attributes
def __init__(self, prof):
self.n_courses = 0
self.courses = []
self.prof = prof
ellis_courses = ProfCourses('Ellis')
print(ellis_courses.n_courses)
print(ellis_courses.prof)
add_class() method
class ProfCourses():
def __init__(self, prof):
self.n_courses = 0
self.courses = []
self.prof = prof
# add method that will add courses as a dictionary
# to our attribute (courses)...which is a list
def add_course(self, course_name, quarter, n_students):
self.courses.append({'course_name': course_name,
'quarter' : quarter,
'n_students': n_students})
# increase value store in n_courses
# by 1 any time a class is added
self.n_courses += 1
# create ellis_courses
ellis_courses = ProfCourses('Ellis')
# add a class
ellis_courses.add_course('COGS18', 'fa20', 363)
# see output
print(ellis_courses.courses)
ellis_courses.n_courses
compare() method
class ProfCourses():
def __init__(self, prof):
self.n_courses = 0
self.courses = []
self.prof = prof
def add_course(self, course_name, quarter, n_students):
self.courses.append({'course_name': course_name,
'quarter' : quarter,
'n_students': n_students})
self.n_courses += 1
# add method to compare values in courses
def compare(self, attribute, direction='most'):
fewest = self.courses[0]
most = self.courses[0]
for my_course in self.courses:
if my_course[attribute] <= fewest[attribute]:
fewest = my_course
elif my_course[attribute] >= most[attribute]:
most = my_course
if direction == 'most':
output = most
elif direction == 'fewest':
output = fewest
return output
# create ellis_courses
ellis_courses = ProfCourses('Ellis')
# add a bunch of classes
ellis_courses.add_course('COGS18', 'fa20', 363)
ellis_courses.add_course('COGS108', 'fa20', 447)
ellis_courses.add_course('COGS18', 'su20', 88)
ellis_courses.add_course('COGS108', 'sp20', 469)
# see the courses
print(ellis_courses.n_courses)
ellis_courses.courses
# make comparison among all courses
# returns the class with the most students
ellis_courses.compare('n_students')
# return the class with the fewest students
ellis_courses.compare('n_students', 'fewest')
extending the functionality of the compare() method
class ProfCourses():
def __init__(self, prof):
self.n_courses = 0
self.courses = []
self.prof = prof
def add_course(self, course_name, quarter,
n_students, n_exams, n_assignments):
# add in additional key-value pairs
self.courses.append({'course_name': course_name,
'quarter' : quarter,
'n_students': n_students,
'n_exams' : n_exams,
'n_assignments' : n_assignments}) # <-- changes made in courses
self.n_courses += 1
def compare(self, attribute, direction='most'):
fewest = self.courses[0]
most = self.courses[0]
for my_course in self.courses:
if my_course[attribute] <= fewest[attribute]:
fewest = my_course
elif my_course[attribute] >= most[attribute]:
most = my_course
if direction == 'most':
output = most
elif direction == 'fewest':
output = fewest
return output
# create ellis_courses
ellis_courses = ProfCourses('Ellis')
# add a bunch of classes
ellis_courses.add_course('COGS18', 'fa20', 363, 2, 5)
ellis_courses.add_course('COGS108', 'fa20', 447, 0, 6)
ellis_courses.add_course('COGS18', 'su20', 88, 3, 5)
ellis_courses.add_course('COGS108', 'sp20', 469, 0, 6)
ellis_courses.add_course('COGS108', 'sp19', 825, 0, 5)
ellis_courses.add_course('COGS18', 'fa19', 301, 2, 4)
ellis_courses.add_course('COGS18', 'wi22', 355, 2, 4)
ellis_courses.add_course('COGS18', 'sp23', 355, 2.5, 5)
ellis_courses.add_course('COGS137', 'fa23', 70, 2, 3)
ellis_courses.add_course('COGS169', 'fa23', 58, 2, 0)
ellis_courses.add_course('COGS108', 'wi24', 656, 0, 4)
ellis_courses.add_course('COGS18', 'sp24', 621, 2.5, 5)
ellis_courses.add_course('COGS137', 'fa24', 100, 0, 3)
ellis_courses.add_course('COGS169', 'fa24', 52, 2, 0)
ellis_courses.add_course('COGS18', 'sp25', 630, 2.5, 5)
# see the courses
print(ellis_courses.n_courses)
# return the class with the most exams
ellis_courses.compare('n_exams', 'most')
# return the class with the fewest assignments
ellis_courses.compare('n_assignments', 'fewest')
Activity: ProfCourses Understanding Check#
Complete the Google Form questions here: https://forms.gle/mXX1veAdvDgriApP6
Feel free to chat with and ask questions of your neighbors!
Improving & updating this code
account for ties in
compare()edit code in
compare()usemax()andmin()instead of loopingadd a method to put dictionary in time order
etc.
Classes Review#
classcreates a new class typenames tend to use CapWords case
can have attributes (including instance attributes) and methods
obj.attributeaccesses data stored in attributeobj.method()carries out code defined within method
instance attributes defined with
__init____init__is a reserved method in PythonThis “binds the attributes with the given arguments”
selfrefers to current instance
to create an object (instance) of a specified class type (
ClassType):object_name = ClassType(input1, input2)selfis not given an input when creating an object of a specified class
String Concatenation#
(revisited)
# string concatenation - old way
name = 'Shannon'
name2 = 'Ellis'
name + ' ' + name2
f-Strings#
You can put variables inside of a string by using f-strings.
To create an f-string you will need to put f", an f with double quotation marks infront of it.
Then put any variable name using curly braces {}
Lastly, end your statement with the remaining "
# f strings - new way
f"{name} {name2}"
class CollegeStudent():
def __init__(self, name, age, major, college):
self.name = name
self.age = age
self.major = major
self.college = college
def introduction(self):
return f"Hi, my name is {self.name}, and I am {self.age} years old. I study {self.major} at {self.college}."
my_student = CollegeStudent('Shannon', 37, 'Biology', "King's College")
my_student.name
my_student.college
my_student.introduction()