Inputting the time and comparing it with user input - python

I'm trying to make a function run within a Python script at a certain time given by the user. To do this I'm using the datetime module.
This is part of the code so far:
import os
import subprocess
import shutil
import datetime
import time
def process():
path = os.getcwd()
outdir = os.getcwd() + '\Output'
if not os.path.exists(outdir):
os.mkdir(outdir, 0777)
for (root, dirs, files) in os.walk(path):
filesArr = []
dirname = os.path.basename(root)
parent_dir = os.path.basename(path)
if parent_dir == dirname:
outfile = os.path.join(outdir, ' ' + dirname + '.pdf')
else:
outfile = os.path.join(outdir, parent_dir + ' ' + dirname + '.pdf')
print " "
print 'Processing: ' + path
for filename in files:
if root == outdir:
continue
if filename.endswith('.pdf'):
full_name = os.path.join(root, filename)
if full_name != outfile:
filesArr.append('"' + full_name + '"')
if filesArr:
cmd = 'pdftk ' + ' '.join(filesArr) + ' cat output "' + outfile + '"'
print " "
print 'Merging: ' + str(filesArr)
print " "
sp = subprocess.Popen(cmd)
print "Finished merging documents successfully."
sp.wait()
return
now = datetime.datetime.now()
hour = str(now.hour)
minute = str(now.minute)
seconds = str(now.second)
time_1 = hour + ":" + minute + ":" + seconds
print "Current time is: " + time_1
while True:
time_input = raw_input("Please enter the time in HH:MM:SS format: ")
try:
selected_time = time.strptime(time_input, "%H:%M:%S")
print "Time selected: " + str(selected_time)
while True:
if (selected_time == time.localtime()):
print "Beginning merging process..."
process()
break
time.sleep(5)
break
except ValueError:
print "The time you entered is incorrect. Try again."
The problem is having is trying to find a way on how to compare the user inputted time with the current time (as in, the current time for when the script is running). Also, how do I keep a python script running and process a function at the given time?

I can see various things to be commented in the code you propose, but main one is on selected_time = selected_hour + ..., because I think you are adding integers with different units. You should maybe start with selected_time = selected_hour * 3600 + ....
Second one is when you try to check the validity of the inputs: you make a while on a check that cannot evolve, as user is not requested to enter another value. Which means these loops will never end.
Then, something about robustness: maybe you should compare the selected time to the current time by something more flexible, i.e. replacing == by >= or with some delta.
Last thing, you can make the Python script wait with the following command:
import time
time.sleep(some_duration)
where some_duration is a float, meant in seconds.
Could you please check if this works now?

First of all I'd suggest you look at: http://docs.python.org/library/time.html#time.strptime
which might prove to be helpful in your situation when trying to validate the time.
You can something like this:
import time
import time
while True: #Infinite loop
time_input = raw_input("Please enter the time in HH:MM:SS format: ")
try:
current_date = time.strftime("%Y %m %d")
my_time = time.strptime("%s %s" % (current_date, time_input),
"%Y %m %d %H:%M:%S")
break #this will stop the loop
except ValueError:
print "The time you entered is incorrect. Try again."
Now you can do stuff with my_time like comparing it: my_time == time.localtime()
The simplest way to make the program running until 'it's time is up' is as follows:
import time
while True:
if (my_time <= time.localtime()):
print "Running process"
process()
break
time.sleep(1) #Sleep for 1 second
The above example is by no means the best solution, but in my opinion the easiest to implement.
Also I'd suggest you use http://docs.python.org/library/subprocess.html#subprocess.check_call to execute commands whenever possible.

Related

How can I make the date and time the name of a screenshot taken by python?

My program basically takes a screenshot when the key 'f2' is pressed and saves it in a directory, I am trying to get the screenshot to have the name of when the screenshot was taken, day and time so it won't overlap with any other pictures and make it unique.
This is the program:
import keyboard,pyautogui
from datetime import datetime
while True:
try:
if keyboard.is_pressed('f2'):
myScreenshot = pyautogui.screenshot()
now = datetime.now()
directory = r'E:\Recovery\boot\files\scr'
print(str(directory) + "\\" + str(now))
myScreenshot.save(str(directory) + "\\" + str(now))
break
except:
break
You can use the datetime strftime to provide a date\time format.
For file names, you should avoid colons and slashes in the date.
In your code, try this:
now = datetime.now().strftime("%Y-%m-%d_%H%M%S") # 2020-08-23_211709
......
myScreenshot.save(str(directory) + "\\" + now + ".png") # assuming png
As #arundeep mentioned in his comment, you can also save the capture directly:
pyautogui.screenshot(str(directory) + "\\" + now + ".png")

