Search code examples
pythonalgebra

Algebra in Python (something better than a switch?)


I've built a socket server that listens for commands from another client machine (the code to which I don't have access to). The client sends a number which relates to key strokes and sends a modifier code which relates to the modifier key presses. So for example

shift=1
control=2
alt=4
win=8

The modifier code sent is always one number. e.g. modifier=1. But if more than 1 key is being sent it could be say modifier=3 (i.e. shift+control). The question is how I work out what the keys are from the number.

So to make this simple lets use a,b,c,d- Rules are only one of each in a combination.

So if:

a=1
b=2
c=4
d=8

Then these are the total number of combinations:

a+b=> 3
a+c=> 5
a+d=> 9
b+d=> 10
c+b=> 6
c+d=> 12

a+b+c=> 7
a+b+d=> 11

a+b+c+d=> 15

So what is the best way of calcuating n in Python? A switch?

switch(n):
    case 3:
        print 'its a+b'
     case 5:
         print 'its a+c'

...etc..

there must be a better way right?


Solution

  • You can do this with the power of bitwise arithmetic:

    def switches(n, num=4):
        return [n & (2**i) > 0 for i in range(num)]
    

    This will return a list where each item is a boolean indicating whether that switch is pressed:

    >>> switches(10)
    [False, True, False, True]
    #  a      b     c      d 
    

    This is why the components are all powers of 2 - it makes it trivial to access the value of each switch, when you consider the total as a binary number (note reversed order):

    >>> format(10, 'b') # show 10 as a binary number
    '1010'
    #8421
    #dcba
    

    To show all of the options:

    >>> for i in range(2**4):
        print(i, '\t', format(i, '04b'))
    
    
    0    0000 # no switches
    1    0001 # a only
    2    0010
    3    0011
    4    0100
    5    0101
    6    0110
    7    0111 # a, b and c
    8    1000
    9    1001
    10   1010 # b and d
    11   1011
    12   1100
    13   1101
    14   1110
    15   1111 # all switches