timer starting at the beginning of the program instead of starting point - python

hey i've been working on a timer using python time class. the time should start after the user presses F7 but for some reason it starts counting as soon as I run the program.
from pynput import keyboard
from time import perf_counter
from time_sig import signature
print("Welcome to your smart timer")
datafile = open('data', 'a')
ex_name = input("Please type in the exercise type: ")
datafile.write("\nStarted exercise: " + ex_name.upper())
print("Click F7 to start, F8 every time you finished a question and F9 to stop")
count = 0
def execute_F7():
print("starting timer")
t = perf_counter()
def execute_F8():
print("finished question")
tic = perf_counter
transfer = signature(tic)
global count
count += 1
datafile.write("\nfinished question number " + str(count) + " on time: " + str(signature.convert(transfer)) + " in (" + str(signature.q_time(transfer)) + ")")
print(str(signature.convert(transfer)))
def execute_F4():
tic = perf_counter
transfer = signature(tic)
print(str(signature.convert(transfer)))
datafile.write("\nfinished question number " + str(count) + " on time: " + str(signature.convert(transfer)) + " in (" + str(signature.q_time(transfer)) + ")")
datafile.write("\nWorkout done!")
print("Workout done!")
exit()
def on_press(key):
if key == keyboard.Key.f7:
execute_F7()
elif key == keyboard.Key.f8:
execute_F8()
elif key == keyboard.Key.f4:
execute_F4()
with keyboard.Listener(on_press=on_press) as listener:
listener.join()
love any help thanks!

The perf_counter is always running in the background; its absolute value is undefined, but based on what you're seeing I expect it starts at 0. To time a particular event, you need to subtract perf_counter() from an earlier reference value. Something like:
from time import perf_counter
from typing import Optional
class Stopwatch:
"""Measures elapsed time in seconds."""
def __init__(self):
self._start: Optional[float] = None
def start(self) -> None:
"""Starts the stopwatch."""
self._start = perf_counter()
def stop(self) -> float:
"""Stops the stopwatch, returning the elapsed time."""
assert self._start is not None, "Missing call to start()"
elapsed = perf_counter() - self._start
self._start = None
return elapsed

Related

How to create a Python timer to count down?

My code:
def timer():
while True:
try:
when_to_stop = 90
except KeyboardInterrupt:
break
except:
print("error, please star game again")
while when_to_stop > 0:
m, s = divmod(when_to_stop, 60)
h, m = divmod(m, 60)
time_left = str(h).zfill(2) + ":" + str(m).zfill(2) + ":" +
str(s).zfill(2) # got cut off, belongs to the line before this
print("time:", time_left + "\r", end="")
if time_left == 0:
print("TIME IS UP!")
time.sleep(1)
when_to_stop -= 1
This works perfectly fine, except that time.sleep means my whole program sleeps, so anything after that while stop for 90 seconds. Any way to fix that?(or make a new timer without time.sleep?)
I think that, alternatively, you could keep track of when the timer starts, and check the time by seeing if the time that's passed is longer than the timer is supposed to last. I'm not sure how much you know about classes and objects in Python, but here is the solution that came to mind:
import datetime
class Timer:
def __init__(self,**kwargs):
self.start = datetime.datetime.now()
self.length = datetime.timedelta(**kwargs)
self.end = self.start+self.length
def isDone(self):
return (self.end-datetime.datetime.now()).total_seconds()<=0
def timeLeft(self):
return self.end-datetime.datetime.now()
def timeElapsed(self):
return datetime.datetime.now()-self.start
Even if you don't quite understand the class itself, if you put it in your code it should work like a charm:
#This has the same options as:
#class datetime.timedelta(days, seconds, microseconds, milliseconds, minutes, hours, weeks)
t = Timer(days=2)
while(not t.isDone()):
#Do other game stuff here....
time_left = t.timeLeft()
print(f"time: {time_left}")
#And here....
print("Done now")

How can I play random audio files based on current time in Python 2.7?

