How to quick sort list of objects by different attributes using the same method?

Advertisements

My class is as below:

class Member:
  def __init__(self, name, zip, hire_date, birth_date):
    self.id = id
    self.name = name
    self.zip = zip
    self.hire_date = hire_date
    self.birth_date = birth_date

  def get_name(self):
    return self.name

  def get_birth_date(self):
    return self.birth_date

  def get_hire_date(self):
    return self.hire_date

  def get_zip_code(self):
    return self.zip

I have need to quick sort a list of this class object based on zip code, name, birth_date and hire_date. I can achieve these using individual sort methods. For example, quick sort by zip code:

def partition(array, begin, end):
    pivot = begin
    for i in range(begin+1, end+1):
        if array[i].get_zip_code() <= array[begin].get_zip_code():
            pivot += 1
            array[i], array[pivot] = array[pivot], array[i]
    array[pivot], array[begin] = array[begin], array[pivot]
    return pivot



def quicksort(array, begin=0, end=None):
    if end is None:
        end = len(array) - 1
    def _quicksort(array, begin, end):
        if begin >= end:
            return
        pivot = partition(array, begin, end)
        _quicksort(array, begin, pivot-1)
        _quicksort(array, pivot+1, end)
    return _quicksort(array, begin, end)

This works fine. But now how do I make the same method work on all attributes; ideally by passing an additional argument to quicksort() defining the attribute to sort on. I also wish to not call object attributes directly but by using getter methods.

This is output after sorting by zip code

Name    Zip Hire Date   Birth Date
Cosmo Kramer 111-222 2019-06-01 1979-08-12
George Costanza 131-212 2016-06-01 1980-08-12
Jerry Seinfeld 223-212 2017-06-01 1981-06-15
John Wayne 323-212 2018-06-01 1962-06-17

>Solution :

You can achieve this by defining another method inside your class:

class Metric:
    b_date = "birth_date"
    h_date = "hire_date"
    zip_code = "zip_code"
    name = "name"


class Member:
    def __init__(self, name, zip, hire_date, birth_date):
        self.id = id
        self.name = name
        self.zip = zip
        self.hire_date = hire_date
        self.birth_date = birth_date

    def get_name(self):
        return self.name

    def get_birth_date(self):
        return self.birth_date

    def get_hire_date(self):
        return self.hire_date

    def get_zip_code(self):
        return self.zip

    def get_metric_value(self, metric):
        if metric == Metric.b_date:
            return self.get_birth_date()
        elif metric == Metric.h_date:
            return self.get_hire_date()
        elif metric == Metric.zip_code:
            return self.get_zip_code()
        elif metric == Metric.name:
            return self.get_name()

def partition(array, begin, end, metric):
    pivot = begin
    for i in range(begin+1, end+1):
        if array[i].get_metric_value(metric) <= array[begin].get_metric_value(metric):
            pivot += 1
            array[i], array[pivot] = array[pivot], array[i]
    array[pivot], array[begin] = array[begin], array[pivot]
    return pivot

def quicksort(array, metric, begin=0, end=None):
    if end is None:
        end = len(array) - 1
    def _quicksort(array, begin, end):
        if begin >= end:
            return
        pivot = partition(array, begin, end, metric)
        _quicksort(array, begin, pivot-1)
        _quicksort(array, pivot+1, end)
    return _quicksort(array, begin, end)

quicksort(array, Metric.zip_code)  # or any other metric ...

Leave a ReplyCancel reply