Секундомер в Python

Я пытаюсь создать простую игру, в которой нужно собрать столько блоков, сколько вы можете за определенное время, скажем, 10 секунд. Как я могу получить секундомер, чтобы начать тикать в начале программы, и когда он достигнет 10 секунд, сделайте что-нибудь (в этом случае выйдите из цикла)?

Ответ 1

import time

now = time.time()
future = now + 10
while time.time() < future:
    # do stuff
    pass

В качестве альтернативы, если у вас уже есть цикл:

while True:
    if time.time() > future:
        break
    # do other stuff

Этот метод хорошо работает с pygame, так как он требует от вас большого основного цикла.

Ответ 2

Использование time.time()/datetime.datetime.now() будет прерываться, если системное время будет изменено (пользователь изменяет время, он корректируется службами синхронизации времени, такими как NTP или переключение с/на дневное время сбережения!).

time.monotonic() или time.perf_counter(), кажется, правильный путь, однако они доступны только из python 3.3. Другая возможность - использование threading.Timer. Независимо от того, является ли это более надежным, чем time.time(), а друзья зависят от внутренней реализации. Также обратите внимание, что создание нового потока не является полностью бесплатным с точки зрения системных ресурсов, поэтому это может быть плохой выбор в случаях, когда много таймеров нужно запускать параллельно.

Ответ 3

Я использую эту функцию в своих программах python. Вход для функции приведен в качестве примера:
  value = time.time()

def stopWatch(value):
    '''From seconds to Days;Hours:Minutes;Seconds'''

    valueD = (((value/365)/24)/60)
    Days = int (valueD)

    valueH = (valueD-Days)*365
    Hours = int(valueH)

    valueM = (valueH - Hours)*24
    Minutes = int(valueM)

    valueS = (valueM - Minutes)*60
    Seconds = int(valueS)


    print Days,";",Hours,":",Minutes,";",Seconds




start = time.time() # What in other posts is described is

***your code HERE***

end = time.time()         
stopWatch(end-start) #Use then my code

Ответ 4

Объект threading.Timer (документация) может подсчитать десять секунд, затем установите его, чтобы установить флаг Event, указывающий, что цикл должен выйти.

Документация указывает, что время может быть неточным - вам нужно будет проверить, достаточно ли он достаточно для вашей игры.

Ответ 5

В этом примере цикл запускается каждую секунду в течение десяти секунд:

import datetime, time
then = datetime.datetime.now() + datetime.timedelta(seconds=10)
while then > datetime.datetime.now():
    print 'sleeping'
    time.sleep(1)

Ответ 6

Для вспомогательного класса StopWatch вот мое решение, которое дает вам точность в выводе, а также доступ к необработанному времени запуска:

class StopWatch:
    def __init__(self):
        self.start()
    def start(self):
        self._startTime = time.time()
    def getStartTime(self):
        return self._startTime
    def elapsed(self, prec=3):
        prec = 3 if prec is None or not isinstance(prec, (int, long)) else prec
        diff= time.time() - self._startTime
        return round(diff, prec)
def round(n, p=0):
    m = 10 ** p
    return math.floor(n * m + 0.5) / m

Ответ 7

Как упражнение для обучения для себя, я создал класс, чтобы иметь возможность создавать несколько экземпляров таймера секундомера, которые могут вам пригодиться (я уверен, что в модулях времени или подобных случаях есть лучшие/более простые версии)

import time as tm
class Watch:
    count = 0
    description = "Stopwatch class object (default description)"
    author = "Author not yet set"
    name = "not defined"
    instances = []
    def __init__(self,name="not defined"):
        self.name = name
        self.elapsed = 0.
        self.mode = 'init'
        self.starttime = 0.
        self.created = tm.strftime("%Y-%m-%d %H:%M:%S", tm.gmtime())
        Watch.count += 1

    def __call__(self):
        if self.mode == 'running':
            return tm.time() - self.starttime
        elif self.mode == 'stopped':
            return self.elapsed
        else:
            return 0.

    def display(self):
        if self.mode == 'running':
            self.elapsed = tm.time() - self.starttime
        elif self.mode == 'init':
            self.elapsed = 0.
        elif self.mode == 'stopped':
            pass
        else:
            pass
        print "Name:       ", self.name
        print "Address:    ", self
        print "Created:    ", self.created
        print "Start-time: ", self.starttime
        print "Mode:       ", self.mode
        print "Elapsed:    ", self.elapsed
        print "Description:", self.description
        print "Author:     ", self.author

    def start(self):
        if self.mode == 'running':
            self.starttime = tm.time()
            self.elapsed = tm.time() - self.starttime
        elif self.mode == 'init':
            self.starttime = tm.time()
            self.mode = 'running'
            self.elapsed = 0.
        elif self.mode == 'stopped':
            self.mode = 'running'
            #self.elapsed = self.elapsed + tm.time() - self.starttime
            self.starttime = tm.time() - self.elapsed
        else:
            pass
        return

    def stop(self):
        if self.mode == 'running':
            self.mode = 'stopped'
            self.elapsed = tm.time() - self.starttime
        elif self.mode == 'init':
            self.mode = 'stopped'
            self.elapsed = 0.
        elif self.mode == 'stopped':
            pass
        else:
            pass
        return self.elapsed

    def lap(self):
        if self.mode == 'running':
            self.elapsed = tm.time() - self.starttime
        elif self.mode == 'init':
            self.elapsed = 0.
        elif self.mode == 'stopped':
            pass
        else:
            pass
        return self.elapsed

    def reset(self):
        self.starttime=0.
        self.elapsed=0.
        self.mode='init'
        return self.elapsed

def WatchList():
    return [i for i,j in zip(globals().keys(),globals().values()) if '__main__.Watch instance' in str(j)]

Ответ 8

Это самый короткий путь, который я знаю об этом:

def stopWatch():
        import time
        a = 0
        hours = 0
        while a < 1:
            for minutes in range(0, 60):
                for seconds in range(0, 60):
                    time.sleep(1)
                    print(hours,":", minutes,":", seconds)
        hours = hours + 1

Ответ 9

Новое в мире питонов!
Мне нужен независимый от системного времени Секундомер, поэтому я перевел свой старый класс С++ на Python:

from ctypes.wintypes import DWORD
import win32api
import datetime

class Stopwatch:

    def __init__(self):
        self.Restart()

    def Restart(self):
        self.__ulStartTicks = DWORD(win32api.GetTickCount()).value

    def ElapsedMilliSecs(self):
        return DWORD(DWORD(win32api.GetTickCount()).value-DWORD(self.__ulStartTicks).value).value

    def ElapsedTime(self):
        return datetime.timedelta(milliseconds=self.ElapsedMilliSecs())

У этого не было проблемы на 49 дней из-за математики DWORD, но NOTICE, что GetTickCount имеет гранулярность около 15 миллисекунд, поэтому не используйте этот класс, если вам нужно 1-100 миллисекунд прошедших временных интервалов.

Любые улучшения или отзывы приветствуются!