web-dev-qa-db-ja.com

Pythonでタイマープログラムを作成する方法

これが私の目標です。挨拶から始まる小さなプログラム(テキストベース)を作成するには、最後のイベントからの経過時間のタイマーを出力し、次にイベントのタイマーを出力します。私はこのコードを使用してタイマーを理解することから始めましたが、最初の問題は、タイマーが新しい行で新しい秒ごとに繰り返され続けることです。どうすれば停止できますか?また、このタイマーは実際の秒数よりも遅れているようです。

import os
import time


s=0
m=0

while s<=60:
    os.system('cls')
    print (m, 'Minutes', s, 'Seconds')
    time.sleep(1)
    s+=1
    if s==60:
        m+=1
        s=0
6

私はこのようなもので行きます:

import time
import sys

time_start = time.time()
seconds = 0
minutes = 0

while True:
    try:
        sys.stdout.write("\r{minutes} Minutes {seconds} Seconds".format(minutes=minutes, seconds=seconds))
        sys.stdout.flush()
        time.sleep(1)
        seconds = int(time.time() - time_start) - minutes * 60
        if seconds >= 60:
            minutes += 1
            seconds = 0
    except KeyboardInterrupt, e:
        break

ここでは、スリープは正確に1秒ではないため、スリープインクリメンターだけでなく、実際の時間モジュールに依存しています。

また、sys.stdout.writeの代わりにprintを使用することもできますが、ほぼ確実にsys.stdout.flushがまだ必要です。

お気に入り:

print ("\r{minutes} Minutes {seconds} Seconds".format(minutes=minutes, seconds=seconds)),

改行が印刷されないように、末尾のコンマに注意してください。

7
sberry

これは私のバージョンです。初心者には最適です。

     # Timer
import time
print("This is the timer")
# Ask to Begin
start = input("Would you like to begin Timing? (y/n): ")
if start == "y":
    timeLoop = True

# Variables to keep track and display
Sec = 0
Min = 0
# Begin Process
timeLoop = start
while timeLoop:
    Sec += 1
    print(str(Min) + " Mins " + str(Sec) + " Sec ")
    time.sleep(1)
    if Sec == 60:
        Sec = 0
        Min += 1
        print(str(Min) + " Minute")
# Program will cancel when user presses X button
2
user5556486

私のPC(Windows 7)でcmdウィンドウで実行すると、このプログラムは期待どおりに機能します。タイマーが毎秒新しい行で繰り返されている場合、os.system ('cls')が機能していないことを示唆しています-おそらくWindows以外のOSで実行しているためでしょうか?

sが60になることはないため、_while s<=60:_ステートメントは正しくないように見えます。60になると常に0にリセットされ、mがインクリメントされます。おそらく、テストは_while m<60:_である必要がありますか?

最後に、私のPCでは、タイマーが実際の秒数に大幅に遅れているようには見えません。必然的に、このコードは時計の秒数を少し遅らせます-つまり、whileループ内のすべてのコード行をtime.sleep(1)以外のすべての行に実行するのにかかる時間に加えて、プロセスをスリープ状態から戻す。私の場合、それほど長くはありませんが、そのコードの実行に(たとえば、何らかの理由で)0.1秒(たとえば)かかった場合、タイマーは実時間と比較して10%遅く実行されます。 @sberryの答えは、この問題に対処する1つの方法を提供します。

0
Simon

Timeitモジュールを使用して、コードの時間を計ります。次に、それに応じてtime.sleep(x)を調整します。たとえば、次のいずれかを使用できます。

import timeit
#Do all your code and time stuff and while loop
#Store that time in a variable named timedLoop
timer = 1- timedLoop

#Inside while loop:
   time.sleep(timer)

これにより、time.sleep以外のコードの時間が計測され、1秒から減算され、その時間の間スリープします。これにより、1秒の正確な表現が得られます。もう1つの方法は作業量が少なくなりますが、それほど正確ではない場合があります。

#set up timeit module in another program and time your code, then do this:
#In new program:
timer = 1 - timerLoop
print timerLoop

プログラムを実行してから、印刷された時間をコピーして、現在のプログラム2に貼り付けます。 time.sleep()でtimerLoopを使用します。

time.sleep(timerLoop)

これで問題が解決します。

0
PyGuy
# Timer
import time
import winsound
print "               TIMER"
#Ask for Duration
Dur1 = input("How many hours?  : ")
Dur2 = input("How many minutes?: ")
Dur3 = input("How many seconds?: ")
TDur = Dur1 * 60 * 60 + Dur2 * 60 + Dur3
# Ask to Begin
start = raw_input("Would you like to begin Timing? (y/n): ")
if start == "y":
    timeLoop = True

# Variables to keep track and display
CSec = 0
Sec = 0
Min = 0
Hour = 0
# Begin Process
timeLoop = start
while timeLoop:
    CSec += 1
    Sec += 1
    print(str(Hour) + " Hours " + str(Min) + " Mins " + str(Sec) + " Sec ")
    time.sleep(1)
    if Sec == 60:
        Sec = 0
        Min += 1
        Hour = 0
        print(str(Min) + " Minute(s)")
    if Min == 60:
        Sec = 0
        Min = 0
        Hour += 1
        print(str(Hour) + " Hour(s)")
    Elif CSec == TDur:
        timeLoop = False
        print("time\'s up")
        input("")
    while 1 == 1:
        frequency = 1900  # Set Frequency To 2500 Hertz
        duration = 1000  # Set Duration To 1000 ms == 1 second
        winsound.Beep(frequency, duration)

タイマーはuser5556486のバージョンに基づいています。期間を設定でき、フォースファイターのバージョンと同様に、期間が終了するとビープ音が鳴ります。

0
TMagnetB

では、タイマーが遅れている理由から始めましょう。

プログラムで発生するのは、time.sleep()呼び出しが1秒間プログラムの操作を「スリープ」し、その1秒が経過すると、プログラムが再び実行を開始することです。ただし、プログラムは、指定した他のすべてのコマンドを実行するためにまだ時間を必要とするため、実際にすべての操作を実行するには_1s + Xs_が必要です。これは非常に基本的な説明ですが、タイマーが同期しないのはそのためです。

常に新しい行に出力する理由については、print()関数には、指定された文字列に追加する事前定義された行末文字があります。

_print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
_

このようにあなたの印刷ステートメントに_end="YourThing"_を置くことでこれを何でも上書きできます

_for x in range(3):
    print("Test", end="")
_

上記の例では、行の最後に空の文字列が追加されるため、ループの出力は次のようになります。

_"TestTestTest"
_

タイマーの問題を解決するには、次のようなものを使用する必要があります

_timePoint = time.time()

while True:

    #Convert time in seconds to a gmtime struct
    currentTime = time.gmtime(time.time() - timePoint))

    #Convert the gmtime struct to a string
    timeStr = time.strftime("%M minutes, %S seconds", currentTime)

    #Print the time string
    print(timeStr, end="")
_
0
TheMerovingian