6.1. Object-Oriented Python (215m) Flashcards

1
Q

What Are Objects And Classes?

A

Sure! In programming, think of a “class” as a blueprint for making something. It’s like the concept of a “car” in general; you know a car has wheels, seats, and an engine, but this general idea doesn’t tell you anything about a specific car, like its color or make.

Objects are like individual instances or examples of that blueprint. If a “class” is the general concept of a “car,” then an “object” would be a specific car, like a red Toyota Corolla with a sunroof.

Classes and Objects in terms of Grammar:

  1. Class = Noun: A class is like a “noun,” a general concept that describes things. For example, “Dog” is a noun that represents a general concept of a four-legged animal that barks.
  2. Object = Proper Noun: An object is like a “proper noun,” a specific instance of that general concept. For example, “Fido” would be a specific dog with its own unique traits and behaviors.
  3. Attributes = Adjectives: Attributes are qualities or characteristics of the object. Just like adjectives describe nouns, attributes describe or provide more details about objects. For example, the color of the car, or the breed of the dog.
  4. Methods = Verbs: Methods are actions that the object can perform. Like how verbs show what a noun can do, methods define what an object can do. For example, a dog can “bark,” or a car can “accelerate.”

Example:

Let’s take a class called “Dog.”

  • Class (Noun): Dog
  • Attributes (Adjectives): Breed, Color, Age
  • Methods (Verbs): Bark, Fetch

Now, let’s create an object from this class.

  • Object (Proper Noun): Fido
    • Attributes (Adjectives): Golden Retriever, Yellow, 3 years
    • Methods (Verbs): Fido can Bark, Fido can Fetch

So, a class is like the blueprint that tells us what a ‘Dog’ should have and be able to do, while an object is a specific ‘Dog’ with its own attributes and behaviors.

Treehouse Notes:
The class keyword lets us define a class. We use it just like we do the def keyword for making functions. Class definitions are blocks like function definitions.

class NewClass:

Inside of the class, variables are called attributes.

class NewClass:
    name_attribute = "Kenneth"

And functions that are defined inside of a class are called methods.
~~~
class NewClass:
name_attribute = “Kenneth”

def name_method(self):
    return self.name_attribute ~~~ Whenever we call a class, it creates an instance. Each instance has full access to the all of the attributes and methods of the class. ~~~ new_instance = NewClass() new_instance.name_method() ~~~
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

A method is a function defined inside of what?

A

A method is a function that is defined inside of a class. Unlike standalone functions, methods are designed to operate on instances of the class, often modifying the state or attributes of those instances.

In the context of our previous example with dogs, the methods like “Bark” and “Fetch” would be functions defined inside the “Dog” class. These methods would typically operate on specific instances (objects) of that class, like “Fido” or “Spot.”

Here’s a simplified Python example to illustrate:

