osdir.com

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Should nested classes in an Enum be Enum members?


On 06/28/2018 05:58 PM, Ben Finney wrote:

> So I remain dumbfounded as to why anyone would want a class to *both* be
> an enumerated type, *and* have callable attributes in its API.

Perhaps I am using Enum incorrectly, but here is my FederalHoliday Enum.  Note that date(), next_business_day, and 
year() are all callables.  The AutoEnum parent assigns values from 1 to n for each member.  It's at Stackoverflow [1] if 
you'd like up- or down-vote it.  ;)

---

class FederalHoliday(AutoEnum):
     NewYear = "First day of the year.", 'absolute', Month.JANUARY, 1
     MartinLutherKingJr = "Birth of Civil Rights leader.", 'relative', Month.JANUARY, Weekday.MONDAY, 3
     President = "Birth of George Washington", 'relative', Month.FEBRUARY, Weekday.MONDAY, 3
     Memorial = "Memory of fallen soldiers", 'relative', Month.MAY, Weekday.MONDAY, 5
     Independence = "Declaration of Independence", 'absolute', Month.JULY, 4
     Labor = "American Labor Movement", 'relative', Month.SEPTEMBER, Weekday.MONDAY, 1
     Columbus = "Americas discovered", 'relative', Month.OCTOBER, Weekday.MONDAY, 2
     Veterans = "Recognition of Armed Forces service", 'relative', Month.NOVEMBER, 11, 1
     Thanksgiving = "Day of Thanks", 'relative', Month.NOVEMBER, Weekday.THURSDAY, 4
     Christmas = "Birth of Jesus Christ", 'absolute', Month.DECEMBER, 25

     def __init__(self, doc, type, month, day, occurance=None):
         self.__doc__ = doc
         self.type = type
         self.month = month
         self.day = day
         self.occurance = occurance

     def date(self, year):
         "returns the observed date of the holiday for `year`"
         if self.type == 'absolute' or isinstance(self.day, int):
             holiday =  Date(year, self.month, self.day)
             if Weekday(holiday.isoweekday()) is Weekday.SUNDAY:
                 holiday = holiday.replace(delta_day=1)
             return holiday
         days_in_month = days_per_month(year)
         target_end = self.occurance * 7 + 1
         if target_end > days_in_month[self.month]:
             target_end = days_in_month[self.month]
         target_start = target_end - 7
         target_week = list(xrange(start=Date(year, self.month, target_start), step=one_day, count=7))
         for holiday in target_week:
             if Weekday(holiday.isoweekday()) is self.day:
                 return holiday

     @classmethod
     def next_business_day(cls, date, days=1):
         """
         Return the next `days` business day from date.
         """
         holidays = cls.year(date.year)
         years = set([date.year])
         while days > 0:
             date = date.replace(delta_day=1)
             if date.year not in years:
                 holidays.extend(cls.year(date.year))
                 years.add(date.year)
             if Weekday(date.isoweekday()) in (Weekday.SATURDAY, Weekday.SUNDAY) or date in holidays:
                 continue
             days -= 1
         return date

     @classmethod
     def year(cls, year):
         """
         Return a list of the actual FederalHoliday dates for `year`.
         """
         holidays = []
         for fh in cls:
             holidays.append(fh.date(year))
         return holidays

--
~Ethan~


[1] https://stackoverflow.com/a/22594360/208880