Home > Enterprise >  How to sort objects and attributes by date?
How to sort objects and attributes by date?

Time:10-29

I have next code:

class Petshop():
    def __init__(self, entryDate, name, ownerName):
        self.entryDate = entryDate
        self.name = name
        self.ownerName = ownerName

class Pets():
    def __init__(self):
        self.petsList = []
    
    def addPets(self, entryDate, name, ownerName):
        entry_pet = Petshop(entryDate, name, ownerName)
        self.petsList.append(entry_pet)
    
    def printPets(self):
        for pet in self.petsList:
            if pet.entryDate == pet.entryDate:#Here I try to sort by date
                print("---------------",pet.entryDate,'------------------')
                print("Name:", pet.name)
                print("Owner name:", pet.ownerName)

pet = Pets()

pet.addPets('04/13/2021','Pinky', 'David Smith')
pet.addPets('07/10/2020', 'Charlie', 'Joe Davis')
pet.addPets('12/22/2018', 'Teddy', 'Carl Johnson')
pet.addPets('07/10/2020', 'Kenny', 'Susan Jones')
pet.addPets('04/13/2021','Max', 'Bryan Miller')
pet.addPets('07/10/2020', 'Buddy', 'Kathy Brown')
pet.printPets()

With that code I would like to sort pets entry by date, so for example I expect to print the next:

--------------- 04/13/2021 ------------------
Name: Pinky
Owner name: David Smith
Name: Max
Owner name: Bryan Miller
--------------- 07/10/2020 ------------------
Name: Charlie
Owner name: Joe Davis
Name: Kenny
Owner name: Susan Jones
Name: Buddy
Owner name: Kathy Brown
--------------- 12/22/2018 ------------------
Name: Teddy
Owner name: Carl Johnson

But instead of that I get to print each object, and this is not what I expect:

--------------- 04/13/2021 ------------------
Name: Pinky
Owner name: David Smith
--------------- 07/10/2020 ------------------
Name: Charlie
Owner name: Joe Davis
--------------- 12/22/2018 ------------------
Name: Teddy
Owner name: Carl Johnson
--------------- 07/10/2020 ------------------
Name: Kenny
Owner name: Susan Jones
--------------- 04/13/2021 ------------------
Name: Max
Owner name: Bryan Miller
--------------- 07/10/2020 ------------------
Name: Buddy
Owner name: Kathy Brown

I tried to make a kind of sort in printPets(), but it does not work. So I come here for help. Thanks!

CodePudding user response:

itertools.groupby is what you're looking for:

    def printPets(self):
        self.petsList.sort(key=lambda p: p.entryDate)
        for group in groupby(self.petsList, key=lambda p: p.entryDate):
            ls = list(group)
            print("---------------", ls[0], '------------------')
            for pet in list(ls[1]):
                print("Name:", pet.name)
                print("Owner name:", pet.ownerName)

CodePudding user response:

You can use sorted() with lambda function passed as argument for key. Edit: this code should produce exactly what you expect. i.e one input date print per distinct date.

    def printPets(self):
      for inputdate in sorted(list(set(i.entryDate for i in self.petsList))):
          print("---------------",inputdate,'------------------')
          for pet in list(filter(lambda x: x.entryDate == inputdate, self.petsList)):
            print("Name:", pet.name)
            print("Owner name:", pet.ownerName)

CodePudding user response:

This code if pet.entryDate == pet.entryDate is invalid in your program, you can make the following changes:

entry_data = ""
if entry_data != pet.entryDate:
    ...
entry_data = pet.entryDate

Sort using the function sorted.

class Petshop:
    def __init__(self, entryDate, name, ownerName):
        self.entryDate = entryDate
        self.name = name
        self.ownerName = ownerName


class Pets:
    def __init__(self):
        self.petsList = []

    def addPets(self, entryDate, name, ownerName):
        entry_pet = Petshop(entryDate, name, ownerName)
        self.petsList.append(entry_pet)

    def printPets(self):
        entry_data = ""
        for pet in sorted(self.petsList, key=lambda pet_shop: pet_shop.entryDate):
            if entry_data != pet.entryDate:  # Here I try to sort by date
                print("---------------", pet.entryDate, '------------------')
            print("Name:", pet.name)
            print("Owner name:", pet.ownerName)
            entry_data = pet.entryDate


pet = Pets()

pet.addPets('04/13/2021', 'Pinky', 'David Smith')
pet.addPets('07/10/2020', 'Charlie', 'Joe Davis')
pet.addPets('12/22/2018', 'Teddy', 'Carl Johnson')
pet.addPets('07/10/2020', 'Kenny', 'Susan Jones')
pet.addPets('04/13/2021', 'Max', 'Bryan Miller')
pet.addPets('07/10/2020', 'Buddy', 'Kathy Brown')
pet.printPets()

--------------- 04/13/2021 ------------------
Name: Pinky
Owner name: David Smith
Name: Max
Owner name: Bryan Miller
--------------- 07/10/2020 ------------------
Name: Charlie
Owner name: Joe Davis
Name: Kenny
Owner name: Susan Jones
Name: Buddy
Owner name: Kathy Brown
--------------- 12/22/2018 ------------------
Name: Teddy
Owner name: Carl Johnson