```python
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed

# Method (Verb)
def bark(self):
    print(f"{self.name} says Woof!")

Create an Object (Proper Noun)
fido = Dog(name=”Fido”, breed=”Golden Retriever”)

Call a Method (Verb) on the Object
fido.bark() # Output: “Fido says Woof!”
~~~

In this example, bark is a method defined inside the Dog class. The fido object is an instance of the Dog class, and we can call the bark method on this object.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

In Python, only dictionaries, lists, tuples, and sets are objects. Is this true?

A

No, that statement is not true. In Python, nearly everything is an object. This includes not just dictionaries, lists, tuples, and sets, but also numbers, strings, functions, and even modules and classes themselves. Python is an object-oriented language, which means that it uses objects as a fundamental building block for constructing programs.

Examples:

  1. Numbers are objects: You can find out the type of an object using the type() function.
    python
     x = 42
     print(type(x))  # Output: <class 'int'>
  2. Strings are objects: They have methods like upper(), lower(), etc.
    python
     s = "hello"
     print(s.upper())  # Output: "HELLO"
  3. Functions are objects: You can assign them to variables, pass them as arguments, etc.
    ```python
    def my_function():
    print(“Hello from my_function”)func_var = my_function
    func_var() # Output: “Hello from my_function”
    ```
  4. Modules are objects: You can assign them to variables and manage them just like any other object.
    python
     import math
     print(type(math))  # Output: <class 'module'>
  5. Even Classes are objects: They are instances of a meta-class.
    ```python
    class MyClass:
    passprint(type(MyClass)) # Output: <class ‘type’>
    ```

So, in Python, the concept of an “object” is very broad and not limited to just a few data types.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Sequence 1: The file characters.py contains:
~~~
class Thief:
pass
~~~
The following is run within terminal/console:
~~~
python
from characters import Thief
kenneth = Thief()
kenneth
~~~

Sequence 2:
The file characters.py contains:
~~~
class Thief:
sneaky = True #attribute
~~~
The following is run within terminal/console:
~~~
python
from characters import Thief
kenneth = Thief()
kenneth.sneaky
~~~

Explain the sequence 1 and 2, what’s happening in it?

A

Certainly! Let’s go through both sequences step-by-step.

Sequence 1:

  1. File Creation: The file characters.py contains a class definition for Thief. The pass statement is a placeholder indicating that the class is currently empty; it doesn’t have any attributes or methods yet.
    python
     class Thief:
       pass
  2. Console/Terminal Steps:
    • python: This command starts the Python interpreter.
    • from characters import Thief: This imports the Thief class from the characters.py file. Now you can create instances (objects) of this class.
    • kenneth = Thief(): This creates a new object of the Thief class and assigns it to the variable kenneth.
    • kenneth: This would display a representation of the kenneth object, something like <\_\_main\_\_.Thief object at 0x7f8f9c0>.

Sequence 2:

  1. File Creation: The file characters.py has been updated to include an attribute sneaky in the Thief class, set to True.
    python
     class Thief:
       sneaky = True  # attribute
  2. Console/Terminal Steps:
    • python: Starts the Python interpreter.
    • from characters import Thief: Imports the updated Thief class from the characters.py file.
    • kenneth = Thief(): Creates a new object of the Thief class and assigns it to the variable kenneth.
    • kenneth.sneaky: Accesses the sneaky attribute of the kenneth object. Since sneaky is set to True in the class definition, this would return True.

Summary:

  • In Sequence 1, you created an empty Thief class and made an instance of it. The instance didn’t have any special attributes or methods because the class was empty.
  • In Sequence 2, you added a sneaky attribute to the Thief class and set it to True. When you made an instance of this updated class, you could access this attribute, which returned True.

In both sequences, the steps in the terminal are to import the class and create an instance (object) of that class. The key difference is in the attributes that the class and its instances have.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Challenge Task 1 of 2
Alright, it’s time create your first class all on your own! Make a new class named Student. Give it an attribute name and put your own name, as a string, into the attribute.

Challenge Task 2 of 2
Now, create a variable named me and assign it an instance of Student(). Then print() out the name attribute of your instance.

A

Task 1:
~~~
class Student:
name = “Sethu”
~~~

Task 2:
~~~
class Student:
name = “Sethu”

me = Student()
print(me.name)
~~~

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Sequence 1:
The file characters.py contains the following code:
~~~
import random

class Thief:
sneaky = True #attribute
def pickpocket(self): #methods
return bool(random.randint(0, 1))
~~~
The following code is run in console/terminal:
~~~
python
from characters import Thief
kenneth = Thief()
kenneth.pickpocket() #returns false
Thief.pickpocket() #returns error as has no self
Thief.pickpocket(kenneth) #kenneth is self, returns false
~~~

Sequence 2:
The file characters.py contains the following code:
~~~
import random

class Thief:
sneaky = True #attribute
def pickpocket(self): #methods
print(“Called by {}”.format(self))
return bool(random.randint(0, 1))
~~~
The following code is run in console/terminal:
~~~
python
from characters import Thief
kenneth = Thief()
kenneth.pickpocket()
Thief.pickpocket(kenneth)
~~~

Sequence 3:
The file characters.py contains the following code:
~~~
import random

class Thief:
sneaky = True #attribute
def pickpocket(self): #methods
if self.sneaky:
return bool(random.randint(0, 1))
return False
~~~
The following code is run in console/terminal:
~~~
python
from characters import Thief
kenneth = Thief()
kenneth.pickpocket() #returns True
kenneth.pickpocket() #returns Talse
kenneth.pickpocket() #returns True
kenneth.sneaky = False
kenneth.pickpocket() #returns False
kenneth.pickpocket() #returns False
kenneth.pickpocket() #returns False
~~~

Explain the sequence 1,2,3 and what’s happening in it?

A

Absolutely! Let’s break down what’s happening in each of the sequences.

Sequence 1:

  1. File Code: In characters.py, a Thief class is defined with an attribute sneaky set to True and a method pickpocket that returns a random boolean value (True or False).```python
    import randomclass Thief:
    sneaky = True
    def pickpocket(self):
    return bool(random.randint(0, 1))
    ```
  2. Console Steps:
    • kenneth = Thief(): Creates an object kenneth of class Thief.
    • kenneth.pickpocket(): Calls the pickpocket method on the kenneth object. This returns False due to the random number generated.
    • Thief.pickpocket(): Tries to call pickpocket directly on the class, which results in an error because no self argument is provided.
    • Thief.pickpocket(kenneth): Calls pickpocket on the class, passing kenneth as the self argument. This works and returns False (due to random generation).

Sequence 2:

  1. File Code: Similar to Sequence 1, but the pickpocket method now includes a print statement to show which object called it.
    python
     def pickpocket(self):
       print("Called by {}".format(self))
       return bool(random.randint(0, 1))
  2. Console Steps:
    • kenneth.pickpocket(): Calls the method and prints “Called by <Thief>".</Thief>
    • Thief.pickpocket(kenneth): Similar to the above but called directly on the class. It also prints the same message.

Sequence 3:

  1. File Code: The pickpocket method now includes an if condition that checks the sneaky attribute before returning a random boolean.
    python
     def pickpocket(self):
       if self.sneaky:
         return bool(random.randint(0, 1))
       return False
  2. Console Steps:
    • kenneth.pickpocket(): Called multiple times and returns either True or False based on random generation, because sneaky is True.
    • kenneth.sneaky = False: Sets sneaky to False.
    • kenneth.pickpocket(): Now always returns False as sneaky is set to False.

Summary:

  • Sequence 1: Demonstrates basic class and method usage, including how to call methods both on an instance and directly on the class.
  • Sequence 2: Adds a print statement to show which instance is calling the method.
  • Sequence 3: Adds conditional logic to the method based on an attribute, demonstrating how methods can access and use the attributes of the instance on which they are called. It also shows how changing an attribute affects the behavior of methods.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Challenge Task 1 of 1
This class should look familiar! First, I need you to add a method named praise to the Student class. It should take the self argument. Then, inside the praise method, return a positive message about the student using the name attribute. As an example, it could say “You’re doing a great job, Jacinta!” or “I really like your hair today, Michael!”. Feel free to change the name attribute to your own name, too!

File: first_class.py:
~~~
class Student:
name = “Your Name”
~~~

A

Task 1:
Variant 1:
~~~
class Student:
name = “Sethu”

def praise(self):
    return "You're doing a great job {}".format(self.name) ~~~

Variant 2:
~~~
class Student:
name = “Sethu”

def praise(self):
    return f"You're doing a great job, {self.name}!" ~~~

Run:
~~~
# Adding a method named ‘praise’ to the Student class
class Student:
name = “Your Name”

def praise(self):
    return f"You're doing a great job, {self.name}!"

Create an instance of the Student class to test the praise method
student_instance = Student()
praise_message = student_instance.praise()
praise_message
~~~

Result:
~~~
“You’re doing a great job, Your Name!”
~~~

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Sequence 1:
The file characters.py contains the following:
~~~
import random

class Thief:
sneaky = True #attribute

def pickpocket(self): #methods
if self.sneaky:
return bool(random.randint(0, 1))
return False

def hide(self, light_level):
return self.sneaky and light_level <10
~~~

The following code is run in Terminal/Console:
~~~
python
from characters import Thief
kenneth = Thief()
kenneth.hide(4)
kenneth.hide(14)
kenneth.sneaky = False
kenneth.hide(0)
~~~

Sequence 2:
The file characters.py contains the following:
~~~
import random

class Thief:
sneaky = True # attribute

def __init__(self, name, sneaky=True, **kwargs):
self.name = name
self.sneaky = sneaky

def pickpocket(self): # methods
return self.sneaky and bool(random.randint(0, 1))

def hide(self, light_level):
return self.sneaky and light_level < 10
~~~

The following code is run in Terminal/Console:
~~~
from characters import Thief
kenneth = Thief(“Kenneth”, False)
kenneth.name
kenneth.sneaky
~~~

Sequence 3:
The file characters.py contains the following:
~~~
import random

class Thief:
sneaky = True # attribute

def __init__(self, name, sneaky=True, **kwargs):
self.name = name
self.sneaky = sneaky

for key, value in kwargs.items():
  setattr(self, key, value)

def pickpocket(self): # methods
return self.sneaky and bool(random.randint(0, 1))

def hide(self, light_level):
return self.sneaky and light_level < 10
~~~

The following code is run in Terminal/Console:
~~~
from characters import Thief
kenneth = Thief(“Kenneth”, scars=None, favorite_weapon=”Wit”)
kenneth.name
kenneth.sneaky
kenneth.favorite weapon
~~~

Explain the sequence 1,2,3 and what’s happening in it?

A

Certainly, let’s explore each sequence in more detail, taking into account both the code within characters.py and the code run in the terminal.

Sequence 1

characters.py
- Thief class is defined with a class attribute sneaky set to True.
- Two methods, pickpocket() and hide(light_level), are also defined. pickpocket() returns a random boolean if sneaky is True, and hide() returns True if sneaky is True and light_level is less than 10.

Terminal/Console
- An object named kenneth is created from the Thief class.
- kenneth.hide(4) is called and would return True because light_level (4) is less than 10 and sneaky is True.
- kenneth.hide(14) would return False because light_level (14) is not less than 10.
- kenneth.sneaky is set to False.
- kenneth.hide(0) is called and would now return False because sneaky is False, irrespective of light_level.

Sequence 2

characters.py
- Thief class now includes an \_\_init\_\_ method to initialize name and sneaky attributes when a new object is created.
- pickpocket() is modified to return a boolean based on both sneaky and a random value between 0 and 1.

Terminal/Console
- A new object named kenneth is created with sneaky set to False and name set to “Kenneth”.
- Accessing kenneth.name would return “Kenneth”.
- Accessing kenneth.sneaky would return False.

Sequence 3

characters.py
- Thief class is further modified to accept arbitrary keyword arguments (**kwargs) in the \_\_init\_\_ method.
- These keyword arguments are set as attributes on the object using the setattr function.

Terminal/Console
- A new object named kenneth is created with additional attributes: scars is set to None, and favorite_weapon is set to “Wit”.
- Accessing kenneth.name would return “Kenneth”.
- Accessing kenneth.sneaky would return True (default value as no value for sneaky was provided during object creation).
- Accessing kenneth.favorite_weapon would return “Wit”. Note: The code has a typo and uses kenneth.favorite weapon which would actually result in a syntax error. It should be kenneth.favorite_weapon.

In summary, these sequences display the evolution of the Thief class, starting from a simple version to a more complex one that allows for custom attributes and initialization. The terminal/console interactions help to show how these class features can be accessed and modified for individual objects.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Challenge Task 1 of 1
Alright, I need you to make a new method named feedback. It should take self and an argument named grade. Methods take arguments just like functions do.

Inside the feedback method, if grade is above 50, return the result of the praise method. If it’s 50 or below, return the reassurance method’s result.

first_class.py:
~~~
class Student:
name = “Your Name”

def praise(self):
    return "You inspire me, {}".format(self.name)

def reassurance(self):
    return "Chin up, {}. You'll get it next time!".format(self.name) ~~~
A

Task 1:
Certainly! To implement the feedback method, you can check the value of the grade argument and return the result of either the praise or reassurance method accordingly. Here’s how you can update the Student class in first_class.py:

```python
class Student:
name = “Your Name”

