【问题标题】:Python Nested conditional? double condition followed by another conditionPython嵌套条件?双重条件后跟另一个条件
【发布时间】:2020-05-31 19:00:49
【问题描述】:

我正在尝试学习 python,但在这个问题上苦苦挣扎。

想象一下这种情况:

1- 用户按下按钮 1 和按钮 2 = 程序需要“做一些”

2 - 用户按下按钮 1 和按钮 2,然后按下按钮 3 = 我可以“做一些 2”

3 - 用户按下按钮 2 和按钮 1,然后按下按钮 3 = 我可以“做一些 2”

但是

4 - 如果用户在 button1 和 button2 之前按下 button3 = “do some2”对我来说不行,我只需要“do some”

所以首先按下哪个按钮的顺序对我的目的很重要

def button1_pressed():  # Returns true if the left mouse button is pressed
    button1_state = win32api.GetKeyState(0x01)
    return button1_state < 0

def button2_pressed():  # Returns true if the right mouse button is pressed
    button2_state = win32api.GetKeyState(0x02)
    return  button2_state < 0

def button3_pressed():  # Returns true if the M button is pressed
    button3_state = win32api.GetKeyState(0x4D)
    return button3_state < 0

while True:
    while button1_pressed() and button2_pressed(): # No matter which one is pressed first to me
        print("do some")
        while button3_pressed(): # Only if it is pressed after button1 and button2 are pressed
            print("do some2")
            if button2_pressed() == 0:
                break # this only breaks the inner while loop
        break # added an extra break else it would just be stuck in an endless loop

如果有人给我一些帮助,我将不胜感激。

【问题讨论】:

  • 为什么我们要把这个循环?你想达到什么目的?

标签: python python-3.x nested-loops


【解决方案1】:

您在这里想要的是所谓的“状态机”。您描述的情况称为“状态”,并且在按钮按下停止后它们会持续存在(例如,您可以处于“用户按下按钮 2”的状态,这与“用户正在按下按钮 2”不同)。

pressed = [True, False, False, False]
while True:
  if button1_pressed() and not pressed[1]:
      pressed[1] = True
      if pressed[2]:
          print("do some")
          continue
  if button2_pressed() and not pressed[2]:
      pressed[2] = True
      if pressed[1]:
          print("do some")
          continue
  if button3_pressed() and not pressed[3]:
      pressed[3] = True
      if pressed[1] and pressed[2]:
          print("do some 2")
  if all(pressed):
      # All the buttons have been pressed (in some order).  Done!
      break

您可能会在数据结构中对其进行编码,如下所示:

buttons = [lambda: False, button1_pressed, button2_pressed, button3_pressed]
pressed = [False, False, False, False]
actions = {
    # For each button press, what action happens 
    # based on button(s) previously pressed.
    1: ([2], "do some")
    2: ([1], "do some")
    3: ([1, 2], "do some 2")
}
while True:
    for num in (1, 2, 3):
        if not buttons[num]() or pressed[num]:
            continue
        pressed[num] = True
        prev, action = actions[num]
        if all(pressed[p] for p in prev):
            print(action)
    if any(
        not pressed_now() and was_pressed
        for pressed_now, was_pressed in zip(buttons, pressed)
    ):
        # Break condition: previously pressed button was released
        break

【讨论】:

  • +1 表示状态机;我更喜欢使用命名状态列表(START、AFTER_DUAL_PUSH、AFTER_PUSH_2 等),但想法是一样的。
  • 感谢您的帮助,但按下按钮时我需要它。我想我没有把自己说清楚,我的错。因此,仅当用户按下按钮时才需要执行结果。因此,如果用户停止按下按钮 1 或 2,则所有循环都消失了。如果 use 停止按 M,则仅内部循环停止。抱歉拼写错误,英语不是我的母语。
  • 哦,明白了,所以一旦他们松开按钮,它需要打破吗?这其实很简单,让我稍微修改一下我的答案。
  • 排序.. 如果用户按此顺序按下:按钮 1 + 按钮 2 = 执行某些操作(此按钮的顺序无关紧要),但如果按下按钮 1 + 按钮 2 + M (按此顺序)= 做一些 2,但如果 M + 按钮 1 或 2 + 按钮 1 或 2 = 做一些(按钮 1 或 2 之前的 M 很重要,但 M 之后的 1 或 2 的顺序无关紧要)。在最后一种情况下,如果 M 是 reallead,do some2 需要成为/变成 do some。
  • 我在遵循这一点时遇到了麻烦,但我认为如果您阅读了这段代码并理解它是如何工作的,那么它应该与您尝试做的任何事情都足够接近,您可以弄清楚如何适应它。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-13
  • 1970-01-01
  • 2013-04-19
  • 2012-06-30
  • 1970-01-01
  • 2021-07-29
  • 1970-01-01
相关资源
最近更新 更多