1

I had a class challenge this week and although I returned the correct age I did not return the class instance as per instructions. I've read this post but the python 2.7 syntax seems completely different.

Instructor's notes.

The class is implemented correctly, and you create its instances correctly. But when you try to find the oldest dog, you return only its age, not the actual instance (as per instructions). The instance holds the information not only on the age, but also on the name. A minor comment: you call the function "oldest_dog" from inside the formatted string - this is unconventional, you'd better execute the function on the line before that and include only the calculated variable inside the formatted string.

class Dog:

    # constructor method
    def __init__(self, name, age):
        self.name = name
        self.age = age

# three class instance declarations
maxx = Dog("Maxx", 2)
rex = Dog("Rex", 10)
tito = Dog("Tito", 5)

# return max age instance
def oldest_dog(dog_list):
    return max(dog_list)

# input
dog_ages = {maxx.age, rex.age, tito.age}

# I changed this as per instructor's notes.
age = oldest_dog(dog_ages)
print(f"The oldest dog is {age} years old.")
Snostorp
  • 544
  • 1
  • 8
  • 14
TokyoToo
  • 926
  • 2
  • 10
  • 21
  • 4
    Well, as your instructor said, you are creating a new set which includes only the ages. But he expects you to return the `Dog` **object**, which **has the max age**. A hint: [`max`](https://docs.python.org/3/library/functions.html#max) takes another argument - `key` - which is the function to compare the items according to – Tomerikoo May 25 '20 at 12:18
  • Duplicate: https://stackoverflow.com/questions/38840580/how-to-return-a-class-instance-in-member-function-of-a-class?noredirect=1&lq=1 – Snostorp May 25 '20 at 12:20
  • 1
    @Snostorp this is not related. It is not about returning a new class instance from a method. Simply returning the max between a few instances – Tomerikoo May 25 '20 at 12:22
  • Thanks @Tomerikoo. That's what codepope answered with below. Is this the only way when we use max? I feel like the use of the lambda and key is beyond our class. Oh well, I guess that's what it is. Thanks – TokyoToo May 25 '20 at 12:29
  • Well you could avoid using `max` at all and implement your own loop finding the max age between the objects. But that, sorry for the word, is just stupid because smart programming is reusing available code and not inventing wheel each time, so I guess that yes - that's the best way – Tomerikoo May 25 '20 at 13:31

1 Answers1

3

I have changed your code to show how you can return instances:

class Dog:

    # constructor method
    def __init__(self, name, age):
        self.name = name
        self.age = age

# three class instance declarations
maxx = Dog("Maxx", 2)
rex = Dog("Rex", 10)
tito = Dog("Tito", 5)

# return the dog with the max age
def oldest_dog(dog_list):
    return max(dog_list,  key=lambda x: x.age)  # use lambda expression to access the property age of the objects

# input
dogs = [maxx, rex, tito]

# I changed this as per instructor's notes.
dog = oldest_dog(dogs)     # gets the dog instance with max age
print(f"The oldest dog is {dog.age} years old.")

Output:

The oldest dog is 10 years old.

EDIT: If you are not allowed to use lambda, then you have to iterate through the objects. Here an implementation without lambda of the function oldest_dog(dog_list):

# return max age instance
def oldest_dog(dog_list):
    max_dog = Dog('',-1)
    for dog in dog_list:
        if dog.age > max_dog.age:
            max_dog = dog

EDIT 2: As @HampusLarsson stated you can also define a function which returns the property age and use it to prevent using lambdas. Here a version:

def get_dog_age(dog):
    return dog.age

# return max age instance
def oldest_dog(dog_list):
    return max(dog_list,  key= get_dog_age)
Code Pope
  • 5,075
  • 8
  • 26
  • 68
  • Ok thank you. But with our beginners python class I don't think we can use lambdas and all that right now. Is there another more elementary version? Something you would see in a 101 class. – TokyoToo May 25 '20 at 12:24
  • @TokyoToo I have added an **EDIT** to include a version of the function without lambda. – Code Pope May 25 '20 at 12:28
  • You can also just make a non-lambda function that does the exact same thing that the lambda does. Just return `dog.x`. and then just set key to the new function. – Hampus Larsson May 25 '20 at 12:31
  • @HampusLarsson this is correct. I have added to answer as **EDIT 2**. – Code Pope May 25 '20 at 12:36
  • Or, use `attrgetter`: `from operator import attrgetter` and then in `max`: `max(dog_list, key=attrgetter('age'))` – Tomerikoo May 25 '20 at 13:48