Chapter 6 : classes Flashcards
What is a class?
Structure that contains data (variables) and logic (functions) in a reusable container
Sort of like a cookie cutter
What is an object?
The are created from classes so you can use those classes (data and logic)
What is a method?
When a function (logic) is added to a class
Create a class, object and method and define them
class world:
greeting = “Hello, World!”
def \_\_init\_\_(self): print(self.greeting) w = World()
1) Class is from the term class down to the print indent
2) The function is known as a method since it’s in a class
3) w = World is our object, since it allows us to use the class. Remember that the naming convention should normally be a capitalized word.
4) __init__ is a special method ( the initializer ) that is automatically called when an object is create from the method.
5) self is an argument used to reference the object created by the class. This just means that the variable it’s trying to access isn’t in the method but the class, so it needs to refernce itself to find its variable
Create a bug class and object, the object will be Andy.
The method will store all his bug attributes like the type of bug he is, color, size, and aggression. After you have that information, show just his size.
Andy should also be able to do some stuff that bugs do, like walk or run, give him these attributes and print him doing them!
class Bug:
def __init__(self, type, color, size, agression):
self.type = type
self.color = color
self.size = size
self.agression = agression
def walk(self): print("walking...") def run(self): print("running...") Andy = Bug("beetle", "black", "big", "agressive") print(Andy.size) Andy.walk()
https://www.youtube.com/watch?v=rJzjDszODTI
What’s a good way of thinking of objects/classes
Your class is what your thing is made up of, it’s good to think of it like a person, so a person is going to be made up of different things, like height, weight, and skin color.
The Object itself is going to refer to a specific person who has the foundation found in the class, but his attributes are what makes him who he is.
What’s a good way to read self as?
“This instance of the class
sort a list from least to greatest
list = [
“laugh”,
“cry”,
“fart”
]
list.sort()
Show the biggest number in a list
then show the smallest
then show the amount of elements in the list
max(list)
min(list)
len(list)
What are instance variables?
Variables used in an instance of a class
class man:
def __init__(self, name, age)
name and age are our instance variables
customer(“Nathan”, “23”)
Those are also instance variables
Class variables
Variable that are actually stored in the class
greeting = “Hello”
You can call these like this
object.greeting
If calling from inside the class you use
self.greeting
Use enter and exit, try to explain what they do
class customer:
def \_\_init\_\_(self, name, city): self.name = name self.city = city def \_\_enter\_\_(self): print("entering scope") return self def \_\_exit\_\_(self, exc_type, exc_value, traceback): print("Leaving scop") def greet(self): print("Hello, " + self.name + "!")
with customer(“Robert”, “Florence”) as robert:
robert.greet()
Basically what happens here is we create a temporary object “robert”
The with statement lets python know we’ll use the Enter and Exit methods
First __init__ runs and creates the instance variables
Next __enter__ runs whatever it needs to and then uses “return self” to denote that it’s finished.
Next, rober.greet() can run and do what it needs to
Finally the exit sequence gets a go and it runs some exception stuff to basically say “if something goes wrong, lets close this up so we don’t run the computers resources wild”, this is important if the program is doing something with a computer resource, like a file, if it malfunctioned without those excepts it would just leave it open and the world would end
Other Explanation
You use “with” to tell it to open and use the class, enter will start, then your code will be implemented in the scope of the class, finally when you’re finished your exit code and close out of whatever you got into.
For instance, maybe your enter opens a SQL database, then your code runs something in it, lastly the exit will close it up and make sure it doesn’t continue to run.
Delete your object and explain why using delete isn’t always ideal
class ferret:
def __init__(self):
print(“This is it”)
def __del__(self):
print(“Deleted”)
user = ferret()
del(user)
Sometimes this won’t even delete what you’ve asked it to
if the code is large and error prone it can affect python’s garbage collection which cleans up uneeded object so they don’t take so many resources.
Also, this could cause memory leaks which garbage cleanup tries to prevent
“__del__” Tells your program to delete the object when there are no more references to it, whereas del(object) just deletes it.
Say that you have created the code below, but in at some point you have to change the object’s first name (maybe the person had a name change) for the rest of your program. Your code is huge so you don’t want to retype every instance of referencing a method in the code, what would you do:
class Person:
def __init__(self, name, age, city):
self.name = name self.age = age self.city = city self.introduction = f"Hello, my name is {self.name}, and I'm {self.age}"
class Person:
def \_\_init\_\_(self, name, age, city): self.name = name self.age = age self.city = city @property def introduction(self): return f"Hello, my name is {self.name}, and I'm {self.age}"
me = Person(“Nathan”, 33, “Clarksville”)
me.name = “Bill”
print(me.introduction)
remember, this works because when you’re getting introduction, you do it like you did when it was just a variable before me.introduction
if it were a method it would look like this:
me.introduction()
Describe private variables, then show a coding example of them
Private variables are variables that we want to remain in a class and not accessed outside of it.
Private variables begin with and underscore like the below example. If it wasn’t private, and didn’t have the underscore, we would access it like this
class Demons:
def __init__(self, color):
self._color = color
@property
def color(self):
return self._color
If it wasn’t private, and didn’t have the underscore, we would access it like this:
me = Demons()
me.color
But, since it’s private we have to respect that, but here’s the work around…
Properties can be summoned just like variables, so if instead we use the property above, name the function color, then return self._color, we’re technically not returning the private variable, it’s just the property color, done the same way
me = Demons()
me.color
What does refactor mean?
Update the code to make it work better
Use setters and getters and explain how they work
class Distance:
def __init__(self, km):
self._km = km
@property def km(self): return self._km @km.setter def km(self, value): self_km = value @property def miles(self): return self._km / 1.609 @miles.setter def miles(self, value): self._km = value * 1.609
d = Distance(3)
d.miles = 4
print(d.km)
when you change a variable/attribute here, the setter is called, and then it does a little calculation after, if you just call on the property itself it will spit out whatever it normally would from the getter
Explanation on what is happening with setters and getters
why this works is because we initially set the inch value with our object me
# everything that sets self._inches after just updates it for good.
# that’s why when you set the method with a 3 at the bottom (it’s that way because it’s a property now) that inches updates to the equation needed.
class Distance:
def __init__(self, inches):
self._inches = inches
@property def inches(self): return self._inches @inches.setter def inches(self, value): self._inches = value @property def cent(self): return self._inches * 2.54 @cent.setter def cent(self, value): self._inches = value / 2.54
me = Distance(2)
me.cent = 3
print(float(me.inches))
sort list
#find min/max number
#show length
#replace number
#add number to beginning
#add number to end
#add number to middle?
list = [
183,
23,
204,
10,
44,
2
]
sort list
#find min/max number
#show length
#replace number
#add number to beginning
#add number to end
#add number to middle?
list = [
183,
23,
204,
10,
44,
2
]
print(list)
list.sort()
print(list)
print(len(list))
list[2] = 14
print(list)
list.append(98)
list.insert(0, 38)
list.insert(1, 18)
print(list)
print(min(list))
print(max(list))
Create a PARENT furniture class the default arguments:
width = 0
height = 0
material = wood
Now create a CHILD chair class that inherits Furniture’s methods(functions) and attributes(variables)
The chair class should have two of it’s own attributes:
arms = True
back = True
class Furniture:
def __init__(self, width = 0, height = 0, material = “wood”):
self.width = width
self.height = height
self.material = material
class Chair(Furniture):
def __init__(self, width = 0, height = 0, material = “wood”, arms = True, back = True):
self.arms = arms
self.back = back
super().__init__(width, height, material)
print(Chair(Furniture).material)
We user super.() because we want to use Furniture’s init, normally we couldn’t since Chair’s init would override it.
Expand your chair class to have a folded and unfolded method where you set the folded attribute to True and False depending on its state
class Furniture:
def __init__(self, width = 0, height = 0, material = “wood”):
self.width = width
self.height = height
self.material = material
class Chair(Furniture):
def __init__(self, width = 0, height = 0, material = “wood”, arms = True, back = True):
self.arms = arms
self.back = back
super().__init__(width, height, material)
def folded(self): self.folded = True print("Chair is folded and ready for transport") def unfolded(self): self.folded = False print("Chair is now unfolded and ready for use")
Add the class Bench that has multilevel inheritance to Furniture and Chair
Show what instance variables it has to make sure it inherited from Furniture
class Furniture:
def __init__(self, width = 0, height = 0, material = “wood”):
self.width = width
self.height = height
self.material = material
class Chair(Furniture):
def __init__(self, width = 0, height = 0, material = “wood”, arms = True, back = True):
self.arms = arms
self.back = back
super().__init__(width, height, material)
class Bench(Chair):
pass
sofa = Bench(“Metal”)
print(vars(sofa)
THIS SHOWS ALL MUTABLE ATTRIBUTES AND THEIR VALUES
Create 3 classes
Furniture:
width, height, material
Surface:
flat
Table:
self.legs = 4
Give Table MULTIPLE INHERITANCE to Surface and Furniture
Create an object for table and check what instance variables it has inherited
This time only give default arguments to table since it’s the only one that will need to use them
class Furniture:
def __init__(self, width, height, material):
self.width = width
self.height = height
self.material = material
class Surface:
def __init__(self, flat):
self.flat = flat
class Table(Furniture, Surface):
def __init__(self, width = 0, height = 0, material = “wood”, flat = True):
Furniture.__init__(self, width, height, material)
Surface.__init__(self, flat)
self.legs = 4
s = Table()
print(vars(s))
Multilevel vs Multiple Inheritance
Multilevel - Grandparent to parent, parent to child
Multiple - Child has two parents
Create the chair class, give a number argument to the init method
open a “bar” list
put 8 chairs in the bar
Print one of them out
Explain why you can’t put out the whole list
class Chair:
def __init__(self, number):
self.number = number
bar = []
for i in range(10):
bar.append(Chair(i))
print(bar[2].number)
This list will only print positions in memory since it needs specifics on each object. You can still technically do it, but I’m not about all that nonsense today.
Create a stool class, it can just have pass written in it.
Open a dictionary called “bar”
create two objects off of the stool class named Carl and Alex
Add them to dictionary keys with their respective names
class Chair:
def __init__(self, number):
self.number = number
bar ={}
Carl = Chair(1)
Alex = Chair(2)
bar[“carl”] = Carl
bar[“Alex”] = Alex
print(bar[“carl”].number)