Background: I'm using as Raspberry Pi rev 2 B to run a nature sound white noise generator of sorts that will randomly play audio tracks of varying length based on the time of night/morning. Some tracks are only a minute, some are several hours long. I'm looking for a way to check the time and change which type of sounds play based on time.
Current issue: I can start the appropriate audio for the time when the program first executes, but the timeloop execution stops polling once omxplayer starts up.
I have tried to call OMXPlayer without interrupting the time checker that determines what kind of audio to play, but once the audio playback starts I have been unable to continue checking time. Even if the play_audio() function wasn't recursive I would still like a way for the time checker to continue executing while the audio plays
#!/usr/bin/env python
import datetime, time, os, subprocess, random
from timeloop import Timeloop
from datetime import timedelta
from time import sleep
from omxplayer.player import OMXPlayer
from pathlib import Path
tl = Timeloop()
running_cycle = "off" # default value for the time cycle currently running
#function to check current time cycle
def check_time () :
dt_now = datetime.datetime.now()
t_now = dt_now.time()
t_night = datetime.time(hour=2,minute=0)
t_twilight = datetime.time(hour=4,minute=45)
t_morning = datetime.time(hour=7,minute=0)
t_end = datetime.time(hour=10,minute=0)
if t_night <= t_now < t_twilight:
return "night"
elif t_twilight <= t_now < t_morning:
return "twilight"
elif t_morning <= t_now < t_end:
return "morning"
else:
return "off"
# function that plays the audio
def play_audio (time_cycle):
subprocess.call ("killall omxplayer", shell=True)
randomfile = random.choice(os.listdir("/home/pi/music/nature-sounds/" + time_cycle))
file = '/home/pi/music/nature-sounds/' + time_cycle + '/' + randomfile
path = Path(file)
player = OMXPlayer(path)
play_audio (time_cycle)
# function that determines whether to maintain current audio cycle or play another
def stay_or_change():
global running_cycle
current_cycle = check_time()
if running_cycle != current_cycle:
if current_cycle == "off" :
player.quit()
else:
running_cycle = current_cycle
print "Now playing: " + running_cycle + " #{}".format(time.ctime())
play_audio(running_cycle)
#starts timeloop checker to play audio - works until stay_or_change() calls play_audio
#tl.job(interval=timedelta(seconds=10))
def job_10s():
print "10s job - running cycle: " + running_cycle + " - current time: {}".format(time.ctime())
stay_or_change()
# starts the timeloop
if __name__ == "__main__":
tl.start(block=True)
I have also tried running OMXPlayer with subprocess.run() but it still seems to hang up after the player starts. I'm completely open to any recommendations for background threading media players, process daemons, or time based execution methods.
I'm new to Python.
I had the recursion all wrong so it got caught in an infinite loop and the timeloop function wasn't really viable for this solution. Instead I had a function that played the sound, and then called the function that checked the time and plays from the appropriate sub-directory (or play nothing and wait).
Here's what I managed to come up with:
#!/usr/bin/env python
import datetime, time, os, subprocess, random
from datetime import timedelta
from time import sleep
from omxplayer.player import OMXPlayer
def check_time () :
dt_now = datetime.datetime.now()
t_now = dt_now.time()
t_night = datetime.time(hour=0,minute=0)
t_twilight = datetime.time(hour=5,minute=45)
t_morning = datetime.time(hour=7,minute=45)
t_end = datetime.time(hour=10,minute=0)
if t_night <= t_now < t_twilight:
return "night"
elif t_twilight <= t_now < t_morning:
return "twilight"
elif t_morning <= t_now < t_end:
return "morning"
else:
return "off"
def play_audio (time_cycle):
randomfile = random.choice(os.listdir("/home/pi/music/nature-sounds/" + time_cycle))
file = '/home/pi/music/nature-sounds/' + time_cycle + '/' + randomfile
print "playing track: " + randomfile
cmd = 'omxplayer --vol -200 ' + file
subprocess.call (cmd, shell=True)
what_to_play()
def what_to_play():
current_cycle = check_time()
if current_cycle == "off" :
print "sounds currently off - #{}".format(time.ctime())
time.sleep(30)
what_to_play()
else:
print "Now playing from " + current_cycle + " #{}".format(time.ctime())
play_audio(current_cycle)
what_to_play()

Stop the program execution after some time interval

