Classes#
Key Ideas#
classes
objects
inheritance
Definition
Class is code that acts like a blueprint. “Objects” are made from classes. Classes can represent things in terms of code. For example, they could represent a car - make, model, year; a dog - dog name, breed, color; a person - first name, last name, address, city, state; etc.
Lecture Code#
Example 1 - Cars#
# -*- coding: utf-8 -*-
"""
Created on Mon Oct 2019
@author: jgoudy
"""
class car:
carspeed = 0
carengineOn = True
# constructor - there can only be one in python
def __init__(self, carmake="",carmodel="",caryear="", carcolor=""):
self.carspeed = 0
self.carengineOn = False
self.carmake = carmake
self.carmodel = carmodel
self.caryear= caryear
self.carcolor = carcolor
# __str__ defines what print() or str() is printed for the obje
# example print(car) = what is defined here is what will be printed
def __str__(self):
return ("Make: " + self.carmake + "\n" + \
"Model: " + self.carmodel + "\n" + \
"Year: " + self.caryear + "\n" + \
"Color: " + self.carcolor + "\n")
# __str__ must return string object
# whereas __repr__ can return any python expression.
#https://docs.python.org/3/reference/datamodel.html
# when possible it should return a string
def __repr__(self):
return (self.carmake+","+ self.carmodel+","+ self.caryear+","+ self.carcolor)
@property
def make(self):
return self.carmake
@make.setter
def make(self, value):
self.carmake = value
@property
def model(self):
return self.carmodel
@model.setter
def model(self, value):
self.carmodel = value
@property
def year(self):
return self.caryear
@year.setter
def year(self, value):
self.caryear = value
@property
def color(self):
return self.carcolor
@color.setter
def color(self, value):
self.carcolor = value
@property
def speed(self):
return self.carspeed
@property
def engineOn(self):
return self.carengineOn
def startCar(self):
self.carengineOn = True
def stopCar(self):
self.carengineOn = False
def accelerate(self,speed = 5):
if (self.carengineOn == True) :
self.carspeed += speed
print("aaargh")
else:
print("Start the car")
def deccelerate(self,speed = 5):
if self.carspeed > 0:
self.carspeed -= speed
else:
self.carspeed = 0
print("car is stopped")
def honk(self):
print("beep beep")
# --------------------------------------------------
def main():
mycar1 = car()
mycar2 = car("Ford", "Mustang","1967","red")
mycar2.accelerate()
mycar2.startCar()
mycar2.accelerate()
print(mycar2.speed)
mycar2.accelerate()
print(mycar2.speed)
mycar2.accelerate(50)
print(mycar2.speed)
mycar2.deccelerate(70)
print("The color of my car is " + mycar2.color)
mycar2.color = "blue"
print("The color of my car is " + mycar2.color)
mycar1.honk()
print("\bye bye")
main()
Example 2 - Person / Worker / Voter#
class Person:
""" Represents a person. """
# python can only have one constructor
def __init__(self, first_name="", last_name="", town=""):
self.first_name = first_name
self.last_name = last_name
self.town = town
# describes the class person
def __str__(self):
return self.first_name + ", " + self.last_name + ", " + self.town
# falls back to this if there is no __str__ - used in debugging
def __repr__(self):
return self.first_name + ", " + self.last_name + ", " + self.town
#CANNOT HAVE VARIABLE NAME SAME AS FUNCTION NAME
@property
def firstname(self):
return self.first_name
@firstname.setter
def firstname(self, first_name):
self.first_name = first_name
@property
def lastname(self):
return self.last_name
@lastname.setter
def lastname(self, last_name):
self.last_name = last_name
@property
def city(self):
return self.town
@city.setter
def city(self, town):
self.town = town
# methods
def full_name(self):
""" Returns the full name (first and last name) as a string """
return self.first_name + " " + self.last_name
def full_name_city(self):
""" Returns first, last and city as string """
return self.first_name + " " + self.last_name + self.city
def username(self):
""" returns the username as string """
return self.first_name[0] + self.last_name
# --------------- End Of Person ---------------
class Worker(Person):
""" represents a worker """
def __init__(self, first_name = "", last_name= "", town= "",
job_title= "", company_name= "", wages=0):
self.job_title = job_title
self.company_name = company_name
self.wages = wages
Person.__init__ (self, first_name, last_name, town)
# describes the class person
def __str__(self):
return self.first_name + ", " + self.last_name + ", " + self.town
+ " " + self.job_title + ", " + self.company_name +
", " +str(self.wages)
# falls back to this if there is no __str__ - used in debugging
def __repr__(self):
return self.first_name + ", " + self.last_name + ", " + self.town
+ " " + self.job_title + ", " + self.company_name +
", " +str(self.wages)
@property
def jobtitle(self):
return self.job_title
@jobtitle.setter
def jobtitle(self, title_value):
self.job_title = title_value
@property
def company(self):
return self.company_name
@company.setter
def company(self, company_value):
self.company_name = company_value
@property
def salary(self):
return self.wages
@salary.setter
def salary(self, wages_value):
self.wages = wages_value
# --------------- End Of Worker ---------------
class Voter(Person):
""" Represents a voter based on Person """
def __init__(self, first_name = "", last_name= "", town= "",
precient_number= 0, party_name= ""):
self.precient_number = precient_number
self.party_name = party_name
Person.__init__ (self, first_name, last_name, town)
def __str__(self):
return self.first_name + " " + self.last_name + " " + self.town
+ " " + str(self.precient_number) + " " + self.party_name
# falls back to this if there is no __str__ - used in debugging
def __repr__(self):
return self.first_name + ", " + self.last_name + ", " + self.town
+ ", " + str(self.precient_number) + ", " + self.party_name
@property
def precient(self):
"""represents the precient of the voter as a string """
return self.precient_number
@precient.setter
def precient(self, precient_value):
self.precient_number = precient_value
@property
def party(self):
"""represents the party of the voter as a string"""
return self.party_name
@party.setter
def party(self, party_value):
self.party_name = party_value
# --------------- End Of Voter ---------------
def main():
qty = 5
print("Create Person")
# p1 = Person("John", "Doe", "Anywhere")
p1 = Person("John","Doe","Kali")
p1.firstname = "Jimbo"
p1.lastname = "Smith"
p1.city = "Whitefish"
print(p1)
print(p1.full_name())
print(p1.first_name)
print(p1.lastname)
print(p1)
p2 = Person("Sally", "Smith", "Polson")
#change first and last name of p2
p2.first_name = "Bonnie"
p2.last_name = "Bond"
print(p2)
# create a list of people
people = []
for i in range(qty):
px = Person("John" + str(i),
"Doe" + str(i),
"Kali" + str(i))
people.append(px)
print(people[i].first_name + " "+ people[i].last_name)
print()
# create workers
w1 = Worker("Tom", "Tune", "New York", "Dancer", "Broadway", 100000)
print(w1)
w2 = Worker()
w2.firstname = "Ira"
w2.lastname = "Money"
w2.company = "IRS"
w2.jobtitle = "Auditor"
w2.salary = 90000
print(w2)
print()
# create a list of workers
workers = []
for i in range(qty):
wx = Worker("John" + str(i),
"Doe" + str(i),"",
"Programmer" + str(i))
workers.append(wx)
print(workers[i].first_name + " "+
workers[i].last_name + " " +
workers[i].jobtitle)
print()
# create voters
v1 = Voter("Abe", "Lincoln", "Springfield", 17, "Republican")
v2 = Voter()
v2.firstname = "Charles"
v2.lastname = "Daily"
v2.city = "Chicago"
v2.precient_number= 1
v2.party ="Democrat"
print(v1)
print(v2)
print()
# create a list of voters
voters = []
for i in range(qty):
vx = Voter("John" + str(i),
"Doe" + str(i),"","",
"Independent" + str(i))
voters.append(vx)
print(voters[i].firstname + " "+
voters[i].lastname + " " +
voters[i].party)
print("bye")
main()
Example 3 - getters and setters#
# -*- coding: utf-8 -*-
"""
@author: jgoudy
"""
class class1:
# The traditional "old" style of creating getters and setters
def __init__(self, number = 0):
self.number = number
# getter method
def get_Number(self):
return self.number
# setter method
def set_Number(self, value):
self.number = value
# ---------------- End of class 2 -----------------
class class2:
# using properties
# using a property allows the object code to be cleaner
# and users of the class will not have to make changes to their code
def __init__(self, anumber = 0):
self.anumber = anumber
# getter method
def get_Number(self):
return self.anumber
# setter method
def set_Number(self, value):
self.anumber = value
# function to delete the number attribute
def del_Number(self):
del self.anumber
# TURN SETTERS AND GETTERS INTO PROPERTIES
number = property(get_Number, set_Number, del_Number, "Stores a number")
# ---------------- End of class 2 -----------------
class class3:
# THE PYTHONIC WAY
# This is the preferred way of doing setters and getters.
# this is a getter method
def __init__(self, anumber = 0):
self.anumber = anumber
@property
def number(self):
return self.anumber
# this is the setter method
@number.setter
def number(self, value):
self.anumber = value
@number.deleter
def number(self):
del self.anumber
# ---------------- End of class 3 -----------------
def main():
#Old way
mc1 = class1()
mc1.set_Number(42)
print(mc1.get_Number())
print("\n----------\n")
mc2 = class2()
mc2.number = 52
print(mc2.number)
print("\n----------\n")
mc3 = class3()
mc3.number = 62
print(mc3.number)
main()
Example 4 - Trains#
# trains
"""
Train
id
engine
cabose
start (location)
destination (location)
traincars
"""
import random
class Train:
# constructor
def __init__(self, a_trainid, a_start="Whitefish",a_destination=""):
self.a_trainid = a_trainid
self.a_start = a_start
self.a_destination = a_destination
# create an empty list to hold train cars
self.traincars = []
# functions can be called within a constructor
# or any other function as well
self._addengine()
# properties
@property
def trainid(self):
return self.a_trainid
@trainid.setter
def trainid(self,value):
self.a_trainid = value
@property
def start(self):
return self.a_startstart
@start.setter
def start(self,value):
self.a_start = value
@property
def destination(self):
return self.a_destination
@destination.setter
def destination(self,value):
self.a_destination = value
# add our methods
def _addengine(self):
self.traincars.append("engine")
def addcar(self,value):
self.traincars.append(value)
def addcaboose(self):
self.traincars.append("caboose")
# print the train cars
def printtrain(self):
print("\n"+ self.a_trainid + "\t" + self.a_start + " to " + self.a_destination)
for i in range(len(self.traincars)):
print("\t" + self.traincars[i])
print()
# ---------------- End Of Class ----------------------------------
# *****************************************************************
# program starts here
# global variable to hold whole trains
mytrains = []
# create a function to create a train with random cars
def createtrain(maxNumTrains, maxNumCars):
# create a list car types
cartypes = ["flat","box","tanker","passenger","ore"]
# create a list of towns
towns = ["Denver", "Seattle","Missoula", "Kalispell",
"Whitefish", "Chicago", "New York", "Ringling","Clarskville"]
# randomly pick a number to determine the number of trains
rnd = random.randint(0,maxNumTrains)
# loop to create the number of complete trains
for i in range(rnd):
# variables to hold the start and end towns
startTown = ""
desTown = ""
# this while statement is used to ensure
# that there will always be two different towns
# if the startTown and desTown are equivalent,
# the while loop runs. Note that the
# startTown and desTown start equivalent
while(startTown == desTown):
# randomly going to pick a start town
rndtemp = random.randint(0,len(towns)-1)
startTown = towns[rndtemp]
# randomly going to pick a destination town
rndtemp = random.randint(0,len(towns)-1)
desTown = towns[rndtemp]
# call the class to create a train
tx = Train("T"+ str(i),startTown,desTown)
# randomly decide on how many train cars
rndtemp = random.randint(0,maxNumCars)
# randomly add cars to the train
for i in range(rndtemp):
rndcar= random.randint(0,len(cartypes)-1)
tx.addcar(cartypes[rndcar])
tx.addcaboose()
# add train to the global variable
mytrains.append(tx)
def printmytrains(alist):
# print the total number of trains
print(len(alist))
# iterate/loop the number of trains
for i in range(len(alist)):
alist[i].printtrain()
# this code will only show two trains at a time
# if the remainder == 0 show the input command
# example i = 4 | 4 / 2 = 0 with a remainder of 0
if((i % 2) == 0):
input("press any key to continue")
def main():
# create an individual train
train1 = Train("ML11","Helena","Missoula")
# add 10 box cars
for c in range(10):
train1.addcar("box")
train1.addcaboose()
# print the train we just created
train1.printtrain()
# create trains
# each time this runs the trains will change
createtrain(15,8)
printmytrains(mytrains)
main()