【问题标题】:Python timer for timing用于计时的 Python 计时器
【发布时间】:2014-09-16 05:43:33
【问题描述】:

这个程序会询问用户问题,但每个问题只给他/她 10 秒的时间来回答。如果他们在时限内回答了问题,程序就会在那个瞬间进入下一个问题。此外,如果他们没有在规定时间内回答,程序将在 10 秒后跳到下一个问题。我知道计时器类,我该如何整合它来做到这一点?这是我到目前为止的代码。不要担心 pmXXXXX 的东西,这是我用于学校项目的软件。

    #question1
one = raw_input("Question 1:" + "\n" + qa + "\n" + "x" + "\n" + "A. Brightens it" + "\n" + "B. A gradient of black to white." + "\n" + "C. A color pallete.")
if(one.lower() == "b"):
    print "Congrats! 10 points."
        pmNewComputedImage("Question 1 Answer", 256, 256, "x")
        score += 10
else:
        print "Wrong. -10 points. Here's the answer."
        window1 = pmNewComputedImage("Question 1 Answer", 256, 256, "x")
        score -= 10



#question2
pmNewComputedImage("Question 2", 256, 256, "x*2")
two = raw_input("Question 2:" + "\n" + qb + "\n" + "A. x/2" + "\n" + "B. y/2" + "\n" + "C. x*2")
if (two.lower() == "c"):
    print "Congrats! 10 points."
    score += 10
else:
    print "Wrong -10 points. The answer is C."
    score -= 10


def stopwatch(seconds):
    import time
    start = time.time()
    time.clock()
    elapsed = 0
    while elapsed < seconds:
                elapsed = time.time() - start
                print "Seconds count: %02d" % elapsed
                time.sleep(1)

【问题讨论】:

  • 如果用户花的时间太长,你想打断他,放弃提示和他已经输入的任何内容,等等?还是等他,然后告诉他他花了太长时间?如果是前者,这需要跨平台吗?如果没有,您需要它用于什么平台?
  • 我想如果达到 10 秒,然后关闭现有的问题窗口并显示另一个窗口说“超时”,然后进入下一个问题。我不清楚,你说的平台是什么意思?
  • 什么窗口?您正在使用raw_input,它只要求输入当前标准输入。如果您在 IDLE 开发环境中运行(您的真实用户都不会这样做),这会涉及一个弹出窗口,但通常它将是命令行上启用 readline 的提示。
  • 对于“平台”:Mac、Windows、Linux 等。但理想情况下,尽可能具体:Windows 8.1 64-bit with official-installer 64-bit Python 2.7.4,或 OS X 10.9 .3 和 Homebrew 安装的 Python 2.7,或 Red Hat Enterprise Linux 5 和默认的 Python 2.6.8,或其他。
  • 只是一个旁注。与其在输入提示中的许多小字符串之间使用+,不如将​​提示作为单个字符串进行,如下所示:"Question 1:\n%s\nx\nA. Brightens it\nB. A gradient of black to white.\nC. A color palette." % qa。然后您可以将所有提示字符串收集到一个整洁的元组或列表中。此外,if(one.lower() == "b"): 会比 if one.upper() == "B"): 更好,因为您在提示符中使用大写。

标签: python timer while-loop


【解决方案1】:

raw_input 函数在用户输入内容之前不会返回,因此您不能直接执行此操作。

有多种解决方法。您可以在后台线程中运行计时器并使用信号中断主线程;您可以使用 signal.alarm 自动执行此操作,甚至不需要后台线程(但在 Windows 上不需要);您可以将sys.stdin 置于非阻塞模式并使用较低级别的I/O 来读取而不是raw_input;您可以在子进程中进行输入,如果时间过长则终止它等。

这是第一个版本的示例,它甚至可以在 Windows 上运行,尽管我不保证它会在实践中实现:

import os
import signal
import threading

try:
    mysig = signal.CTRL_C_EVENT
except NameError:
    mysig = signal.SIGINT

def timed_raw_input(prompt, timeout):
    t = threading.Timer(timeout, lambda: os.kill(os.getpid(), mysig))
    try:
        t.start()
        result = raw_input(prompt)
    except KeyboardInterrupt:
        return '' # or whatever you want to do on timeout
    else:
        t.cancel()
        return result

我不确定CTRL_C_EVENT 是否真的会在 Windows 上引发 KeyboardInterrupt;您可能必须使用signal.signal 安装您自己的处理程序。阅读链接的文档,然后自己测试一下。如果您必须安装信号处理程序,您不妨使用其他可用的跨平台信号之一而不是 CTRL_C_EVENT,并引发您自己的自定义异常而不是 KeyboardInterrupt

【讨论】:

  • 很好,我在 Windows 机器上,它不会中断,即使使用标准输入(我用 stdin() 替换了 raw_input )它也会保持不间断。我刚刚调用了 timed_raw_input("whats x?", 3.0)
  • @user1767754:好的,所以请使用signal.signal 编写您自己的处理程序,引发自定义异常,可能使用文档中提到的Windows 兼容信号名称之一,而不是CTRL_C_EVENT
  • @user1767754:但是,如果您在 IDLE 中运行它,值得一提的是,IDLE 对信号处理做了一些时髦的事情,并且任何实际用户都不会在 IDLE 中运行,所以这可能不是测试事物的最佳方法。 (如果你想要一个 GUI,一个更好的解决方案是构建一个简单的 Tkinter GUI,它需要的代码不会比构建一个警报计时器多多少,并且会有很多其他优点——比如在窗口中显示结果而不是在输出日志。)
  • “平台是什么意思”是“我正在使用 Windows”的代码。 :) 是的,这绝对是 GUI 的工作。
  • @PM2Ring:这在几年前是正确的,但现在它也可以表示“我正在使用 Mac”。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-22
  • 1970-01-01
  • 1970-01-01
  • 2010-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多