I have the following code and I want to stop the program if the condition is not true for a certain period of time. Suppose the condition (sum>99999) is false for a period of 10 seconds, then this program stops and gives present sum values. I am on Windows. Any idea how to do it in Windows.
for j in i:
sum=sum+A[j]
if(sum>99999):
print("Current sum is",sum)
This should accomplish what you're describing.
import time
import sys
start_time = time.time()
for j in i:
sum = sum + A[j]
if sum > 99999:
print("Current sum is ", sum)
start_time = time.time() # reset timer if the condition becomes true
elif time.time() - start_time >= 10:
print("Current sum is ", sum)
sys.exit()
Try this:
import time
import sys
start = time.time()
for j in i:
sum += A[j]
if sum > 99999:
print(sum)
elif time.time() - start > 10:
print(sum)
break # if you just want to exit the loop or sys.exit() if you want to exit the program
Sometimes an iteration is heavy enough to render technique proposed by other answers pretty useless. If you don't have access to break execution upon condition, this or that recipes would be helpful.
I will copy the simpler one (and the one I prefer in my code):
import threading
def timeout(func, args=(), kwargs={}, timeout_duration=1, default=None):
class InterruptableThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.result = None
def run(self):
try:
self.result = func(*args, **kwargs)
except:
self.result = default
it = InterruptableThread()
it.start()
it.join(timeout_duration)
if it.isAlive():
return default
else:
return it.result
import sys
import time
start_time = time.time()
time_limit = 2
if (comdition):
if((time.time() - start_time) > time_limit):
sys.exit()
else:
#more stuff here

Python Multiprocessing - Too Slow

