Why do I get an error after running my code to print and modify condition?

Question

Why do I get an error after running my code to print and modify condition?

Answer

The steps must be followed in exactly the order asked for in the instructions, otherwise you’ll get errors saying that you didn’t print or change something properly.
In this order, we should:

  1. print our car’s condition instance variable by accessing it using dot notation, like this: print my_car.condition
  2. Change the value stored in condition by using the method we just created. To use an object’s method, simply use dot notation, like this: my_car.method_name(). You don’t need to type anything else on the line other than that, since the method is just doing what it does (changing a value) and then moving on.
  3. print the car’s condition one last time to see the change it made!
4 Likes

For the code in Classes 8. ,

class Car(object):
  condition = "new"
  def __init__(self, model, color, mpg):
    self.model = model
    self.color = color
    self.mpg   = mpg
   
  def display_car(self):
    print "This is a %s %s with %s MPG." % (self.color, self.model, str(self.mpg))
  
  def drive_car(self):
    self.condition = "used"

my_car = Car("DeLorean", "silver", 88)

print my_car.condition
print my_car.drive_car()

Why does the last line of the above code print none? Is it because there wasn’t anything returned from the second line of code? As such, we have to change the member variable using my_car.drive_car() before we can print my_car.condition

1 Like

This method has no return so should not be printed.

print my_car.condition
my_car.drive_car()
print my_car.condition
4 Likes

This is my original code for the initial step of defining a method to change the value for ‘condition’

  def drive_car(self):
    self.condition = condition
    condition = "used"
    return condition

And below is the correct code:

def drive_car(self):
    self.condition = "used"

I figured this out, but I was just wondering what is wrong with my original code

1 Like

In your first version, in the statement, self.condition = condition
… the object on the right of the assignment, condition, is nowhere defined (or, rather, is defined in the next line, which the interpreter does not know is coming.)

1 Like

Add to that, when we set the value of an attribute, the work is done and there is no need for a return.

1 Like

Is that exclusively the case for classes? as I know that we ‘return’ when learning about functions

Ah okay, so swapping that round would produce the right result?

swapping that round would produce the right result?

Well, condition just becomes an unnecessary intermediate variable then:

 def drive_car(self):
    condition = "used"
    self.condition = condition        

It’s not needed at all, as you found with your second version.

I’m not 100% sure what you’re trying to do, but perhaps condition should be passed to the method when it is declared:

def drive_car(self, condition):
    self.condition = condition      

# Then, from inside the class:
self.drive_car("used")
 # ... or,  from outside the class:
my_car_instance.drive_car("used")

As for the return statement, it’s a bit like modifying a list by means of a function. The list is just modified; you don’t return it. Here, once you set condition, condition remains an attribute of that instance of your class (Car, or whatever), and you can just call it:

c = my_car_instance.condition
# do something with c

1 Like

For completeness’ sake, I should mention that OOP purists don’t like the idea of being able to directly access an instance attribute from outside of the class, as I did above.

They would want you to have a special method, called a “getter”, for that purpose, which would use return.

def get_condition(self):
    return self.condition

Its a big deal in Java, not so much in Python. Google “getters and setters in Python” for some controversy!

2 Likes

As such, yes. The method is a type of setter and accesses the properties in current scope (the instance context). It is not a function that needs to return anything, just set the attribute and be done.

The purpose of the method is simple, set the condition attribute to ‘used’ once the car has been driven. How do we know the car has been driven? Well, we called the drive_car method, didn’t we?

3 Likes

Yes, probably need self.value = self.price/2 also!

2 Likes

Here’s my code:

class Car(object):
  condition = "new"
  def __init__(self, model, color, mpg):
    self.model = model
    self.color = color
    self.mpg   = mpg
   
  def display_car(self):
    print "This is a %s %s with %s MPG." % (self.color, self.model, str(self.mpg))
  
  def drive_car(self):
    self.condition = "used"

my_car = Car("DeLorean", "silver", 88)

print my_car.condition()
my_car.drive_car(self)

print my_car.condition()

It is exactly like what everyone talks about here, yet I got the error:

Output:
Traceback (most recent call last):
File “python”, line 16, in
TypeError: ‘str’ object is not callable

I’m not sure what the problem is

We make all kinds of mistakes, all the time. Something to get used to. To err is human. To yearn it is divine.

Error messages and tracebacks are the only apparatus available to the language with which to inform us. Fortunately we will see so many of these messages we will learn the language, if by sedimentation.