def praise(self):
    return "You inspire me, {}".format(self.name)

def reassurance(self):
    return "Chin up, {}. You'll get it next time!".format(self.name)

def feedback(self, grade):
    if grade > 50:
        return self.praise()
    else:
        return self.reassurance() ~~~

Now, the Student class has a feedback method that takes a grade argument. If grade is greater than 50, the method returns the result of praise(). Otherwise, it returns the result of reassurance().

You can test the feedback method by creating an instance of the Student class and calling it:

```python
student1 = Student()
student1.name = “Alice”

print(student1.feedback(60)) # Output: “You inspire me, Alice”
print(student1.feedback(40)) # Output: “Chin up, Alice. You’ll get it next time!”
~~~

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Challenge Task 1 of 2:
Our Student class is coming along nicely!
I’d like to be able to set the name attribute at the same time that I create an instance. Can you add the code for doing that?

Override the \_\_init\_\_ method by adding your own \_\_init\_\_ method to the Student class. Add self and name as arguments to the \_\_init\_\_ method. Inside of \_\_init\_\_, set self.name to the argument name.

first_class.py:
~~~
class Student:
name = “Your Name”

def praise(self):
    return "You inspire me, {}".format(self.name)

def reassurance(self):
    return "Chin up, {}. You'll get it next time!".format(self.name)

def feedback(self, grade):
    if grade > 50:
        return self.praise()
    return self.reassurance() ~~~

Challenge Task 2 of 2:
Sometimes I have other attributes I need to store on a Student instance. Add **kwargs as an argument to the \_\_init\_\_ method. Then use setattr inside the \_\_init\_\_ method to add attributes for any other key/value pairs I want to send to the instance when I create it.

first_class.py:
~~~
class Student:
name = “Your Name”

def \_\_init\_\_(self, name):
    self.name = name

def praise(self):
    return "You inspire me, {}".format(self.name)

def reassurance(self):
    return "Chin up, {}. You'll get it next time!".format(self.name)

def feedback(self, grade):
    if grade > 50:
        return self.praise()
    return self.reassurance() ~~~
A

Task 1:
~~~
class Student:
name = “Your Name”

def \_\_init\_\_(self, name):
    self.name = name

def praise(self):
    return "You inspire me, {}".format(self.name)

def reassurance(self):
    return "Chin up, {}. You'll get it next time!".format(self.name)

def feedback(self, grade):
    if grade > 50:
        return self.praise()
    return self.reassurance() ~~~

Task 2:
~~~
class Student:
name = “Your Name”

def \_\_init\_\_(self, name, **kwargs):
    self.name = name
    for key, value in kwargs.items():
        setattr(self, key, value)

def praise(self):
    return "You inspire me, {}".format(self.name)

def reassurance(self):
    return "Chin up, {}. You'll get it next time!".format(self.name)

def feedback(self, grade):
    if grade > 50:
        return self.praise()
    return self.reassurance() ~~~
How well did you know this?
1
Not at all
2
3
4
5
Perfectly