Why Python program execution slows down when using functions?

So I have a rather general question I was hoping to get some help with. I put together a Python program that runs through and automates workflows at the state level for all the different counties. The entire program was created for research at school - not actual state work. Anyways, I have two designs shown below. The first is an updated version. It takes about 40 minutes to run. The second design shows the original work. Note that it is not a well structured design. However, it takes about five minutes to run the entire program. Could anybody give any insight why there are such differences between the two? The updated version is still ideal as it is much more reusable (can run and grab any dataset in the url) and easy to understand. Furthermore, 40 minutes to get about a hundred workflows completed is still a plus. Also, this is still a work in progress. A couple minor issues still need to be addressed in the code but it is still a pretty cool program.
Updated Design
import os, sys, urllib2, urllib, zipfile, arcpy
from arcpy import env
path = os.getcwd()
def pickData():
myCount = 1
path1 = 'path2URL'
response = urllib2.urlopen(path1)
print "Enter the name of the files you need"
numZips = raw_input()
numZips2 = numZips.split(",")
myResponse(myCount, path1, response, numZips2)
def myResponse(myCount, path1, response, numZips2):
myPath = os.getcwd()
for each in response:
eachNew = each.split(" ")
eachCounty = eachNew[9].strip("\n").strip("\r")
try:
myCountyDir = os.mkdir(os.path.expanduser(myPath+ "\\counties" + "\\" + eachCounty))
except:
pass
myRetrieveDir = myPath+"\\counties" + "\\" + eachCounty
os.chdir(myRetrieveDir)
myCount+=1
response1 = urllib2.urlopen(path1 + eachNew[9])
for all1 in response1:
allNew = all1.split(",")
allFinal = allNew[0].split(" ")
allFinal1 = allFinal[len(allFinal)-1].strip(" ").strip("\n").strip("\r")
numZipsIter = 0
path8 = path1 + eachNew[9][0:len(eachNew[9])-2] +"/"+ allFinal1
downZip = eachNew[9][0:len(eachNew[9])-2]+".zip"
while(numZipsIter <len(numZips2)):
if (numZips2[numZipsIter][0:3].strip(" ") == "NWI") and ("remap" not in allFinal1):
numZips2New = numZips2[numZipsIter].split("_")
if (numZips2New[0].strip(" ") in allFinal1 and numZips2New[1] != "remap" and numZips2New[2].strip(" ") in allFinal1) and (allFinal1[-3:]=="ZIP" or allFinal1[-3:]=="zip"):
urllib.urlretrieve (path8, allFinal1)
zip1 = zipfile.ZipFile(myRetrieveDir +"\\" + allFinal1)
zip1.extractall(myRetrieveDir)
#maybe just have numzips2 (raw input) as the values before the county number
#numZips2[numZipsIter][0:-7].strip(" ") in allFinal1 or numZips2[numZipsIter][0:-7].strip(" ").lower() in allFinal1) and (allFinal1[-3:]=="ZIP" or allFinal1[-3:]=="zip"
elif (numZips2[numZipsIter].strip(" ") in allFinal1 or numZips2[numZipsIter].strip(" ").lower() in allFinal1) and (allFinal1[-3:]=="ZIP" or allFinal1[-3:]=="zip"):
urllib.urlretrieve (path8, allFinal1)
zip1 = zipfile.ZipFile(myRetrieveDir +"\\" + allFinal1)
zip1.extractall(myRetrieveDir)
numZipsIter+=1
pickData()
#client picks shapefiles to add to map
#section for geoprocessing operations
# get the data frames
#add new data frame, title
#check spaces in ftp crawler
os.chdir(path)
env.workspace = path+ "\\symbology\\"
zp1 = os.listdir(path + "\\counties\\")
def myGeoprocessing(layer1, layer2):
#the code in this function is used for geoprocessing operations
#it returns whatever output is generated from the tools used in the map
try:
arcpy.Clip_analysis(path + "\\symbology\\Stream_order.shp", layer1, path + "\\counties\\" + layer2 + "\\Streams.shp")
except:
pass
streams = arcpy.mapping.Layer(path + "\\counties\\" + layer2 + "\\Streams.shp")
arcpy.ApplySymbologyFromLayer_management(streams, path+ '\\symbology\\streams.lyr')
return streams
def makeMap():
#original wetlands layers need to be entered as NWI_line or NWI_poly
print "Enter the layer or layers you wish to include in the map"
myInput = raw_input();
counter1 = 1
for each in zp1:
print each
print path
zp2 = os.listdir(path + "\\counties\\" + each)
for eachNew in zp2:
#print eachNew
if (eachNew[-4:] == ".shp") and ((myInput in eachNew[0:-7] or myInput.lower() in eachNew[0:-7])or((eachNew[8:12] == "poly" or eachNew[8:12]=='line') and eachNew[8:12] in myInput)):
print eachNew[0:-7]
theMap = arcpy.mapping.MapDocument(path +'\\map.mxd')
df1 = arcpy.mapping.ListDataFrames(theMap,"*")[0]
#this is where we add our layers
layer1 = arcpy.mapping.Layer(path + "\\counties\\" + each + "\\" + eachNew)
if(eachNew[7:11] == "poly" or eachNew[7:11] =="line"):
arcpy.ApplySymbologyFromLayer_management(layer1, path + '\\symbology\\' +myInput+'.lyr')
else:
arcpy.ApplySymbologyFromLayer_management(layer1, path + '\\symbology\\' +eachNew[0:-7]+'.lyr')
# Assign legend variable for map
legend = arcpy.mapping.ListLayoutElements(theMap, "LEGEND_ELEMENT", "Legend")[0]
# add wetland layer to map
legend.autoAdd = True
try:
arcpy.mapping.AddLayer(df1, layer1,"AUTO_ARRANGE")
#geoprocessing steps
streams = myGeoprocessing(layer1, each)
# more geoprocessing options, add the layers to map and assign if they should appear in legend
legend.autoAdd = True
arcpy.mapping.AddLayer(df1, streams,"TOP")
df1.extent = layer1.getExtent(True)
arcpy.mapping.ExportToJPEG(theMap, path + "\\counties\\" + each + "\\map.jpg")
# Save map document to path
theMap.saveACopy(path + "\\counties\\" + each + "\\map.mxd")
del theMap
print "done with map " + str(counter1)
except:
print "issue with map or already exists"
counter1+=1
makeMap()
Original Design
import os, sys, urllib2, urllib, zipfile, arcpy
from arcpy import env
response = urllib2.urlopen('path2URL')
path1 = 'path2URL'
myCount = 1
for each in response:
eachNew = each.split(" ")
myCount+=1
response1 = urllib2.urlopen(path1 + eachNew[9])
for all1 in response1:
#print all1
allNew = all1.split(",")
allFinal = allNew[0].split(" ")
allFinal1 = allFinal[len(allFinal)-1].strip(" ")
if allFinal1[-10:-2] == "poly.ZIP":
response2 = urllib2.urlopen('path2URL')
zipcontent= response2.readlines()
path8 = 'path2URL'+ eachNew[9][0:len(eachNew[9])-2] +"/"+ allFinal1[0:len(allFinal1)-2]
downZip = str(eachNew[9][0:len(eachNew[9])-2])+ ".zip"
urllib.urlretrieve (path8, downZip)
# Set the path to the directory where your zipped folders reside
zipfilepath = 'F:\Misc\presentation'
# Set the path to where you want the extracted data to reside
extractiondir = 'F:\Misc\presentation\counties'
# List all data in the main directory
zp1 = os.listdir(zipfilepath)
# Creates a loop which gives use each zipped folder automatically
# Concatinates zipped folder to original directory in variable done
for each in zp1:
print each[-4:]
if each[-4:] == ".zip":
done = zipfilepath + "\\" + each
zip1 = zipfile.ZipFile(done)
extractiondir1 = extractiondir + "\\" + each[:-4]
zip1.extractall(extractiondir1)
path = os.getcwd()
counter1 = 1
# get the data frames
# Create new layer for all files to be added to map document
env.workspace = "E:\\Misc\\presentation\\symbology\\"
zp1 = os.listdir(path + "\\counties\\")
for each in zp1:
zp2 = os.listdir(path + "\\counties\\" + each)
for eachNew in zp2:
if eachNew[-4:] == ".shp":
wetlandMap = arcpy.mapping.MapDocument('E:\\Misc\\presentation\\wetland.mxd')
df1 = arcpy.mapping.ListDataFrames(wetlandMap,"*")[0]
#print eachNew[-4:]
wetland = arcpy.mapping.Layer(path + "\\counties\\" + each + "\\" + eachNew)
#arcpy.Clip_analysis(path + "\\symbology\\Stream_order.shp", wetland, path + "\\counties\\" + each + "\\Streams.shp")
streams = arcpy.mapping.Layer(path + "\\symbology\\Stream_order.shp")
arcpy.ApplySymbologyFromLayer_management(wetland, path + '\\symbology\\wetland.lyr')
arcpy.ApplySymbologyFromLayer_management(streams, path+ '\\symbology\\streams.lyr')
# Assign legend variable for map
legend = arcpy.mapping.ListLayoutElements(wetlandMap, "LEGEND_ELEMENT", "Legend")[0]
# add the layers to map and assign if they should appear in legend
legend.autoAdd = True
arcpy.mapping.AddLayer(df1, streams,"TOP")
legend.autoAdd = True
arcpy.mapping.AddLayer(df1, wetland,"AUTO_ARRANGE")
df1.extent = wetland.getExtent(True)
# Export the map to a pdf
arcpy.mapping.ExportToJPEG(wetlandMap, path + "\\counties\\" + each + "\\wetland.jpg")
# Save map document to path
wetlandMap.saveACopy(path + "\\counties\\" + each + "\\wetland.mxd")
del wetlandMap
print "done with map " + str(counter1)
counter1+=1
Have a look at this guide:
https://wiki.python.org/moin/PythonSpeed/PerformanceTips
Let me quote:
Function call overhead in Python is relatively high, especially compared with the execution speed of a builtin function. This strongly suggests that where appropriate, functions should handle data aggregates.
So effectively this suggests, to not factor out something as a function that is going to be called hundreds of thousands of times.
In Python functions won't be inlined, and calling them is not cheap. If in doubt use a profiler to find out how many times is each function called, and how long does it take on average. Then optimize.
You might also give PyPy a shot, as they have certain optimizations built in. Reducing the function call overhead in some cases seems to be one of them:
Python equivalence to inline functions or macros
http://pypy.org/performance.html

