NotAnAmbiTurner
NotAnAmbiTurner

Reputation: 2743

Controlling how a custom class is sorted / indexed?

I am attempting to represent a calendar in a Class-based format.

Currently, the data is represented in an OrderedDict of the following form:

from collections import OrderedDict

dictionary = OrderedDict()
dictionary[date] = {'attr1': ... ,
                    'attr2': ... ,
                    ... }

I would ideally like to instantiate some sort of EnhancedDay class which represents the data in the dictionary, with a corresponding EnhancedCalendar class that holds a sorted container (list, OrderedDict?) of EnhancedDays. Features I'm looking at:

  1. a number of EnhancedDay objects to be stored, sorted, as EnhancedCalendar.attr
  2. ability to retrieve / work with EnhancedDays by date (i.e. I would like to use the date as a sort of 'key' so I could retrieve an EnhancedDay through something similar to EnhancedCalendar.attr[date]
  3. a way to append/modify attributes of EnhancedDay instances which are stored as part of a EnhancedCalendar instance so that if I were to attempt to add an EnhancedDay to EnhancedCalendar.attr where there already was an EnhancedDay object in EnhancedCalendar.attr representing that date, the EnhancedDay object would instead be merged "automatically."

I think for #1, I basically understand the answer:

  1. I would use the @total_ordering decorator (https://docs.python.org/2/library/functools.html#functools.total_ordering), specify an __eq__ and other comparison operator to use the EnhancedDay's date attr, and be good-to-go.
  2. No idea. There are a few posts on SO on this topic, but I haven't found any that meet my needs.
  3. The best way I know would be to write a custom merging function (something akin to a custom_append). EnhancedCalendar.attr[date].custom_append(EnhancedDay) and have a merge occur OR if attr[date] doesn't exist, create attr[date] Again, not sure of the best/smoothest way to do this. I'd love to use +=.

Also: what would be the best datatype to store the EnhancedDay instances in, in the EnhancedCalendar instance?

Alternatively, given what I'm trying to accomplish, some of my thinking might just be... off. Any help on that front would be appreciated.

Alternatively, this all may be way more trouble than it's worth, in which case I'm still interested in how you would theoretically accomplish these things using classes.

Upvotes: 0

Views: 31

Answers (1)

Robin Davis
Robin Davis

Reputation: 632

For #2 There are a few ways to do this. One way might be to convert the date to some sort of canonical format, then use that as a string index into a dictionary.

For #3 take a look at https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence

It makes sure you implement the functions required for indexing and += operators to work the way you want. Specifically for += to work you need to override the __iadd__() function. For Calendar[date] to do what you want you'll need to override the __getitem__() and __setitem__() functions -- however collections.DefaultDict nearly does what you want there so I might be tempted to base EnhancedCalendar off of that.

I think I would use a list datatype to store the days inside the calendar, then you would index by day-1.

Upvotes: 1

Related Questions