>>> from env_helper import info; info()
待更新

5.3. 项目:超级秒表

假设要记录在没有自动化的枯燥任务上花了多少时间。 你没有物理秒表,要为笔记本或智能手机找到一个免费的 秒表应用,没有广告,且不会将你的浏览历史发送给市场 营销人员,又出乎意料地困难(在你同意的许可协议中, 它说它可以这样做。你确实阅读了许可协议,不是吗?)。 你可以自己用Python写一个简单的秒表程序。

总的来说,你的程序需要完成:

  • 记录从按下回车键开始,每次按键的时间,每次按键 都是一个新的“单圈”。

  • 打印圈数、总时间和单圈时间。

这意味着代码将需要完成以下任务:

  • 在程序开始时,通过调用 time.time() 得到当前时间, 将它保存为一个时间戳。在每个单圈开始时也一样。

  • 记录圈数,每次用户按下回车键时加1。

  • 用时间戳相减,得到计算流逝的时间。

  • 处理 Keyboardlnterrupt异常, 这样用户可以按Ctrl-C退出。

打开一个新的文件编辑器窗口,并保存为 stopwatch.py

5.3.1. 第1步:设置程序来记录时间

秒表程序需要用到当前时间,所以要导入的 time 模块。程序在调用 input() 之前, 也应该向用户打印一些简短的说明,这样计时器 可以在用户按下回车键后开始。然后,代码将开始 记录单圈时间。在文件编辑器中输入以下代码,为 其余的代码编写TODO注释,作为占位符:

>>> #! python3
>>> # stopwatch.py - A simple stopwatch program.
>>>
>>> import time
>>>
>>> # Display the program's instructions.
>>> print('Press ENTER to begin. Afterwards, press ENTER to "click" the stopwatch.Press Ctrl-C to quit.')
>>> input()       # press Enter to begin
>>> print('Started.')
>>> startTime = time.time() # get the first lap's start time
>>> lastTime = startTime
>>> lapNum = 1
>>>
>>> # TODO: Start tracking the lap times.
Press ENTER to begin. Afterwards, press ENTER to "click" the stopwatch.Press Ctrl-C to quit.
Started
Started.

既然我们已经编码显示了用户说明,那就开始第一圈, 记下时间,并将圈数设为1。

5.3.2. 第2步:记录并打印单圈时间

现在,让我们编码开始每一个新的单圈,计算前一圈花了 多少时间,并计算自启动秒表后经过的总时间。我们将显 示的单圈时间和总时间,为每个新的单圈增加 圈计数。将下面的代码添加到程序中:

#! python3
# stopwatch.py - A simple stopwatch program.

import time

print('Press ENTER to begin. Afterwards, press ENTER to "click" the stopwatch.Press Ctrl-C to quit.')
input()       # press Enter to begin
print('Started.')
startTime = time.time() # get the first lap's start time
lastTime = startTime
lapNum = 1

# Start tracking the lap times.
try:
    while True:

        input()
        lapTime = round(time.time() - lastTime, 2)
        totalTime = round(time.time() - startTime, 2)
        print('Lap #%s: %s (%s)' % (lapNum, totalTime, lapTime),end=' ')
        lapNum += 1
        lastTime = time.time() # reset the last lap time
except Keyboardlnterrupt:
    # Handle the Ctrl-C exception to keep its error message from displaying.
    print('\nDone.')

如果用户按Ctrl-C停止秒表, Keyboardlnterrupt 异常将抛出, 如果程序的执行不是一个 try 语句,就会崩溃。为了防止崩溃, 我们将这部分程序包装在一个 try 语句中。我们将在 except 子句中处理异常所以当Ctrl-C按下并引发异常时,程序执行转向 except 子句,打印 Done ,而不是 Keyboardlnterrupt 错误消息。在此之前,执行处于一个无限循环中,调用 input() 并等待,直到用户按下回车键结束一圈。当一圈结束时,我们用当 前时间 time.time() 减去该圈开始的时间lastTime,计算该 圈花了多少时间。我们用当前时间减去秒表最开始启动的时间 startTime ,计算总共流逝的时间 。

由于这些时间计算的结果在小数点后有许多位(如4.766272783279419), 所以我们用 round() 函数,将浮点值四舍五入到小数点后两位。

print('Lap #%s: %s (%s)' % (lapNum, totalTime, lapTime),end=' ')中, 我们打印出圈数,消耗的总时间和单圈时间。由于用户为 input() 调用 按下回车时,会在屏幕上打印一个换行,所以我们向 print() 函数 传入end ='',避免输出重复空行。打印单圈信息后,我们将计数器 lapNum 加1,将 lastTime 设置为当前时间(这就是下一圈的 开始时间),从而为下一圈做好准备。

5.3.3. 第3步:类似程序的想法

时间追踪为程序打开了几种可能性。虽然可以下载应用程序来做 其中一些事情,但自己编程的好处是它们是免费的,而且不会充 斥着广告和无用的功能。可以编写类似的程序来完成以下任务:

  • 创建一个简单的工时表应用程序,当输入一个人的名字时, 用当前的时间记录下他们进入或离开的时间。

  • 为你的程序添加一个功能,显不自一项处理开始以来的时间, 诸如利用 requests模块进行的下载(参见第11章)。

  • 间歇性地检查程序已经运行了多久,并为用户提供了一个机会, 取消耗时太长的任务。