Как да разберете кои битове са зададени на 1 в битов масив

Свързан съм към PLC с Python. Този PLC дава алармени условия в 8-битово представяне. Например:

0110 0010
  • бит 0 = включване/изключване на светлините
  • бит 1 = вентилаторът е включен/изключен
  • бит 2 = аларма вкл./изкл
  • бит 3 = включване/изключване на вратата
  • ...

Всеки бит казва различни условия.

Искам да създам списък с условия и да ги отпечатам заедно, като: вратата е включена, алармите са изключени, светлините са изключени и т.н.

В горния пример има три различни условия. Искам да ги покажа заедно, всички могат да бъдат 1 или 0. Как мога да свържа грешки/условия с битове?


person A. Alper Kunt    schedule 15.05.2015    source източник
comment
Трябва да приложите bitwise and с битова маска, която изолира всеки от полезните битови индикатори, напр. andвключването на байта с 00000001 ще изолира светлините за включване/изключване. и т.н   -  person StuartLC    schedule 15.05.2015
comment
Имайте предвид, че битовата маска за бит n е 2**n или 1 << n: 0b01100010 & 1 << 2 е 0, което ви казва, че алармата е изключена.   -  person jonrsharpe    schedule 15.05.2015
comment
Вижте тук за пример: http://repl.it/oGQ   -  person Malik Brahimi    schedule 15.05.2015
comment
@MalikBrahimi отговаряйте на въпроса или не, но моля, не изпращайте хора към ресурси извън сайта, които може да изчезнат.   -  person jonrsharpe    schedule 15.05.2015


Отговори (2)


За тези видове задачи обичам да създавам речник с битовете, съпоставени с хубавото текстово представяне. Тъй като Python поддържа двоични литерали, той е доста добре самодокументиращ се...

Нещо като:

status_lookup = { 0b00000001 : "Lights",
                  0b00000010 : "Fan",
                  0b00000100 : "Alarm",
                  0b00001000 : "Door"}

След това, ако искате списък с текущите състояния „включени“:

bits = 0x0a # or whatever your input value was
currently_on = [status_lookup[i] for i in status_lookup if i & bits]

Ако искате да ги свържете заедно в низ:

print("; ".join(currently_on))

Като алтернатива, ако използвате Python 3.4+, можете да направите нещо подобно, като използвате новия модул enum:

from enum import IntEnum

class Status(IntEnum):
    Lights = 0b00000001
    Fan = 0b00000010
    Alarm = 0b00000100
    Door = 0b00001000

bits = 0x0a
currently_on = [x for x in Status if x & bits]
person LexyStardust    schedule 15.05.2015
comment
Имайте предвид, че ... if i & bits] също ще работи; ненулевите цели числа са верни, вижте docs.python. org/2/library/stdtypes.html#truth-value-testing - person jonrsharpe; 15.05.2015

Има по-елегантни начини да го направите, но това ще ви помогне да продължите:

s = ''
if value & 1:
    s += "lights on"
else:
    s += "lights off"

if value & 2:
    s += ", fan on"
else:
    s += ", fan off"

if value & 4:
    s += ", alarm on"
else:
    s += ", alarm off"

if value & 8:
    s += ", door on"  #?  "door open"?
else:
    s += ", door off"
person wallyk    schedule 15.05.2015