How to stop a stopwatch with a keyboard press in python? - python

I made a super rudimentary stopwatch in python, just to get myself more acclimated with it, (It's my first programming language)and I've been trying to get the code to stop running when a key is pressed (using keyboard interrupt) but the code basically ignores keyboard interrupt and keeps going on forever.
(here's my code for reference)
# Time
import time
import sys
timeLoop = True
# Variables to keep track and display
Sec = 0
Min = 0
Hour = 0
# Begin Process
timeloop = True
while timeloop == True:
try:
Sec += 1
print(str(Hour) + " Hrs " + str(Min) + " Mins " + str(Sec) + " Sec ")
time.sleep(1)
if Sec == 60:
Sec = 0
Min += 1
print(str(Min) + " Minute")
if Min == 60:
Sec = 0
Min = 0
Hour += 1
print(str(Hour) + " Hours")
except KeyboardInterrupt:
sys.exit(0)

Use a second thread (https://en.wikipedia.org/wiki/Multithreading_(computer_architecture), How to use threading in Python?):
def quit_on_user_input():
input = raw_input("Press any key to quit.")
# thread will lock up and wait for user to input. That's why this is on a separate thread.
sys.exit(0)
quit_thread = threading.Thread(target=quit_on_user_input, args=[])
quit_trhead.start()
# The rest of your code. quit_thread will run in the background and therefor won't lock up your main thread.

The KeyboardInterrupt exception is thrown when the user quit's the program with ctrl + c. You will need to use another method to detect a key press. This answer seems to have a good cross-platform class to check stdin.
EDIT: The answer I linked above would require the user to press enter, so that could work if you run it in a different thread.
The following method should work on any keypress but only on Windows.
import msvcrt
# Time
import time
import sys
timeLoop = True
# Variables to keep track and display
Sec = 0
Min = 0
Hour = 0
# Begin Process
while True:
try:
Sec += 1
print(str(Hour) + " Hrs " + str(Min) + " Mins " + str(Sec) + " Sec ")
time.sleep(1)
if Sec == 60:
Sec = 0
Min += 1
print(str(Min) + " Minute")
if Min == 60:
Sec = 0
Min = 0
Hour += 1
print(str(Hour) + " Hours")
if msvcrt.kbhit():
break
except KeyboardInterrupt:
break
EDIT2: Found a library for kbhit that has cross-platform support. In the example below I have saved it in the same directory as kbhit.py and have imported it at line #1.
from kbhit import KBHit
# Time
import time
import sys
timeLoop = True
# Variables to keep track and display
Sec = 0
Min = 0
Hour = 0
k = KBHit()
# Begin Process
while True:
try:
Sec += 1
print(str(Hour) + " Hrs " + str(Min) + " Mins " + str(Sec) + " Sec ")
time.sleep(1)
if Sec == 60:
Sec = 0
Min += 1
print(str(Min) + " Minute")
if Min == 60:
Sec = 0
Min = 0
Hour += 1
print(str(Hour) + " Hours")
if k.kbhit():
break
except KeyboardInterrupt:
break

Related

Resetting the count of variable in a while loop

from microbit import *
from ssd1306 import initialize, clear_oled
from ssd1306_stamp import draw_stamp
from ssd1306_img import create_stamp
from ssd1306_text import add_text
import utime as time
window = []
threshold = 550 # limit
count = 0
sample = 0
beat = False
start = False
good = create_stamp(Image.HAPPY)
bad = create_stamp(Image.SAD)
heart = create_stamp(Image.HEART)
values = []
def mean(datalist):
sum = 0
for i in datalist:
sum += i
if len(datalist) > 0:
return sum/len(datalist)
else:
return None
while True:
if button_a.was_pressed():
while True:
signal = pin1.read_analog()
window.append(signal)
avg = round(mean(window))
values.append(avg)
if len(window) == 11:
window.pop(0)
if beat is False and avg >= threshold+10:
beat = True
count += 1
display.show(Image.HEART, wait=False)
if count == 1:
t1 = time.ticks_ms()
if count == 11:
t2 = time.ticks_ms()
T = t2 - t1
bpm = round(600*1000/(T))
display.scroll(str(bpm))
initialize()
clear_oled()
add_text(0, 0, "Heart rate :")
add_text(0, 3, str(bpm) + " bpm")
if 60 <= bpm <= 100:
draw_stamp(38, 24, good, 1)
else :
draw_stamp(38, 24, bad, 1)
count = 0
sleep(2000)
if button_b.was_pressed():
break
count = 0
elif beat is True and avg <= threshold-10:
beat = False
display.clear()
sample += 1
if sample == 250:
threshold = mean(values)
values = []
sample = 0
sleep(20)
sleep(20)
This is the code connect to the microbit, and the function is about the heart rate sensor, which it will appear the average beat per minute when sensing 10 beats of the heart.
I am thinking of adding a function that if button b is pressed, the loop will pause, and press the button a to start again. I tried to add a break function in the loop, it worked when I click the button b, it pause the loop, however, the count of beat won't reset, and the time between the beat is also recorded although I break the loop.
Is there any way that I can break the loop and reset the count?
You should reset the counter before breaking. In your current code the line for the count is not executing since it breaks out before it reaches it.
if button_b.was_pressed():
count = 0
break

Check a condition every 3 minutes without functions and without interrupting the loop

I have this working code that checks a conditions every 3 minutes considering the local time, so every 0, 3, 6, 9.....It prints "checking condition".
import time
def get_next_time():
minute = time.localtime().tm_min
result = 3 - (minute % 3) + minute
if result == 60:
result = 0
return result
next_run = get_next_time()
while True:
now = time.localtime()
if next_run == now.tm_min:
print("checking condition")
#some condition
next_run = get_next_time()
time.sleep(1)
The problem is that I need the code without functions, so I need to find a way to write this code without using any funcion, and I cannot use break or interrput the loop
I tried:
while True:
minute = time.localtime().tm_min
result = 3 - (minute % 3) + minute
if result == 60:
result = 0
now = time.localtime()
if result == now.tm_min:
print("checking conditions")
time.sleep(1)
But it does not work: it does not do nothing.
Any ideas?
you can compact the function in one statement:
import time
next_run = (3 - (time.localtime().tm_min % 3) + time.localtime().tm_min)%60
while True:
now = time.localtime()
if next_run == now.tm_min:
print("checking condition")
#checking conditions...
next_run=(3 - (time.localtime().tm_min % 3) + time.localtime().tm_min)%60
time.sleep(1)
The first time, the get_next_time() will only be executed when next_run == now.tm_min. The second time, you execute it each loop
import time
minute = time.localtime().tm_min
result = 3 - (minute % 3) + minute
if result == 60:
result = 0
while True:
now = time.localtime()
if result == now.tm_min:
print("checking conditions")
minute = time.localtime().tm_min
result = 3 - (minute % 3) + minute
if result == 60:
result = 0
time.sleep(1)
Rounding to the next multiple of 3 minutes contradicts the specification "every 0...".
It is enough to do
import time
first= True
while True:
minute= time.localtime().tm_min
if first or minute == target:
print("checking condition")
first= False
target= (minute + 3) % 60
time.sleep(1)
Update:
I modified the code so that a single call to localtime is made on every iteration, to make fully sure that the minutes do not change between the calls.
More compact but less efficient:
import time
while True:
minute= time.localtime().tm_min
if 'target' not in locals() or minute == target:
print("checking condition")
target= (minute + 3) % 60
time.sleep(1)

trying to get an if statement to be triggered during certain times of day

im fairly new with python but im tring to get a device to turn on for one minute and off for 3 minutes repeatedly from the times of 9am to 5pm and i can't get the if statement to reference the updated time from the loop any help would be greatly appreciated!!!
import datetime
import time
n = "on" #to be replaced with GPIO output
f = "off" #to be replaced with GPIO output
nt = "tis not be the time" #used to see if working or not
tt = "tis be time" #used to see if working or not
now = datetime.datetime.now()
hour = now.hour
def count():
now = datetime.datetime.now()
hour = now.second
total = 1
if hour >= 8 and hour <= 16:
now = datetime.datetime.now()
hour = now.hour
for i in range(1,100):
total = total*2
print (tt)
print (n)
time.sleep(60)
print(f)
time.sleep(180)
now = datetime.datetime.now()
hour = now.second
print (hour)
else :
for i in range(1,100):
now = datetime.datetime.now()
hour = now.hour
print (nt)
print (hour)
time.sleep(10)
count()
You could fix it with a while loop instead, it would look like this, just put all of it inside your function
now = datetime.datetime.now()
hour = now.hour
if hour >= 8 and hour <= 16:
run = True
else:
run = False
while run:
total = total*2
print (tt)
print (n)
time.sleep(60)
print(f)
time.sleep(180)
now = datetime.datetime.now()
hour = now.second
print (hour)
if hour >= 8 and hour <= 16:
run = True
else:
run = False
while run == False:
now = datetime.datetime.now()
hour = now.hour
print (nt)
print (hour)
time.sleep(10)
if hour >= 8 and hour <= 16:
run = True
else:
run = False
Maybe using a while statement. In addition, you have hour = now.second on the second line of the function count and I think it should be hour = now.hour.
See the code with comments:
import datetime
import time
n = "on" #to be replaced with GPIO output
f = "off" #to be replaced with GPIO output
nt = "tis not be the time" #used to see if working or not
tt = "tis be time" #used to see if working or not
#Next lines are redundant, commented out.
#now = datetime.datetime.now()
#hour = now.hour
def count():
now = datetime.datetime.now()
hour = now.hour #now.second
total = 1
while hour >= 8 and hour <= 16:
now = datetime.datetime.now()
hour = now.hour
# for i in range(1,100): -> why you need this?
total = total*2
print (tt)
print (n)
time.sleep(60)
print(f)
time.sleep(180)
now = datetime.datetime.now()
hour = now.hour #now.second
print (hour)
for i in range(1,100): #I don't know why you need a loop here
now = datetime.datetime.now()
hour = now.hour
print (nt)
print (hour)
time.sleep(10)
count()
Edited for correcting another hour = now.second inside the while loop
I don't know how are you planning on running the code, but the main problem I see is that you do not have any loop for your code to run infinitely and check the time condition.
Also it's not clear for me why you need this total variable that gets doubled.
Another thing is your for loops - the condition is not clear. Why do you want to run it in this specific range?
What I would do is I would create an infinite loop and inside it make some decisions based on a clear time conditions - the conditions that are specified by you.
So if I understood your case correctly I'd rather write something like this:
# between 9am to 5pm turn on the device for 60 seconds and off for 180 seconds repeatedly
from datetime import datetime
import time
def update_device_state(state):
# TODO: implement GPIO output code
pass
def run():
device_state = 'off'
new_state = device_state
on_timer = 0
off_timer = time.time() - 180 # initial value must be over 180 seconds to trigger device on a first run
while True:
hour = datetime.now().hour
if 5 <= hour <= 17:
if device_state == 'off' and time.time() - off_timer > 180:
on_timer = time.time()
new_state = 'on'
off_timer = 0
elif device_state == 'on' and time.time() - on_timer > 60:
off_timer = time.time()
new_state = 'off'
on_timer = 0
else:
if device_state = 'on'
new_state = 'off'
on_timer = 0
off_timer = time.time()
if device_state != new_state:
update_device_state(new_state)
device_state = new_state
time.sleep(1)
run()
But the code requires some testing as I just quickly drafted it and I just briefly red it.

Python printing before/after different lines

I have created some code long ago which helps to create a table in BBcode used in forums.
counter = 0
counter2 = 0
while True:
UserInput = input("")
if counter2 == 0:
print ("[tr]")
print ("[td][center]Label\n" + "[img]" + str(UserInput) + "[/img][/center][/td]")
counter += 1
counter2 += 1
if counter % 5 == 0:
print ("[/tr]")
So if i input Image1.jpg ~ Image7.jpg on seperate lines, the output is as shown below
> [tr]
> [td][center]Label[img]Image1.jpg[/img][/center][/td]
> [td][center]Label[img]Image2.jpg[/img][/center][/td]
> [td][center]Label[img]Image3.jpg[/img][/center][/td]
> [td][center]Label[img]Image4.jpg[/img][/center][/td]
> [td][center]Label[img]Image5.jpg[/img][/center][/td]
> [/tr]
> [td][center]Label[img]Image6.jpg[/img][/center][/td]
> [td][center]Label[img]Image7.jpg[/img][/center][/td]
Currently, the code only inserts [/tr] at the end of ever 5 images.How does one make it so that [/tr] is also printed at the end of output no matter how many jpgs are entered?
How can I print [tr] at the start and join it with the line below, and then not print again until a [/tr] has been printed?
Apologies for my crap English & explanation skills.
(Current progress)
counter = 0
while True:
UserInput = input("")
if counter == 0 or counter % 5 == 0:
print("[tr]", end = "")
print ("[td][center]Label\n" + "[img]" + str(UserInput) + "[/img][/center][/td]")
counter += 1
if counter % 5 == 0:
print("[/tr]")
After reading what you wrote 5 times I believe what you want is:
print("[tr]")
while True:
counter = 0
UserInput = input("")
if UserInput == "exit":
exit(0)
print("[tr]", end = "")
while (counter !=5):
print ("[td][center]Label\n" + "[img]" + str(UserInput) + "[/img][/center][/td]")
counter += 1
print ("[/tr]")
print("[/tr]")
So what happens here is you print [tr] in the same line as the first print from the inside while as you wanted. the [/tr] is in a new line but you can put it in the same by adding end = "" to the second print as well.
Separate the functions. Get the list of images, then process it:
def bbcode(images):
for i in range(0,len(images),5):
print('[tr]')
for image in images[i:i+5]:
print(f'[td][center]Label[img]{image}[/img][/center][/td]')
print('[/tr]')
def get_images():
images = []
while True:
image = input('Image? ')
if not image: break
images.append(image)
return images
images = get_images()
bbcode(images)
You can do it as one long script, but it isn't as clear:
count = 0
while True:
image = input('Image? ')
if not image:
break
count = (count + 1) % 5
if count == 1:
print('[tr]')
print(f'[td][center]Label[img]{image}[/img][/center][/td]')
if count == 0:
print('[/tr]')
if count != 0:
print('[/tr]')
Below is the result with some commentary. To update for your specifications, just set the max_item_blocks variable to whatever you want.
### your main body element with {} to pass a number
element = '[td][center]Label[img]Image{}.jpg[/img][/center][/td]'
### The number of "blocks" you want to print.
max_item_blocks = 3
### Define a start value of 1
start = 1
### Our simple loop with join() function
while max_item_blocks > 0:
### End value is start + 5
end = start + 5
print('[tr]\n' + '\n'.join([element.format(i) for i in range(start, end)]) + '\n[\\tr]')
### Start takes ending value
start = end
### Ending value is now start + 5
end = start + 5
### Reduce our block counts by 1
max_item_blocks -= 1
Output for 3 blocks:
[tr]
[td][center]Label[img]Image1.jpg[/img][/center][/td]
[td][center]Label[img]Image2.jpg[/img][/center][/td]
[td][center]Label[img]Image3.jpg[/img][/center][/td]
[td][center]Label[img]Image4.jpg[/img][/center][/td]
[td][center]Label[img]Image5.jpg[/img][/center][/td]
[\tr]
[tr]
[td][center]Label[img]Image6.jpg[/img][/center][/td]
[td][center]Label[img]Image7.jpg[/img][/center][/td]
[td][center]Label[img]Image8.jpg[/img][/center][/td]
[td][center]Label[img]Image9.jpg[/img][/center][/td]
[td][center]Label[img]Image10.jpg[/img][/center][/td]
[\tr]
[tr]
[td][center]Label[img]Image11.jpg[/img][/center][/td]
[td][center]Label[img]Image12.jpg[/img][/center][/td]
[td][center]Label[img]Image13.jpg[/img][/center][/td]
[td][center]Label[img]Image14.jpg[/img][/center][/td]
[td][center]Label[img]Image15.jpg[/img][/center][/td]
[\tr]

Countdown Clock: 01:05

How can I create a countdown clock in Python that looks like 00:00 (min & sec) which is on a line of its own. Every time it decreases by one actual second then the old timer should be replaced on its line with a new timer that is one second lower:
01:00 becomes 00:59 and it actually hits 00:00.
Here is a basic timer I started with but want to transform:
def countdown(t):
import time
print('This window will remain open for 3 more seconds...')
while t >= 0:
print(t, end='...')
time.sleep(1)
t -= 1
print('Goodbye! \n \n \n \n \n')
t=3
I also want to make sure that anything after Goodbye! (which would most likely be outside of the function) will be on its own line.
RESULT: 3...2...1...0...Goodbye!
I know this is similar to other countdown questions but I believe that it has its own twist.
Apart from formatting your time as minutes and seconds, you'll need to print a carriage return. Set end to \r:
import time
def countdown(t):
while t:
mins, secs = divmod(t, 60)
timeformat = '{:02d}:{:02d}'.format(mins, secs)
print(timeformat, end='\r')
time.sleep(1)
t -= 1
print('Goodbye!\n\n\n\n\n')
This ensures that the next print overwrites the last line printed:
Here is the code which counts from 01:05 to 00:00 in MM:SS format.
Python 3 :
import time
def countdown(p,q):
i=p
j=q
k=0
while True:
if(j==-1):
j=59
i -=1
if(j > 9):
print(str(k)+str(i)+":"+str(j), end="\r")
else:
print(str(k)+str(i)+":"+str(k)+str(j), end="\r")
time.sleep(1)
j -= 1
if(i==0 and j==-1):
break
if(i==0 and j==-1):
print("Goodbye!", end="\r")
time.sleep(1)
countdown(1,5) #countdown(min,sec)
Python 2 :
import time
def countdown(p,q):
i=p
j=q
k=0
while True:
if(j==-1):
j=59
i -=1
if(j > 9):
print "\r"+str(k)+str(i)+":"+str(j),
else:
print "\r"+str(k)+str(i)+":"+str(k)+str(j),
time.sleep(1)
j -= 1
if(i==0 and j==-1):
break
if(i==0 and j==-1):
print "\rGoodbye!"
time.sleep(1)
countdown(1,5) #countdown(min,sec)
For the simplicity, this code is able to say you how long it takes until the next desired time, which might be whatever you want to do in your program. In your case, this is a kind of countdown timer.
from datetime import datetime
x=datetime.today()
y=x.replace(day=x.day+1, hour=3, minute=1, second=0, microsecond=0)
delta_t=y-x
secs=delta_t.seconds+1
second = (secs % 60)
minut = (secs / 60) % 60
hour = (secs / 3600)
print ("Seconds: %s " % (second))
print ("Minute: %s " % (minut))
print ("Hour: %s" % (hour))
print ("Time is %s:%s:%s" % (hour, minut, second))
Then, output is as follows:
Seconds: 50
Minute: 32
Hour: 12
Time is 12:32:50
Good luck with your coding.
Maybe this link will help:
Making a Timer in Python 3
And look at my answer, it is same for your too!
Anyway, here is answer:
import time
import os
hour = int(input('Enter any amount of hours you want -+==> '))
minute = int(input('Enter any amount of minutes you want -+==> '))
second = int(input('Enter any amount of seconds you want -+==> '))
time = hour*10800 + minute*3600 + second*60
print('{}:{}:{}'.format(hour,minute,second))
while time > 0:
time = time - 1
seconds = (time // 60) % 60
minutes = (time // 3600)
hours = (time // 10800)
print('Time Left -+==> ',hours,':',minutes,':',seconds,)
os.system("CLS")
if time == 0:
print('Time Is Over!')
Input:
Enter any amount of hours you want -+==> 0
Enter any amount of minutes you want -+==> 0
Enter any amount of seconds you want -+==> 10
Output # All are on the same line
Time Left -+==> 0:0:10
Time Left -+==> 0:0:9
Time Left -+==> 0:0:8
Time Left -+==> 0:0:7
Time Left -+==> 0:0:6
Time Left -+==> 0:0:5
Time Left -+==> 0:0:4
Time Left -+==> 0:0:3
Time Left -+==> 0:0:2
Time Left -+==> 0:0:1
Time Left -+==> 0:0:0
Time Is Over!
import time
import sys
print(' ')
print('Countdown Timer, By Adam Gay')
print(' ')
print('Instructions: Input time to countdown from.')
print(' ')
c=':'
hourz=input('Hours: ')
minz=input('Minutes: ')
secz=input('Seconds: ')
print(' ')
hour=int(hourz)
min=int(minz)
sec=int(secz)
while hour > -1:
while min > -1:
while sec > 0:
sec=sec-1
time.sleep(1)
sec1 = ('%02.f' % sec) # format
min1 = ('%02.f' % min)
hour1 = ('%02.f' % hour)
sys.stdout.write('\r' + str(hour1) + c + str(min1) + c + str(sec1))
min=min-1
sec=60
hour=hour-1
min=59
Print('Countdown Complete.')
time.sleep(30)

Categories

Resources