I try to implement mergesort using 'Person' class, however I cannot use any attributes of 'Person' outside this class. I want to change the key argument of 'mergesort' function based on sort_key value in 'create_persons_list' function - I use lambda function for it. I create a tuple in person_objects with name, age, height and weight. Thus, if I want to sort the list based on names, set the sorting key to index 0 of the tuple.
import numpy as np
#import load_names
import enum
from merge_sort import mergesort
# NAMES is a list or array with common first names.
NAMES = ["Alice", "Bob", "Charlie", "David", "Eve", "Frank", "Grace", "Hank", "Ivy", "Jack"] # Variables in the global namespace should be capitalized.
class Person():
def __init__(self, name, age, height, weight):
self._name = name
self._age = age
self._height = height
self._weight = weight
def __len__(self):
return len(self.data)
def __repr__(self):
return f"{self._name}, {self._age} years, {self._height} cm, {self._weight} kg\n"
def __eq__(self, other):
return (self._age, self._height, self._weight) == (other._age, other._height, other._weight)
def __lt__(self, other):
return (self._age, self._height, self._weight) < (other._age, other._height, other._weight)
def __le__(self, other):
return (self._age, self._height, self._weight) <= (other._age, other._height, other._weight)
def __gt__(self, other):
return (self._age, self._height, self._weight) > (other._age, other._height, other._weight)
def __ge__(self, other):
return (self._age, self._height, self._weight) >= (other._age, other._height, other._weight)
def __int__(self):
return int(self._age)
def __float__(self):
return float(self._age)
def __str__(self):
return f"{self._name}, {self._age} years, {self._height} cm, {self._weight} kg"
def create_persons_list(n=10, sort_key='weight'):
person_objects = [(Person(np.random.choice(NAMES), np.random.randint(18, 101), np.random.randint(150, 201), np.random.randint(45, 101))) for _ in range(n)]
#print("po: ",person_objects[0])
if sort_key == 'name':
return mergesort(person_objects, key=lambda x: x[0])
elif sort_key == 'age':
return mergesort(person_objects, key=lambda x: x[1])
elif sort_key == 'height':
return mergesort(person_objects, key=lambda x: x[2])
elif sort_key == 'weight':
return mergesort(person_objects, key=lambda x: x[3])
else:
raise ValueError("Invalid sort_key. Supported values are 'name', 'age', 'height', and 'weight'.")
sorted_persons_by_name = create_persons_list(sort_key='name')
sorted_persons_by_age = create_persons_list(sort_key='age')
sorted_persons_by_height = create_persons_list(sort_key='height')
sorted_persons_by_weight = create_persons_list(sort_key='weight')
print("Sorted by name: \n")
print(sorted_persons_by_name)
print("Sorted by age: \n")
print(sorted_persons_by_age)
print("Sorted by height: \n")
print(sorted_persons_by_height)
print("Sorted by weight: \n")
print(sorted_persons_by_weight)
#print(create_persons_list())
If I execute it, I get a TypeError, that 'Person' object is not subscritable. Is it possible to implement my idea without using any attributes outside 'Person' class?
The
xthat gets passed to the lambda function is a Person object, not a tuple. So it should be something likekey=lambda x: x._ageor whatever is appropriate.