【问题标题】:Algebra in Python (something better than a switch?)Python中的代数(比开关更好的东西?)
【发布时间】:2014-06-07 15:00:17
【问题描述】:

我已经构建了一个套接字服务器,用于侦听来自另一台客户端机器的命令(我无权访问的代码)。客户端发送与击键相关的数字并发送与修饰键按下相关的修饰代码。比如

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

发送的修饰符代码始终是一个数字。例如修饰符=1。但是,如果发送了超过 1 个键,则可以说修饰符 = 3(即 shift+control)。问题是我如何从数字中找出键。

所以为了简单起见,让我们使用 a,b,c,d- 规则只是组合中的一个。

如果:

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

那么这些是组合的总数:

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

那么在 Python 中计算 n 的最佳方法是什么?一个开关?

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

...等等..

一定有更好的方法吧?

【问题讨论】:

  • “位域”将是一个有趣的搜索。
  • (我知道你的意思可能只是类比的“switch”,但作为记录,Python 没有像 C 那样的 switch 语句。)
  • a+c+db+c+d 出了什么问题?
  • 没什么@jonrsharpe !只是错过了那两个:)

标签: python algebra


【解决方案1】:

您可以通过bitwise arithmetic 的力量做到这一点:

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

这将返回一个列表,其中每个项目都是一个布尔值,指示是否按下了该开关:

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

这就是为什么组件都是 2 的幂 - 当您将总数视为二进制数时,访问每个开关的值变得微不足道(注意颠倒顺序):

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

显示所有选项:

>>> 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

【讨论】:

  • 另外,如果你处理位域,至少使用<< 而不是**
  • 非常感谢。从未在 uni 学习过 comp sci 并通过 php 等级进入 python,当涉及到“位”和任何涉及数学的东西时,我确实感到完全不知所措......再次感谢。
【解决方案2】:

使用bitwise operations 检查不同的键。选择常量,以便每个修饰符由不同的位表示。

MOD_SHIFT       = 0b00000001  # ==  1
MOD_CONTROL     = 0b00000010  # ==  2
MOD_ALT         = 0b00000100  # ==  4
MOD_WIN         = 0b00001000  # ==  8

这意味着,您可以通过or将各个值组合在一起来表示多个修饰键。

MOD_ALT|MOD_WIN = 0b00001100  # == 12

另一方面,如果您想知道是否按下了特定键,请使用anding。

if keys_pressed & MOD_SHIFT:
    print "Shift key is pressed."

很难说在您的具体情况下如何处理这个问题。我猜你真的不想只打印出按下的键。给我们更多信息,我们或许能提供更好的帮助。

【讨论】:

  • 是的,但0x00001000 不是 8。
  • @thg435:脑子放个屁。但你可以编辑我的答案而不是明智地破解,你知道吗?
  • 对不起,如果我的评论冒犯了您,感谢您的修复。
  • @thg435:没有冒犯!我是认真的:随意自己修复这些明显的错误
猜你喜欢
  • 2011-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-05
  • 2012-04-15
  • 2010-11-29
相关资源
最近更新 更多