Python: Running multi variables using the same function at the same time. New to Python

I've been working with python for the past few days, and started working on a project. Currently trying to figure out how to execute the same function using multiple variables (In this case, Stock symbols). Preferably with one input() separated with a comma or something. I've hit a snag with this last part though. Can anyone point me in the direction of where to go next? (Running the same function with multiple variables at the same time.)
Here is my code:
#Google + Yahoo Finance Stock Lookup
from googlefinance import getQuotes
from yahoo_finance import Share
import googlefinance
import datetime, time
import os
from datetime import datetime
tDate = datetime.now().strftime('%Y-%m-%d')
print (tDate)
tDateConv = str(tDate)
try:
os.chdir('/Users/Jakes_Macbook/Desktop/Python/Stocks')
except Exception:
print('Default Path does not exsist, make sure your directory is right.')
pass
run = True
while run == True:
print('You are currently storing the file in ')
print(os.getcwd())
print('type "yes" to continue')
confirm = input()
if confirm == 'yes':
print ('ok\n')
try:
os.makedirs(tDateConv)
except Exception:
pass
os.chdir(tDateConv)
print('File will be saved to:')
print(os.getcwd())
break
else:
print('Where do you want to store the file?')
changeDir = input()
os.chdir(changeDir)
print('What Stock or Stocks would you like to look up?')
stockSymbol = input()
def runStocks():
print (" ")
print ("Stock Symbol: " + stockSymbol)
stockSymbolYhoo = Share(stockSymbol)
stockFile = open(str(stockSymbol)+'.txt', 'a')
dicStored = googlefinance.getQuotes(stockSymbol)[0]
numStoredPrice = float(dicStored['LastTradePrice'])
print('Stock Open: ' + stockSymbolYhoo.get_open())
print ("Stored Price: " + str(numStoredPrice))
stockFile.write(str("\n" + "Stock Symbol: " + stockSymbol + "\n"))
stockFile.write(str("\n" + "Open Price: " + stockSymbolYhoo.get_open() + "\n"))
stockFile.write(str("Stored Price: " + str(numStoredPrice)+'\n'))
runs = 0
while runs < 5:
stor = googlefinance.getQuotes(stockSymbol)[0]
price = stor['LastTradePrice']
print(str(datetime.now().strftime('%Y-%m-%d %H:%M:%S')) + " | " + price)
stockFile.write(str(datetime.now().strftime('%Y-%m-%d %H:%M:%S')) + " | Price " + price + ' \n')
numPrice = float(price)
if numPrice < numStoredPrice*float(.995):
print ("buy")
time.sleep(5)
runs = runs + 1
stockFile.close()
runStocks()
My goal is to have each stock symbol, that is inputted, create its own file in the folder for today. I'm pretty sure i can figure out how to do that once i get multiple functions going. Thanks in advance.
Also, let me know if you have any important suggestions or best practices. This is like my second day working with python. Thanks Again.
Just pass them into the function:
# Note the definition was updated to be able to pass in a stockSymbol
def runStocks(stockSymbol):
print (" ")
print ("Stock Symbol: " + stockSymbol)
stockSymbolYhoo = Share(stockSymbol)
stockFile = open(str(stockSymbol)+'.txt', 'a')
dicStored = googlefinance.getQuotes(stockSymbol)[0]
numStoredPrice = float(dicStored['LastTradePrice'])
print('Stock Open: ' + stockSymbolYhoo.get_open())
print ("Stored Price: " + str(numStoredPrice))
stockFile.write(str("\n" + "Stock Symbol: " + stockSymbol + "\n"))
stockFile.write(str("\n" + "Open Price: " + stockSymbolYhoo.get_open() + "\n"))
stockFile.write(str("Stored Price: " + str(numStoredPrice)+'\n'))
stockSymbols = input("Enter stock symbols separated by commas").split(",")
for stockSymbol in stockSymbols:
runStocks(stockSymbol) # Call your function in a loop