CodePudding user response:

You have to add a custom comparison functions in order to sort by criteria. Consider the example:

from datetime import datetime

class Petshop():
    def __init__(self, entryDate, name, ownerName):
        self.entryDate = entryDate
        self.name = name
        self.ownerName = ownerName
        # create a utc time or custom integer fro fast compare 
        self.cmptime =  int(datetime.strptime(entryDate, "%m/%d/%Y").strftime('%Y%m%d'))
        pass

    def __lt__(self, other):
        return self.cmptime < other.cmptime

    def __eq__(self, other):
        return self.cmptime == other.cmptime


class Pets():
    def __init__(self):
        self.petsList = []

    def addPets(self, entryDate, name, ownerName):
        entry_pet = Petshop(entryDate, name, ownerName)

        self.petsList.append(entry_pet)

    def printPets(self):
        self.petsList.sort()
        for pet in (self.petsList):
            if pet.entryDate == pet.entryDate:  # Here I try to sort by date
                print("---------------", pet.entryDate, '------------------')
                print("Name:", pet.name)
                print("Owner name:", pet.ownerName)


pet = Pets()


pet.addPets('04/13/2021', 'Pinky', 'David Smith')
pet.addPets('07/10/2020', 'Charlie', 'Joe Davis')
pet.addPets('12/22/2018', 'Teddy', 'Carl Johnson')
pet.addPets('07/10/2020', 'Kenny', 'Susan Jones')
pet.addPets('04/13/2021', 'Max', 'Bryan Miller')
pet.addPets('07/10/2020', 'Buddy', 'Kathy Brown')
pet.printPets()

I create a simple integer from the date time but you may convert to UTC time, then override __lt__ and __gt__ functions on order for the sort function to work.

CodePudding user response:

You can import datetime and compare the dates while creating a petsList:

from datetime import datetime

def getDateFromStr(date):
    date_list = []
    for i in date.split('/'):
        date_list.append(int(i))
    # date_list = list(map(lambda x: int(x), date.split('/')))
    return datetime(date_list[2], date_list[0], date_list[1]).date()

class Petshop():
    def __init__(self, entryDate, name, ownerName):
        self.entryDate = entryDate
        self.name = name
        self.ownerName = ownerName

class Pets():
    def __init__(self):
        self.petsList = []
    
    def addPets(self, entryDate, name, ownerName):
        entry_pet = Petshop(entryDate, name, ownerName)
        # creating petsList sorted by date already
        if len(self.petsList) == 0:
            self.petsList.append(entry_pet)
        else:
            for i, pet in enumerate(self.petsList):
                if getDateFromStr(pet.entryDate) < getDateFromStr(entryDate):
                    self.petsList.insert(i, entry_pet)
                    break
                elif i == len(self.petsList) - 1:
                    self.petsList.append(entry_pet)
                    break
    
    def printPets(self):
        for pet in self.petsList:
            if pet.entryDate == pet.entryDate:#Here I try to sort by date
                print("---------------",pet.entryDate,'------------------')
                print("Name:", pet.name)
                print("Owner name:", pet.ownerName)

pet = Pets()

pet.addPets('04/13/2021','Pinky', 'David Smith')
pet.addPets('07/10/2020', 'Charlie', 'Joe Davis')
pet.addPets('12/22/2018', 'Teddy', 'Carl Johnson')
pet.addPets('07/10/2020', 'Kenny', 'Susan Jones')
pet.addPets('04/13/2021','Max', 'Bryan Miller')
pet.addPets('07/10/2020', 'Buddy', 'Kathy Brown')
pet.printPets()

CodePudding user response:

You have to add magic method __lt__ to your class for sorting to work.

class Petshop():
    def __init__(self, entryDate, name, ownerName):
        self.entryDate = entryDate
        self.name = name
        self.ownerName = ownerName

    def __lt__(self, other):
        return self.entryDate < other.entryDate


class Pets():
    def __init__(self):
        self.petsList = []

    def addPets(self, entryDate, name, ownerName):
        entry_pet = Petshop(entryDate, name, ownerName)
        self.petsList.append(entry_pet)

    def printPets(self):
        for pet in sorted(self.petsList):
            if pet.entryDate == pet.entryDate:  # Here I try to sort by date
                print("---------------", pet.entryDate, '------------------')
                print("Name:", pet.name)
                print("Owner name:", pet.ownerName)


pet = Pets()

pet.addPets('04/13/2021', 'Pinky', 'David Smith')
pet.addPets('07/10/2020', 'Charlie', 'Joe Davis')
pet.addPets('12/22/2018', 'Teddy', 'Carl Johnson')
pet.addPets('07/10/2020', 'Kenny', 'Susan Jones')
pet.addPets('04/13/2021', 'Max', 'Bryan Miller')
pet.addPets('07/10/2020', 'Buddy', 'Kathy Brown')
pet.printPets()
  • Related