Python, SQLAlchemy: хранение рабочих часов в виде двоичной битовой маски - PullRequest
2 голосов
/ 26 июля 2011

Я программирую на Python и использую SQLAlchemy для хранения рабочих часов.
Рабочее время состоит из трех частей:

  1. Дни недели, хранящиеся в двоичном формате как битовая маска
  2. время открытия бизнеса,
  3. время закрытия бизнеса.

Битовая маска работает следующим образом. Есть 7 цифр, которые либо 0, либо 1, которые будут представлять различные последовательности дней недели. Каждая позиция представляет день недели. Первая позиция обозначает понедельник, а последняя - воскресенье. Например, 1111100 представляет понедельник-пятница, а 0000111 пятница-суббота. Кроме того, я храню часы в военное время, 0600 означает 6 утра и 1800 означает 6 вечера.

hours = Table('hours', Base.metadata,
    Column("id", Integer, primary_key=True),
    Column("businessid", Integer, ForeignKey('businesses.id')),
    Column("days", Integer),
    Column("open", Integer),
    Column("close", Integer),
)

class Hours(object):
    def __init__(self, days=None, open=None, close=None):
        self.days = days
        self.open = open
        self.close = close

mapper(Hours, hours)
mapper(Business, businesses, properties={
    'hours': relationship(Hours, backref='business'),
})

Как Pythonic может выяснить, когда две из битовых масок, представляющих дни недели, перекрываются? А также, каков наилучший способ узнать, открыт ли бизнес в настоящее время, если ему предоставлены две пары объектов Hours?

1 Ответ

3 голосов
/ 26 июля 2011

Что касается проверки дней недели, то если в двоичном виде вы имеете в виду строку вида '1011011':

overlap = [n for n in range(7) if (bitmask1[n] == bitmask2[n] == '1')]

выдаст вам список чисел (от 0-6) перекрывающихся дней - [4] для перекрывающегося в пятницу.

overlap = ''.join(('1' if (bitmask1[n] == bitmask2[n] == '1') else '0') for n in range(7))

Даст вам новую строку битовой маски - '00000100' для перекрытия в пятницу.

Если вы на самом деле храните число в виде целого числа, возможно, проще всего просто преобразовать его в единицу с помощью bin(bitmask)[2:] или "{0:b}".format(bitmask).

Я не уверен, что вы подразумеваете под "открытыми в настоящее время ... двумя парами часовых объектов". Хотите ли вы пересечение двух пар часов? Если они целые часы, это просто:

[hour for hour in range(firsthour, secondhour) if hour in range(openinghour, closinghour)

Даст вам список часов в обоих диапазонах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...