#python #bit-fields
#python #битовые поля
Вопрос:
Я использую 5-разрядное битовое поле для отслеживания состояния системы сигнализации в скрипте Python. Например, 0 в MSB означает «Не включен», в то время как 1 в MSB означает «Включен» и т.д. Это позволяет XOR в предыдущем состоянии и текущем состоянии быстро выдавать, какие биты были изменены:
previous = 0b11001
current = 0b10011
delta = current ^ previous # delta = 0b01010
Следующий шаг в моем коде — сгенерировать строку, описывающую, что изменилось, на основе delta
. Существует 10 возможных состояний с описаниями. Мне интересно, как наилучшим образом создать эту строку. То, что у меня есть ниже, работает, но кажется неуклюжим:
statusKey = {
0: ' * Disarmed',
10: ' * No Alarm',
20: ' * No Fire',
30: ' * No Check',
40: ' * No AC',
1: ' * Armed',
11: ' * Alarm',
21: ' * Fire',
31: ' * Check',
41: ' * AC'
}
alert = ''
for i in range (5):
if (0b10000 amp; (delta << i)):
alert = ''.join((alert,statusKey[(10*i) (0b01 amp; (current >> (4-i)))]))
#alert = 'No Alarm * Check'
Есть ли лучший способ структурировать данные в statusKey
?
И есть ли лучший способ сгенерировать alert
строку на основе этой структуры?
Комментарии:
1. вы могли бы использовать
numpy.bitwise_and
поверх столбца, но это немного чрезмерно для такого количества данных. Ваш метод не ужасен.2. @stevedc этот вопрос может лучше подойти для проверки кода , если вы хотите задать его там.
Ответ №1:
Старайтесь использовать как можно меньше побитовых математических операторов, потому что это делает ваш код очень нечитаемым. Простое понимание списка — это все, что вам действительно нужно. Кроме того, вы хотите, чтобы структура данных о вашем битовом статусе была самоописывающейся. Тот, кто читает это впервые, должен сразу понять логику.
bit_status = {
0: ("Disarmed", "Armed"),
1: ("No Alarm", "Alarm"),
2: ("No Fire", "Fire"),
3: ("No Check", "Check"),
4: ("No AC", "AC")
}
previous = 0b11001
current = 0b10011
current_bits = [current >> i amp; 1 for i in reversed(range(5))]
delta_bits = [(current ^ previous) >> i amp; 1 for i in reversed(range(5))]
status = [bit_status[index][current_bits[index]]
for index, delta_bit in enumerate(delta_bits) if delta_bit == 1]
print(" * ".join(status))
# No Alarm * Check