i have this code. It is supposed to classify the segment files with the ratings in sys.argv[5].But it keeps having error

I have the following code tha uses FFmpeg . It has 5 argv and it takes in filename,video,segment size, start time, end time, ratings. thats supposed to let me classify segments many times with my ratings "PG G M18..." but there's this error,
"File "C:\c.py",line 92, in <module> os.rename<filename + str(x), filename + str(x) + classification)
WindowsError: [Error2] The system cannot find the file specified.
Ive tried to edit many times but this error still persists. Anyone have any idea what could this error mean and anyway to solve it?
import sys
import subprocess
import os
#change hh:mm:ss to seconds:
def getSeconds(sec):
l = sec.split(':')
return int(l[0])* 3600 + int(l[1])* 60 + float(l[2])
def get_total_time(filename):
proc = subprocess.Popen(["ffmpeg", "-i", filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
lines = proc.communicate()[1]
target = [line for line in lines.split('\n') if 'Duration:' in line][0]
time = target.split('Duration: ')[-1].split(',', 1)[0]
return time
#check command line arguments
if len(sys.argv) < 5:
print "Error: not enough arguments"
sys.exit()
#save filename to file_name
file_name = sys.argv[1]
if not file_name.endswith('mpg'):
print 'Error! File extension not supported'
sys.exit()
# save a size of chunk in chunk
segsize = int(sys.argv[2])
chunk = (segsize * 1024)
# get time of starting censorship in seconds
start_censorship = getSeconds(sys.argv[3])
# get time of ending censorship in seconds
end_censorship = getSeconds(sys.argv[4])
classification = sys.argv[5]
if classification not in ['P','PG','G','NC16','M18','R21']:
print "Error: invalid classification"
sys.exit()
#initialize variable for extension
file_ext = ''
# if extension exists then save it into file_ext
if '.' in file_name:
# split file_name on two parts from right
file_ext = sys.argv[1].split('.')[-1]
# file_name without extension
filename = '.'.join(file_name.split('.')[:-1])
# total_time of file in seconds
total_time = getSeconds(get_total_time(file_name))
print total_time
#open file
in_file = open(file_name,'rb')
#read first chunks
s = in_file.read(chunk)
in_file.seek(0, 2)
file_size = in_file.tell()
chunks = (file_size / chunk) + 1
chunk_time = total_time/ file_size * chunk
#close input file
in_file.close()
#loop for each chunk
for x in range(0, chunks):
# starting time of current chunk
t1 = chunk_time*x
# ending time of current chunk
t2 = chunk_time*(x+1)
if t2 < start_censorship or t1 > end_censorship:
pass
else:
if os.path.exists(filename + str(x) + 'x'):
os.rename(filename + str(x) + 'x', filename + str(x))
os.rename(filename + str(x), filename + str(x) + classification)
#read next bytes
You're not checking whether filename + str(x) exists before you try to rename it. Either check first, or put it in a try block and catch OSError (which WindowsError subclasses). Either that or you're missing an indent on the second rename.
In that last for loop it looks like you are possibly renaming multiple files -- where do the original files come from?
Or, asked another way, for every chunk that is not censored you are renaming a file -- is that really what you want?

Appending to Created File in Python

I have a file, which I am writing data to, however I would like the naming convention to have the time, the file was created at and then stream to the same file for one hour before creating a new text file.
My problem is that I am using a while loop to create the text file while reading from a GPIO and so when the code runs, it creates a new text file every time it moves through the loop. How can I create the file, then write to the existing file for a predetermined amount of time?
import spidev
import time
import datetime
import os
spi = spidev.SpiDev()
spi.open(0,0) #open port 0 of the SPI
count = 0
def timeStamp(fname, fmt ='%Y-%m-%d-%H-%M-%S_{fname}'):
#this function adds the time and date
return datetime.datetime.now().strftime(fmt).format(fname = fname)
def alarm_check(int):
#this function checks the value read in by the SPI
#creating an alarm if the value is 0
if int == 0:
return ("System Alarm!")
else:
return ("System OK")
def write_to_file(int):
# this function will write the current value to a file,
# the time it was read in
# and if the system was im alarm
with open (('SPI_Input_Values'), 'a') as output:
output.write("Input = " + str(int) + '\t' + timeStamp('ADC') + '\t\t' + str(alarm_check(int)) + '\n')
def readadc(adcnum):
#this function will open the SPI and read it to see the current value
# this will then be written to a text value
# using the write_to_file function
if adcnum > 7 or adcnum < 0:
return -1
r = spi.xfer2([1,8 + adcnum << 4,0])
adcout = ((r[1] & 3) << 8) + r[2]
return adcout
while True:
Inp1 = int(round(readadc(0)/10.24)) # defines Inp1 as an integer to be read in
write_to_file(Inp1)
count = count +1
time.sleep(0.1) # puts the systemm to sleep for 0.1 seconds
You need to dynamically create your filename. At the moment it was a hardcoded string. Here's an example:
fname = 'SPI_Input_Values'
fmt ='%Y-%m-%d-%H'
date_str = datetime.datetime.now().strftime(fmt)
file_name = date_str + "_" + fname
with open ((file_name, 'a') as output:
output.write("Input = " + str(int) + '\t' + timeStamp('ADC') + '\t\t' + str(alarm_check(int)) + '\n')
This will constantly append to the file that represents the current hour. When the next hour begins, it will automatically create a new file and begin appending data to it instead.
Something like:
def write_to_file(output, int):
output.write("Input = " + str(int) + '\t' + timeStamp('ADC') + '\t\t' + str(alarm_check(int)) + '\n')
with open (('SPI_Input_Values'), 'a') as output:
while True:
Inp1 = int(round(readadc(0)/10.24)) # defines Inp1 as an integer to be read in
write_to_file(output, Inp1)
count = count +1
time.sleep(0.1)

Categories