i would like to generate random numbers for 5 minutes. after that, i would like to know the most common numbers.
my question is:
I am not sure about how much time I need. Can i MANUALLY terminate the script at 1 minute or 1 minute 19 seconds and get the result
my code is as follows:
import random
from collections import Counter
t_end = time.time() + 60*5
numbers = []
while time.time() < t_end:
number=''.join(map(str, [random.randint(0,9)for value in range(0,4)]))
numbers.append(number)
print(Counter(numbers))
There are a myriad number of options:
print an intermediate result every 5s or so and abort the script with ctrl+C
check if space or something else is pressed, if so, abort the loop (see here for how to)
listen to signals and handle accordingly (this could also gracefully terminate the script for option 1)
open a socket and listen to a socket if a stop signal comes in
create a gui with TKinter or what and add a stop button
...
The first one is the easiest but also the most quick&dirty one. For the second option, the following script should get you started (your script was working for me after adding whitespaces and linebreaks):
import keyboard
while True:
if keyboard.read_key() == "p":
print("You pressed p")
break
Assuming python3 and windows: Note that keyboard is not shipped with python on default. You need to install it with pip3 install keyboard. Pip3.exe might not be on your path. cd to where you installed python and look around. For me it was in the Scripts-folder (my installation is pretty messed up though).
import random
from collections import Counter
import time
t_end = time.time() + 60*5
numbers = []
while time.time() < t_end:
number=''.join(map(str, [random.randint(0,9)for value in range(0,4)]))
numbers.append(number)
if time.time()==(t_end-60*4): # break a 1 min
break
print(Counter(numbers))
As luigigi already mentioned in the comment, you could simply use the number of iterations as a limit, and use a for-loop:
number_of_iterations = 10000
for i in range(number_of_iterations):
place_your_function_here()
However, if you for some reason really want to use the time, here is how you can do it: Update the current time at the bottom of your while block, and in the continuing condition of the while loop, compare it to the finish time:
import datetime
delta_in_seconds = 60
finish = datetime.datetime.now() + datetime.timedelta(0, delta_in_seconds)
while time < finish:
place_your_function_here()
time = datetime.datetime.now()
Related
Im trying to make a countdown timer with the feature to reset/stop/pause/resume. I tried implementing an if/elif/else statement to check for user input letter within the while loop while it continues looping. However, the loop stops running when the conditional statement executes. How do I implement my intended functionality into the code?
code:
import time
import datetime
def timeinput():
# Inputs for hours, minutes, seconds on timer
h = input("Enter the time in hours: ")
m = input("Enter the time in minutes: ")
s = input("Enter the time in seconds: ")
countdown(int(h), int(m), int(s))
# Create class that acts as a countdown
def countdown(h, m, s):
# Print options for user to do
print("Press w to reset \nPress s to stop \nPress a to pause \nPress d to resume")
# Calculate the total number of seconds
total_seconds = h * 3600 + m * 60 + s
# While loop that checks if total_seconds reaches zero
# If not zero, decrement total time by one second
while total_seconds > 0:
# Timer represents time left on countdown
timer = datetime.timedelta(seconds = total_seconds)
# Prints the time left on the timer
print(timer, end="\r")
# Delays the program one second
time.sleep(1)
# Reduces total time by one second
total_seconds -= 1
user=input()
if user=="w":
total_seconds=0
print("Timer will now reset")
timeinput()
print("Bzzzt! The countdown is at zero seconds!")
timeinput()
result:
outcome of code
As shown in the provided image, the loop stops at 20 secs. My intended action here was for the countdown to continue until the user presses the W key, which shall then reset the countdown back to its original set time at initialization.
Soo, I'm also kinda new to programming and python so I don't exactly how to make a timer with that functionality. What is happening is that when you use the input() function the code stops and waits for the user input.
I know you can use some libraries, like pygame, in order to check for user input inside the loop without stopping it, but without one I'm not sure how to do it.
You can also use the module keyboard, that comes inside python, and I think is great for the problem you shared. Check this post How to detect key presses?
The command input() is blocking. It waits until it get something from the console. Maybe take a look at this post and try to implement a non blocking version of input. Non-blocking console input?
The problem is that input is blocking - that is, it will stop the execution until the user presses < enter> .
Antique running environments, on 8 bit computers, using Basic, could check "what the user is pressing right now", without waiting for a confirmation with "enter" using the inkey command.
In Python programs running on terminal, terminedia, a 3rdy party library, implements inkey() as it was - but it needs the terminal input to be reconfigured for which it provides a "keyboard" context manager.
You can then run almost the same code you have -just install terminedia in your Python environment with "pip install terminedia"
import terminedia as TM
...
def countdown(h, m, s):
...
while total_seconds > 0:
# Timer represents time left on countdown
timer = datetime.timedelta(seconds = total_seconds)
# Prints the time left on the timer
print(timer, end="\r")
with TM.keyboard:
# Delays the program one second
time.sleep(1)
# Reduces total time by one second
total_seconds -= 1
user=TM.inkey()
if user=="w":
total_seconds=0
print("Timer will now reset")
timeinput()
print("Bzzzt! The countdown is at zero seconds!")
timeinput()
(disclaimer: I am terminedia author)
Taking inputs from the answers received here and subsequent follow-up questions on stack overflow and Reddit, this question has been solved using pygame. I'll provide the link below for future reference to this question.
problem solution
Is it possible to have python 2.7 print something at a specific time of the day. For example if I ran the program at 15:06 and coded it to print "Do task now" at 15:07 it prints it. So no matter what time you ran the program once it hit 15:07 it would print "Do task now." In addition is it possible to have it print every week at this time?
I would suggest installing the library schedule, if you're able to.
Use pip install schedule
Your code would look like this if utilizing schedule:
import schedule
import time
def task():
print("Do task now")
schedule.every().day.at("15:07").do(task)
while True:
schedule.run_pending()
time.sleep(1)
You can adjust time.sleep(1) as necessary to sleep for longer if a 1s interval is too long. Here is the schedule library page.
If you're not using cron, then the general solution is to find the time remaining until you need the event to occur, have the program sleep for that duration, then continue execution.
The tricky part is to have the program find the next occurrence of a given time. There are some modules for this, but you could also do it with plain code for a well-defined case where it is only a fixed time of day.
import time
target_time = '15:07:00'
current_epoch = time.time()
# get string of full time and split it
time_parts = time.ctime().split(' ')
# replace the time component to your target
time_parts[3] = target_time
# convert to epoch
future_time = time.mktime(time.strptime(' '.join(time_parts)))
# if not in the future, add a day to make it tomorrow
diff = future_time - current_epoch
if diff < 0:
diff += 86400
time.sleep(diff)
print 'Done waiting, lets get to work'
While python is not ideal to schedule something; there are better tools out there. Yet, if this is desired to be done in python below is a way to implement it:
Prints at scheduled_time of 11AM:
import datetime as dt
scheduled_time = dt.time(11,00,00,0)
while 1==1:
if (scheduled_time < dt.datetime.now().time() and
scheduled_time > (dt.datetime.now()- dt.timedelta(seconds=59)).time() ):
print "Now is the time to print"
break
There are two if conditions with an intent to print within one minute; a shorter duration can be chosen. But the break immediately after print ensures that print is executed only once.
You would need to extrapolate this so that code is run across days.
Refer: datetime Documentation
This is a followup to another question, to which I now have a solution but the implementation doesn't seem to be behaving properly for unrelated reasons.
I have the following code:
import time
import datetime
import threading
def scheduled_function(cycle):
cycle += 1
print "Cycle " + str(cycle) + " complete."
print "Next cycle at " + (datetime.datetime.now() + datetime.timedelta(minutes=5)).strftime("%l:%M%p")
threading.Timer(300, scheduled_function(cycle)).start() # New cycle every 5 mins
return
scheduled_function(1)
while(True):
command = raw_input()
print command
In general this seems to accomplish what I want - allowing the user to enter commands while in the background while a function is periodically called to do some sort of regular activity. However, the interval (300 in this case, which should equate to 5 minutes) does not seem to be doing anything, and the program reaches maximum recursion depth within a second or so. (Max recursion is not a problem for the actual script, as it likely won't be run for more than a few hours at a time).
How am I using threading.Timer wrongly?
That's because you are calling it right away and not letting the Timer call it for you.
threading.Timer(300, scheduled_function, args=[cycle,]).start()
I am trying to have my code detect when a flashdrive is plugged in and then continue the code. I am currently using "os.path.exists". When I start the code with the flashdrive plugged in, the code functions fine, however, if I start when the flashdrive is unplugged, and attempt to plug it in while the code is running, the code never checks to see if the flashdrive is plugged in and keeps forcing the code to sleep. How can I get the code to work?
import os
import sys
import datetime
from datetime import datetime
import shutil
import time
#Wait for FlashDrive to be connected
if os.path.exists("F:\"):
connected = 1
else:
connected = 0
while connected == 0:
print "..."
time.sleep(10)
#Get current date
currentdate=datetime.now().strftime("%m-%d-%Y")
print "Photos saved: " + currentdate
#Copy and rename DCIM
src = "F:/Pictures"
dst = "C:/Users/Josh/Desktop/photos/" + currentdate
shutil.copytree(src, dst)
The code is supposed to be a loop and execute every time an iPhone connects and never stop running, but I cannot get the code to work if it does not really check for the flashdrive.
Cycle with some arbitrary sleeps isn't a good idea (at all). It makes your program less responsive to the event, because it will take at least N ms to catch an event fired at the start of the iteration*. Also it wastes CPU due to a large amount of API calls.
Create a window.
Listen to WM_DEVICECHANGE message in your message loop. It will fire every time your device configuration changed, but won't tell you, how.
On such event, ask for current configuration.
You can find a tutorial here. Also, take a look at the similar answer on SO.
(*) Actually sleep will test on each next system tick if time_passed >= sleep_timeout. If so, it will return to the program. Problem is that system tick could be 1/18 of second on an old PC (56 ms), so you'll never have 10 ms delay.
Your problem is htat you set the connected variable outside the loop so it's never updated.
Try:
while not os.path.exists('F:\'):
print("...")
time.sleep(10)
--edit---
Then, wait for it to be removed at the end:
while os.path.exists('F:\'):
print("...")
time.sleep(10)
And, finally, wrap the entire thing in a big while True: so that the whole program repeats.
(Again, I do agree this is a 'hackish' and inefficent way to do this task)
# run infinitly
while(True):
done = False;
while(not done):
#Do Stuff
#Main Program
#stopping condition of inner while loop
if datetime.datetime.now().minute == 10:
done = True
if datetime.datetime.now().minute == 10:
time.sleep(60-datetime.datetime.now().second)
I can't figure out why this will not work for me. The entire script is supposed to run on an infinite loop, and then the inner loop is supposed to go through until the stopping condition is met every 10 minutes.
It was my understanding, and maybe I am wrong, that using datetime.datetime.now().minute like I did in an if loop like that would set done = True every 10 minutes, and would end the loop and proceed with the rest of the script...until it realizes that its in another infinite loop and then its supposed to start all over.
Am I getting confused with how this command works, or is there something wrong with my code? Or is there even a better way to do it? The script will run, but it does not end the inner loop with that stopping condtion.
There are various ways to do it, but keeping close to your original design, I'd code the inner loop as:
while(not done):
if datetime.datetime.now().minute % 10 == 0:
done = True
else:
time.sleep(60-datetime.datetime.now().second)
(I'm assuming what you were trying to do with that second if was sleep until the next minute when you weren't ready to exit the loop.)
It stops every tenth minute: 1:10, 2:10, 3:10, etc. In order to do that, use something like:
import time
# in outer loop
inner_loop_start = time.time()
# in inner loop
now = time.time()
if now - inner_loop_start > 60*10:
# done= True and all that jazz
Rather than thrashing around constantly checking if it's 10 past the top of the hour, just do some math and sleep appropriately. Time is generally deterministic.
import datetime
import time
def seconds_till_10past():
now = datetime.datetime.now()
delta = now.replace(minute=10, second=0) - now
return delta.seconds % 3600
while True:
time.sleep(seconds_till_10past())
print "Do something at 10 past the hour."
Also, don't parenthesize arguments to statements (e.g. while(True)), it's bad form.
This does not directly answer the question, but just in case all you want to achieve in the first place is to run some python code every (say) 10 minutes, you'd better implement this using cron.
I assume you so far have a script that is somehow started at boot time. It mainly consists of an infinite loop, a main procedure, and a wait-until-next-execution-time component. For example like the following:
""" my_first_daemon.py
does something everytime the datetime minute part is fully divisible by ten
"""
while True:
# do something at 00,10,20,30,40,50 (minutes) every hour
print "Hello World!"
# wait until the next execution time
wait_until_next_ten_minute_time()
If this is indeed the case I'd suggest to move the main section of your script to a separate script. For example like the following:
""" my_first_cronjob.py
is run by cron everytime the datetime minute part is fully divisible by ten
"""
# do something at 00,10,20,30,40,50 (minutes) every hour
print "Hello World!"
The you go ahead and add to your crontab (use the command crontab -e to add the entry to that user's crontab that shall run the script, also have a look at the manpage). For example like this:
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * command to be executed
# example entry:
# (divide minute-star by 10 to get it run every 10 minutes)
*/10 * * * * python /path/to/my_first_cronjob.py
After the edit you should notice a message like crontab: installing new crontab and then you're done. Just wait and have a look if it works.
Some things to note as well:
The script's output to stdout and stderr are sent to you by mail after termination. Have a look at tail -f /var/mail/moooeeeep (specify your username). You can also configure Thunderbird to fetch these mails, in order to inspect them easier.
The corresponding Wikipedia page is a very good source of information for further details.
If you need to keep state information between independent runs of the script, consider using a configuration file to store this state information, e.g., using pickle, shelve, sqlite, whatever.
Expanding from my comment above:
tic = datetime.datetime.now()
while True:
# do stuff
toc = datetime.datetime.now() - tic
if toc.minute > 10:
tic = datetime.datetime.now();
time.sleep(60-datetime.datetime.now().second)
I have removed the "done" variable, since it conveys a meaning of finished. By reading your code, though, it seems you are actually pausing an ever ongoing process, actually.
Hope this helps!