I'm doing a timer in Python, but my code ends up showing two dialog boxes instead of one when the timer stops. What can I do to avoid having the extra window appear?
Code for timer.py below:
#!/usr/bin/python
import time
start = time.time()
interval=1
import sys
import tkMessageBox
def showmessage():
tkMessageBox.showinfo("timer.py", "Timer Complete!")
if __name__ == "__main__":
if len(sys.argv) > 1:
ns = {'__builtins__': None}
seconds=int(eval(str(sys.argv[1]), ns))
if len(sys.argv) > 2:
if sys.argv[2]=="mins" or sys.argv[2]=="min":
seconds=seconds*60
interval = 1 if seconds < interval else interval
second=seconds - (time.time() - start) + 0.5
while second >= 0:
#In Python 3: print('string', end='\r')
if int(second/3600) > 0:
print "\rTime =%3d hrs %02d mins %02d sec" % \
(second/3600, (second % 3600)/60, second % 60),
else:
print "\rTime =%3d mins %02d sec" % \
(second/60, second % 60),
sys.stdout.flush()
time.sleep(interval)
if int(second % 60+0.5) == 0:
print #or sys.stdout.write("\n")
second=seconds - (time.time() - start) + 0.5
showmessage()
else:
print ("Usage: %s [seconds]" % str(sys.argv[0]))
print (" %s [minutes] mins" % str(sys.argv[0]))
that happens because the messagebox wants a parent window if you change showmessage to the following:
def showmessage():
root = tk.Tk()
root.withdraw()
tkMessageBox.showinfo("timer.py", "Timer Complete!")
root.destroy()
and add:
import Tkinter as tk
to your imports then you will only get the messagebox
Related
I am making a macro that uses pyautogui. I want to check the screen every so often for an image, and if the image is not found, the program breaks. The only problem that I am facing is that pyautogui never locates the image and fails it every time the program is started. I have tried to fix this in multiple ways but I am unable to do so, please help.
import pyautogui
import time
import random
import sys
import keyboard
import tkinter as tk
from tkinter import filedialog, Text
import os
#y is click
thent = time.time()
def island_check():
while time.time() - thent > 1:
t = pyautogui.locateOnScreen(r'C:\Users\myname\Desktop\Picture_bar.png', confidence=0.7)
if t == None:
pyautogui.keyUp("y")
pyautogui.keyUp("a")
pyautogui.keyUp("s")
thold = time.time()
while time.time() - thold < 0.3:
pyautogui.keyDown('s')
admin()
def start():
pyautogui.keyDown("y")
time.sleep(0.1)
if keyboard.is_pressed("t"):
sys.exit()
def evenfront():
thold = time.time()
thent = time.time()
while time.time() - thold < random.uniform(17.0, 17.3):
#holds down a for 17 sec
pyautogui.keyDown("a")
#does island check every third second
then = time.time() - thent
if then > 3:
island_check()
thent = thent + then
if keyboard.is_pressed("t"):
sys.exit()
def oddback():
thold = time.time()
thent = time.time()
while time.time() - thold < random.uniform(17.0, 17.3):
pyautogui.keyDown("s")
then = time.time() - thent
if then > 3:
island_check()
thent = thent + then
if keyboard.is_pressed("t"):
print("system exit, T pressed")
sys.exit()
def time_check():
then = time.time() - thent
if then > 2:
admin()
thent = thent + then
def admin():
time.sleep(0.5)
pyautogui.press('t')
time.sleep(0.3)
pyautogui.press('?')
pyautogui.press('enter')
time.sleep(1.5)
pyautogui.press('t')
pyautogui.write('hello?', interval=random.uniform(0.1, 0.5))
time.sleep(0.1)
pyautogui.press('enter')
sys.exit()
def macro():
time.sleep(7)
rep = 1
while True:
time.sleep(round(random.uniform(0.1, 0.11), 2))
if rep == 1:
start()
rep = rep + 1
if rep == 2:
evenfront()
rep = rep + 1
pyautogui.keyUp("a")
time.sleep(round(random.uniform(0.11, 0.17), 2))
elif rep == 3:
oddback()
rep = rep - 1
pyautogui.keyUp("s")
time.sleep(round(random.uniform(0.11, 0.17), 2))
while True:
macro()
I have also just tried to do it this way but it does not work either:
def island_check():
if pyautogui.locateOnScreen(r"C:\Users\myname\Desktop\Skyblock_SugarcaneMacro\Island.png", confidence=0.7) == None:
pyautogui.keyUp("y")
pyautogui.keyUp("a")
pyautogui.keyUp("s")
time.sleep(1)
admin()
Here's the entire program, but I'm trying to figure out how to time it (days:hours:minutes:seconds) if at all possible. It is written in Python.
import random
x = 1
attempt = 0
while x ==1:
rand1 = random.randint(1,1000)
rand2 = random.randint(1,1000)
attempt = attempt + 1
if rand1 ==rand2:
x=2
print(rand1)
print(rand2)
print("Match Found.")
else:
print(rand1)
print(rand2)
print("Trying again.")
print("")
print("It took ", attempt," attempts to find a matching number.")
#for x in range(10):
# rand1 = random.randint(1,101)
# print(rand1)
# ignore the googol that's what I'm using when I figure out how to time it -> 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
The better code:
import random
import time
from datetime import datetime
from datetime import timedelta
print('Current time: %s' % datetime. now())
attempt = 0
start_time = time.time()
while 1:
rand1 = random.randint(1,1000)
rand2 = random.randint(1,1000)
attempt += 1
if rand1 == rand2:
print(rand1)
print(rand2)
print("Match Found.", end = '\n\n')
break
else:
print(rand1)
print(rand2)
print("Trying again.", end = '\n\n')
print("It took %s attempts to find a matching number." % attempt)
print("It took %s to finish" % str(timedelta(seconds=(time.time() - start_time))))
I want to print list data on the specific delays which are on another list. I Want to loop this process for a specific time, but I'm unable to implement it in a thread.
from time import sleep
import datetime
now = datetime.datetime.now()
Start_Time = datetime.datetime.now()
Str_time = Start_Time.strftime("%H:%M:%S")
End_Time = '11:15:00'
class sampleTest:
#staticmethod
def test():
list1 = ["Hello", "Hi", "Ola"]
list2 = [5, 10, 7]
# print(f"{data} delay {delay} & time is {t} ")
# sleep(delay)
i = 0
while i < len(list1):
t = datetime.datetime.now().strftime('%H:%M:%S')
print(f"{list1[i]} delay {list2[i]} & time is {t} ")
sleep(list2[i])
i += 1
else:
print("All Data is printed")
if __name__ == '__main__':
obj = sampleTest
while Str_time < End_Time:
obj.test()
Str_time = datetime.datetime.now().strftime("%H:%M:%S")
else:
print("Time Is done")
Expected output: On first, loop it should print all list data but in the second loop, it should run as per the delay.
1st time: Hello, Hi, Ola
after that
1. Every 5 seconds it should print Hello
2. Every 10 seconds it should print Hi
3. Every 7seconds it should print Ola
Actual Output: List of data is getting printed as per the delay.
Hello delay 5 & time is 11:41:45
Hi delay 10 & time is 11:41:50
Ola delay 3 & time is 11:42:00
All Data is printed
Hello delay 5 & time is 11:42:03
Hi delay 10 & time is 11:42:08
Ola delay 3 & time is 11:42:18
You can try comparing the current time with the start time, for example:
time.sleep(1);
diff = int(time.time() - start_time)
if (diff % wait_time == 0):
print(text_to_print)
Here is the full code implementing this:
from time import sleep
import time
import datetime
now = datetime.datetime.now()
Start_Time = datetime.datetime.now()
Str_time = Start_Time.strftime("%H:%M:%S")
End_Time = '11:15:00'
starttime=time.time()
diff = 0
class sampleTest:
#staticmethod
def test():
list1 = ["Hello", "Hi", "Ola"]
list2 = [5, 10, 7]
for i in range(len(list1)):
if (diff % list2[i] == 0):
t = datetime.datetime.now().strftime('%H:%M:%S')
print(f"{list1[i]} delay {list2[i]} & time is {t} ")
if __name__ == '__main__':
obj = sampleTest
while Str_time < End_Time:
obj.test()
time.sleep(1);
diff = int(time.time() - starttime)
Str_time = datetime.datetime.now().strftime("%H:%M:%S")
else:
print("Time Is done")
In accordance with your desired output, I believe threads are the best option, which means:
from time import sleep
import datetime
import threading
now = datetime.datetime.now()
Start_Time = datetime.datetime.now()
Str_time = Start_Time.strftime("%H:%M:%S")
End_Time = '11:15:00'
class sampleTest:
def __init__(self):
self.run = True
print ("1st time: Hello, Hi, Ola")
print ("Now: " + datetime.datetime.now().strftime('%H:%M:%S'))
def test(self, i):
list1 = ["Hello", "Hi", "Ola"]
list2 = [5, 10, 7]
while self.run:
sleep(list2[i])
t = datetime.datetime.now().strftime('%H:%M:%S')
print(f"{list1[i]} delay {list2[i]} & time is {t}")
def stop(self):
self.run = False
if __name__ == '__main__':
obj = sampleTest()
t1 = threading.Thread(target=obj.test,args=(0,))
t2 = threading.Thread(target=obj.test,args=(1,))
t3 = threading.Thread(target=obj.test,args=(2,))
t1.start()
t2.start()
t3.start()
while Str_time < End_Time:
Str_time = datetime.datetime.now().strftime("%H:%M:%S")
else:
obj.stop()
t1.join()
t2.join()
t3.join()
print("All data is printed")
print("Time Is done")
I'm trying to make the program output the time it took to complete fib(n) but during the time it's calculating, it continuously posts minute amounts of time. How do I get the program to just output the time once. Here if my program:
import time
def fib(n):
if n <= 1:
return 1
else:
start_time = time.time()
answer = fib(n-1) + fib(n-2)
end_time = time.time()
total_time = end_time - start_time
print(total_time)
return answer
Since your function is recursive, each call will print out its own time. If you want to know how much time the function took, I would suggest wrapping the main call to fib in a time statement, rather than putting the timing in the actual function code.
Instead of placing the code which calculates the time inside the fib() function, place it outside the function, like so:
import time
def fib(n):
if n <= 1:
return 1
else:
answer = fib(n-1) + fib(n-2)
return answer
#Place it all here
start_time = time.time()
fib(90) #Or some other number
end_time = time.time()
total_time = end_time - start_time
print(total_time)
You use my timing program that I wrote.
#!python3
import timeit
from os import system
system('cls')
# % % % % % % % % % % % % % % % % %
# times the code 100 times
runs = 100
totalTime = 0.0; average = 0.0
testTimes = []
for i in range(runs):
startTimer = timeit.default_timer()
# % % % % % % % % % % % % % % % %
# >>>>> code to be tested goes here <<<<<
def fib(n):
if n <= 1:
return 1
else:
answer = fib(n - 1) + fib(n - 2)
return answer
r = fib(26)
print('fib result is:', r)
# % % % % % % % % % % % % % % % %
endTimer = timeit.default_timer()
timeInterval = endTimer - startTimer
testTimes.append(timeInterval)
totalTime += timeInterval
print('\n', '{} {:.4f} {}'.format("This run's time is", timeInterval,
'seconds' + '\n'))
# print the results
print('{} {:.4f} {}'.format(' Total time:', totalTime, 'seconds'))
print('{} {:.4f} {}'.format('Shortest time:', min(testTimes), 'seconds'))
print('{} {:.4f} {}'.format(' Longest time:', max(testTimes), 'seconds'))
print('{} {:.4f} {}'.format(' Average time:', (totalTime / runs), 'seconds'))
As others noted, to time a recursive function, place the timings around the call to the function, not in the function. Here some additional code to time computing the first 30 number of the sequence.
import time
import numpy as np
def fib(n):
if n <= 1:
answer = 1
else:
answer = fib(n-1) + fib(n-2)
return answer
for i in np.arange(1,30):
start = time.time()
f = fib(i)
end = time.time()
total = end - start
print(i, fib(i), total)
I have the following code which turns an outlet on/off every 3 seconds.
start_time = time.time()
counter = 0
agent = snmpy4.Agent("192.168.9.50")
while True:
if (counter % 2 == 0):
agent.set("1.3.6.1.4.1.13742.6.4.1.2.1.2.1.1",1)
else:
agent.set("1.3.6.1.4.1.13742.6.4.1.2.1.2.1.1", 0)
time.sleep(3- ((time.time()-start_time) % 3))
counter = counter + 1
Is there a way I can have the loop terminate at any given point if something is entered, (space) for example... while letting the code above run in the mean time
You can put the loop in a thread and use the main thread to wait on the keyboard. If its okay for "something to be entered" can be a line with line feed (e.g., type a command and enter), then this will do
import time
import threading
import sys
def agent_setter(event):
start_time = time.time()
counter = 0
#agent = snmpy4.Agent("192.168.9.50")
while True:
if (counter % 2 == 0):
print('agent.set("1.3.6.1.4.1.13742.6.4.1.2.1.2.1.1",1)')
else:
print('agent.set("1.3.6.1.4.1.13742.6.4.1.2.1.2.1.1", 0)')
if event.wait(3- ((time.time()-start_time) % 3)):
print('got keyboard')
event.clear()
counter = counter + 1
agent_event = threading.Event()
agent_thread = threading.Thread(target=agent_setter, args=(agent_event,))
agent_thread.start()
for line in sys.stdin:
agent_event.set()