По сути, вы пытаетесь реализовать свою собственную версию часов, которая с некоторой скоростью отсчитывает время, используя al oop, например:
value = initial_value
while True:
time.sleep(1)
value += rate
В вашем коде есть нечто большее, чем это, конечно; Вы также хотите прочитать пользовательский ввод и контролировать скорость на основе этого. Но по сути, вы пытаетесь создать часы, и они не работают, потому что ваши часы перестают «тикать», пока input
ждет, пока пользователь что-то введет.
Вместо записи часы, вы должны использовать один из стандартной библиотеки. Функция time.monotonic()
работает как часы, в том смысле, что если вы вызываете функцию дважды, разница между этими двумя числами будет количеством секунд, прошедших между двумя вызовами функции.
Простые «часы» выше, которые имеют переменную value
, увеличивающуюся при фиксированном rate
, могут быть заменены вызовом функции, который вычисляет текущее значение на основе количества прошедших секунд вместо непрерывного поддержания его текущее значение в переменной:
import time
initial_time = time.monotonic()
def get_current_value():
current_time = time.monotonic()
seconds = current_time - initial_time
# use int(seconds) for discrete updates once per second
return initial_value + rate * int(seconds)
Для вашего случая, когда скорость может изменяться динамически, это немного сложнее, но основная идея та же; не пишите свои собственные часы, используйте существующие. Поскольку есть две вещи, которые нам нужно сделать - получить текущее значение и изменить скорость - давайте инкапсулируем эти две операции в классе:
import time
class TimeBasedVariable:
def __init__(self, initial_value, rate):
self.initial_value = initial_value
self.rate = rate
self.initial_time = time.monotonic()
def get_value(self, current_time=None):
if current_time is None:
current_time = time.monotonic()
seconds = current_time - self.initial_time
return self.initial_value + self.rate * int(seconds)
def set_rate(self, rate):
# reset the reference point to the current time
t = time.monotonic()
self.initial_value = self.get_value(t)
self.initial_time = t
self.rate = rate
Обратите внимание, что я немного упростил задачу, сделав переменная обновляется каждую секунду, а не каждые 0,5 секунды. Если вы хотите, чтобы он обновлялся каждые полсекунды, просто напишите int(2 * seconds)
вместо int(seconds)
.