I have built a multiprocessing password cracker (using a wordlist) for a specific function, it halved the time needed compared to using a single process.
The original problem being that it would show you the cracked password and terminate the worker, but the remaining workers would carry on until they ran out of words to hash! not ideal.
My new step forward is to use Manager.Event() to terminate the remaining workers, this works as I had hoped (after some trial and error), but the application now takes far longer that it would take as a single process, I'm sure this must be due to the if function inside pwd_find() but I thought I would seek some advice.
#!/usr/bin/env python
import hashlib, os, time, math
from hashlib import md5
from multiprocessing import Pool, cpu_count, Manager
def screen_clear(): # Small function for clearing the screen on Unix or Windows
if os.name == 'nt':
return os.system('cls')
else:
return os.system('clear')
cores = cpu_count() # Var containing number of cores (Threads)
screen_clear()
print ""
print "Welcome to the Technicolor md5 cracker"
print ""
user = raw_input("Username: ")
print ""
nonce = raw_input("Nonce: ")
print ""
hash = raw_input("Hash: ")
print ""
file = raw_input("Wordlist: ")
screen_clear()
print "Cracking the password for \"" + user + "\" using "
time1 = time.time() # Begins the 'Clock' for timing
realm = "Technicolor Gateway" # These 3 variables dont appear to change
qop = "auth"
uri = "/login.lp"
HA2 = md5("GET" + ":" + uri).hexdigest() # This hash doesn't contain any changing variables so doesn't need to be recalculated
file = open(file, 'r') # Opens the wordlist file
wordlist = file.readlines() # This enables us to use len()
length = len(wordlist)
screen_clear()
print "Cracking the password for \"" + user + "\" using " + str(length) + " words"
break_points = [] # List that will have start and stopping points
for i in range(cores): # Creates start and stopping points based on length of word list
break_points.append({"start":int(math.ceil((length+0.0)/cores * i)), "stop":int(math.ceil((length+0.0)/cores * (i + 1)))})
def pwd_find(start, stop, event):
for number in range(start, stop):
if not event.is_set():
word = (wordlist[number])
pwd = word.replace("\n","") # Removes newline character
HA1 = md5(user + ":" + realm + ":" + pwd).hexdigest()
hidepw = md5(HA1 + ":" + nonce +":" + "00000001" + ":" + "xyz" + ":" + qop + ":" + HA2).hexdigest()
if hidepw == hash:
screen_clear()
time2 = time.time() # stops the 'Clock'
timetotal = math.ceil(time2 - time1) # Calculates the time taken
print "\"" + pwd + "\"" + " = " + hidepw + " (in " + str(timetotal) + " seconds)"
print ""
event.set()
p.terminate
p.join
else:
p.terminate
p.join
if __name__ == '__main__': # Added this because the multiprocessor module sometimes acts funny without it.
p = Pool(cores) # Number of processes to create.
m = Manager()
event = m.Event()
for i in break_points: # Cycles though the breakpoints list created above.
i['event'] = event
a = p.apply_async(pwd_find, kwds=i, args=tuple()) # This will start the separate processes.
p.close() # Prevents any more processes being started
p.join() # Waits for worker process to end
if event.is_set():
end = raw_input("hit enter to exit")
file.close() # Closes the wordlist file
screen_clear()
exit()
else:
screen_clear()
time2 = time.time() # Stops the 'Clock'
totaltime = math.ceil(time2 - time1) # Calculates the time taken
print "Sorry your password was not found (in " + str(totaltime) + " seconds) out of " + str(length) + " words"
print ""
end = raw_input("hit enter to exit")
file.close() # Closes the wordlist file
screen_clear()
exit()
Edit (for #noxdafox):
def finisher(answer):
if answer:
p.terminate()
p.join()
end = raw_input("hit enter to exit")
file.close() # Closes the wordlist file
screen_clear()
exit()
def pwd_find(start, stop):
for number in range(start, stop):
word = (wordlist[number])
pwd = word.replace("\n","") # Removes newline character
HA1 = md5(user + ":" + realm + ":" + pwd).hexdigest()
hidepw = md5(HA1 + ":" + nonce +":" + "00000001" + ":" + "xyz" + ":" + qop + ":" + HA2).hexdigest()
if hidepw == hash:
screen_clear()
time2 = time.time() # stops the 'Clock'
timetotal = math.ceil(time2 - time1) # Calculates the time taken
print "\"" + pwd + "\"" + " = " + hidepw + " (in " + str(timetotal) + " seconds)"
print ""
return True
elif hidepw != hash:
return False
if __name__ == '__main__': # Added this because the multiprocessor module sometimes acts funny without it.
p = Pool(cores) # Number of processes to create.
for i in break_points: # Cycles though the breakpoints list created above.
a = p.apply_async(pwd_find, kwds=i, args=tuple(), callback=finisher) # This will start the separate processes.
p.close() # Prevents any more processes being started
p.join() # Waits for worker process to end
You can use the Pool primitives to solve your problem. You don't need to share an Event object which access is synchronised and slow.
Here I give an example on how to terminate a Pool given the desired result from a worker.
You can simply signal the Pool by returning a specific value and terminate the pool within a callback.
I think your hunch is correct. You are checking a synchronization primitive inside a fast loop. I would maybe only check if the event is set every so often. You can experiment to find the sweet spot where you check it enough to not do too much work but not so often that you slow the program down.

How to run a python loop until a user input? Timer format

I'm coding a timer that counts minutes and seconds, and I want the timer to be able to be paused when you press enter - However, I'm using a while loop to make the timer actually count, and adding a raw_input/input would stop the loop... How would I make the two functions run dynamically - together but separate?
My code so far:
from datetime import datetime
import math
#import subprocess
import sys
import time
import os
sys.stdout.write("\x1b[8;{rows};{cols}t".format(rows=24, cols=60))
t1 = 0
t3 = 0
def space():
print(" ")
print(" ")
print(" ")
print(" ")
print(" ")
print(" ")
print(" ")
print(" ")
print(" ")
print(" ")
while t1 != 1.1:
os.system('clear')
t2 = str(t1)
t4 = str(t3)
space()
print('*')*60
print "James Balazs' Python Timer".center(60,"-")
print ("Passed time: " + t4 + " minutes and " + t2 + " seconds").center(60, " ")
print('*')*60
t1 = t1 + 1
time.sleep(1)
if t1 == 60:
t1 = 0
t3 = t3 + 1
Some unnecessary imports are because I am using a modified copy of a clock I made... So all help is much appreciated as long as I don't have to destroy the majority of my work to make this possible.
Create a function with the timer and use threading to run it while asking for input. Then kill it when the user presses enter.
import threading
def timer():
#Timer goes here
Thread(target = timer).start()
raw_input("Press enter to stop")
#Kill the thread
Also see http://mail.python.org/pipermail/python-list/2004-May/281943.html about killing.

Categories