Is it possible to reference an old value of an instance variable together with the updated value?

Hello,

I’m working on the extensions task for the Python Classes: Medical Insurance Project. Forgive me if I’m not using the correct terminology but I was wondering… If I want to create a method that updates a patient’s name and print a statement that utilises both the original name as well as the new updated name, i.e.: the original instance value as well as the new instance value - is that possible using the level of coding that has been taught up until now? I’ve tried various ways of trying to assign values to the attributes/instances, adding an additional parameter into the update name method and trying to reference the object (patient1) but it keeps throwing errors.

I’ve included part of the code below and written ‘xxx’ for where I was hoping to reference the original name.

Thank you in advance.

class Patient:
  def __init__(self, name, age, sex, bmi, children, smoker):
    self.name = name
    self.age = age
    self.sex = sex
    self.bmi = bmi
    self.children = children
    self.smoker = smoker
  
  def estimated_insurance_cost(self):
    try:
      estimated_cost = 250*self.age - 128*self.sex + 370*self.bmi + 425*self.children + 24000*self.smoker - 12500
      print("{}'s estimated insurance costs is {} dollars.".format(self.name, estimated_cost))
    except TypeError:
      print("Only input numerical values for all data except Name.")

  def update_name(self, new_name):
    self.name = new_name
    print("{} changed their name to {}".format( xxx , self.name))

patient1 = Patient("John Doe", 25, 1, 22.2, 0, 0)
patient1.estimated_insurance_cost()
patient1.update_name("Josephine Doe")

1 Like

You can put the print statement before the self.name, before the assignment operation.

print("{} changed their name to {}".format(self.name, new_name))
self.name = new_name
3 Likes

*I’ll add this is sometimes a dicey practice. You want to make sure that your operations successfully run. If this were a bit more complex, the operation may fail mid-function… and then the message would deceive and make it harder to debug. You could have two print statements, one before one after, to be super safe (but not necessary in this instance).

1 Like

Thank you so much for your input on this. How come this order change makes all the difference? Is there a term for this, something that I can Google to read more about?

And would you mind to expand more on your suggestion of possibly using two print statements - how would they differ from each other?

1 Like

Hi,
I’m not sure there’s a name for it. What’s happening is self.name is being given the new value of new_name. When that happens it’s old value doesn’t exist anymore, and it has no way of knowing what it was.
What @toastedpitabread may have meant by two print statements could be say have the first one similar to what you’ve put. e.g “self.name is changing their name to new_name”
and then once it’s done having a second message saying “completed!”

Alternatively, you could assign self.name to a new variable.
i.e. have something like;
temp = self.name
before you reassign self.name and then use that (temp) in place of xxx in your print statement.

3 Likes

The order change matters because the value of self.name changes during assignment (that’s when the assignment = operator is used). So whatever previous data it had is overwritten.

To be specific, a place where you would not want to change the order is in an operation that changes a file.

Here’s a scenario:

some_change_to_file(my_file)
print("success")

In some cases, the operation may fail, so success will not and should not print.

If we change the order and the operation fails…

print("success")
some_change_to_file(my_file)

well, now we have success printed, but the operation still failed. In which case we have no explicit way of tracking the source of the problem.

This is a bit simplified (printing “success” is not really the way to go either), but it’s more or less the direction I was going for.

2 Likes

Ah… ok, I had initially tried assigning self.name to two different variables:
self.name = old_name
self.name = new_name
but that hadn’t worked. Looking at how you advised, I just tried it again but swapped the positioning around the equals sign and it worked:
old_name = self.name
self.name = new_name

Interesting, thank you so much!! :pray:

This is great, thank you for the explanation. I see what you mean, in my exercise it is clear whether or not the code is working but in your example the print statement is not intrinsically linked to the action :bulb: