Related
How can i get my log parser to accept no arguments if the user hasn't passed one and use the generated log that's stored in the log variable.
#####################
#LogFile
#####################
log =(sys.argv[2])
logging.basicConfig(filename=log ,level=logging.DEBUG)
if log == "-p" or log == "--path":
TIME_STAMPS = re.split('\s+', time.strftime('%Y%m%d %H%M%S %H:%M:%S', time.localtime()))
FILE_TIME_STAMP = TIME_STAMPS[0] + "_" + TIME_STAMPS[1]
log = "version" + "_" + FILE_TIME_STAMP + "_ValidLinkCheck.log"
logging.basicConfig(filename=log ,level=logging.DEBUG)
########################
#Command Line Options
########################
#initiate the parser
parser = argparse.ArgumentParser()
parser.add_argument('-l','--log', dest='log', default = 'log1' , help = "Log File", action="store_true", required= False)
parser.add_argument("-p", "--path", action="store", help="path to file", dest="filename")
parser.add_argument("-x", "--execute", help="delete invalid link", action="store_true")
#read arguments from the command line
args = parser.parse_args()
#check for --path or -p
if args.filename:
print("Script is up to date and running.......................")
logging.info("Script is up to date and running.......................")
path = (format(args.filename))
logging.info("Searching for input link" + path)
status, result = commands.getstatusoutput('cd ' + path)
I want to read any one of the items from a list of videos. The video reading and display code is the following. This code is working perfectly fine.
import cv2
def VideoReading(vid):
cap = cv2.VideoCapture(vid)
while True:
ret, frame = cap.read()
cv2.imshow('Video', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Since I've large number of videos and I'm calling the code through command line, writing the entire video name is cumbersome. So I created a dictionary. Here given the example of 2:
{"Video1.mp4": 1, 'Video2.mp4': 2}
Now I'm using the following code to call the video using value 1 or 2, rather than Video name. The code is the following:
def Main():
VideoFiles= ["Video1.mp4", "Video2.mp4"]
VideoFilesIndicator = [1, 2]
model_list = {}
for i in range(len(VideoFiles)):
model_list[VideoFiles[i]] = VideoFilesIndicator[i]
print(model_list)
def convertvalues(value):
return model_list.get(value, value)
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("-v", "--video", help = "add video file name of any format", type = convertvalues,\
choices = [1,2], default = 1)
args =parser.parse_args()
return VideoReading(args.video)
if __name__ == "__main__":
Main()
Now when I'm running the code in cmd "python VideoReading.py -v 2", it's throwing me the following error.
error: argument -v/--video: invalid choice: '2' (choose from 1, 2)
I'm not understanding why I'm getting this error. I'm following this post to build my program.
The problem is that convertvalues is returning '2' as a string, because convertvalues returns value as it is (i.e. a string) when it is not found in model_list. Try with:
def convertvalues(value):
return model_list.get(value, int(value))
Also, as it is, your argument parser will always receive an integer in video in the end (either you passed an integer or convertvalues transformed a video file name into an integer). To get the actual file name again you can do something like
args = parser.parse_args()
video_file = VideoFiles[VideoFilesIndicator.index(args.video)]
return VideoReading(video_file)
My suggestion is based on trying to make the minimal amount of changes to the code. However, you may also consider more changes in the program, like flevinkelming suggests, if you don't feel comfortable with the final shape of the code.
Your dictionary is backwards; you want to map a number to a file name, so that when you enter a number, a file name can be returned. There's no need to provide a default value from convertvalues, because you are using choices to limit the allowable inputs to the valid keys of the dict.
def main():
video_files = ["Video1.mp4", "Video2.mp4"]
model_list = dict(enumerate(video_files, start=1))
print(model_list)
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("-v", "--video",
help="add video file name of any format",
type=lambda str: model_list[int(str)],
choices=model_list.values())
args = parser.parse_args()
return VideoReading(args.video)
An alternative solution, with minimal code, and dynamic help output for users:
import argparse
def main():
model = {
1: "Video1.mp4",
2: "Video2.mp4",
3: "Video3.mp4"
} # Add more if needed
videos = ['{}({})'.format(v, str(k)) for k, v in model.items()]
help_ = "Videos to choose from: {}".format(', '.join(videos))
parser = argparse.ArgumentParser()
parser.add_argument('-v', '--video', help=help_, type=int, default=1)
args = parser.parse_args()
return VideoReading(model[args.video])
if __name__ == '__main__':
main()
python VideoReading.py -h:
usage: VideoReading.py [-h] [-v VIDEO]
optional arguments:
-h, --help show this help message and exit
-v VIDEO, --v VIDEO
Videos to choose from: Video1.mp4(1), Video2.mp4(2),
Video3.mp4(3)
python VideoReading.py:
If you were printing the selection - Video1.mp4
python VideoReading.py -v 3:
If you were printing the selection - Video3.mp4
I'l like to build a program with this behaviour:
usage: sage 4ct.py [-h] (-r R | -i I | -p P) [-o O]
But if you don't give any parameter, I'd like to have "-r 100" as the default.
Is it possible?
parser = argparse.ArgumentParser(description = '4ct args')
group_input = parser.add_mutually_exclusive_group(required = True)
group_input.add_argument("-r", "-random", help = "Random graph: dual of a triangulation of N vertices", nargs = 1, type = int, default = 100)
group_input.add_argument("-i", "-input", help = "Input edgelist filename (networkx)", nargs = 1)
group_input.add_argument("-p", "-planar", help = "Load a planar embedding of the graph G.faces() - Automatically saved at each run: input_planar_file.serialized", nargs = 1)
parser.add_argument("-o", "-output", help="Output edgelist filename (networkx)", nargs = 1, required = False)
args = parser.parse_args()
Just remove the requiredargument of the add_mutually_exclusive_group function call (or set it to False) and you're done:
import argparse
parser = argparse.ArgumentParser(description = '4ct args')
group_input = parser.add_mutually_exclusive_group(required = False)
group_input.add_argument("-r", "--random", help = "Random graph: dual of a triangulation of N vertices", type = int, default = 100)
group_input.add_argument("-i", "--input", help = "Input edgelist filename (networkx)")
group_input.add_argument("-p", "--planar", help = "Load a planar embedding of the graph G.faces() - Automatically saved at each run: input_planar_file.serialized")
parser.add_argument("-o", "--output", help="Output edgelist filename (networkx)", required = False)
print(parser.parse_args())
# Namespace(input=None, output=None, planar=None, random=100)
print(parser.parse_args("-r 77".split()))
# Namespace(input=None, output=None, planar=None, random=77)
print(parser.parse_args("-o some/path".split()))
# Namespace(input=None, output='some/path', planar=None, random=100)
print(parser.parse_args("-i some/path".split()))
# Namespace(input='some/path', output=None, planar=None, random=100)
print(parser.parse_args("-i some/path -o some/other/path".split()))
# Namespace(input='some/path', output='some/other/path', planar=None, random=100)
print(parser.parse_args("-r 42 -o some/other/path".split()))
# Namespace(input=None, output='some/other/path', planar=None, random=42)
As you can see, the random option is defaulted to 100 even if:
the output option is provided, which seems normal
an option from the mutual exclusive group other than random is provided, which can be problematic. you will have to check in your code if random is the only exclusive option which has a value before taking it in account.
This example also includes some tiny improvement to your option parser:
use long option names with two dashes (it is a convention but it also allows argparse to correctly recognise option name).
remove the nargs=1 in your options definitions which makes you retrieve a list of one value. By removing it, you could retrieve directly the value.
Give the following a try:
import argparse
import sys
parser = argparse.ArgumentParser(description='4ct args')
group_input = parser.add_mutually_exclusive_group(required=True)
group_input.add_argument("-r", "-random", help="Random graph: dual of a triangulation of N vertices", nargs=1, type=int, default=100)
group_input.add_argument("-i", "-input", help="Input edgelist filename (networkx)", nargs=1)
group_input.add_argument("-p", "-planar", help="Load a planar embedding of the graph G.faces() - Automatically saved at each run: input_planar_file.serialized",nargs=1)
parser.add_argument("-o", "-output", help="Output edgelist filename (networkx)", nargs=1, required=False)
if not sys.argv[1:]:
sys.argv.extend(['-r', '100'])
args = parser.parse_args(sys.argv[1:])
Essentially you are checking if any commandline parameters are given at all, and if not, you append the desired -r 100
I am fairly new to python and need a little guidance. I'm trying to pass some variables from the console and get and error message:
AuctionStrategy_2.0.py: error: argument -s/--sectorStocks: invalid int value: 'tep3'
when I run the console command:
run AuctionStrategy_2.0.py -in10 -out5 -rolls15 -step3 -t.001 -s5 -m100 -v50 -e'01/01/2016'
Could someone let me how to fix this please? My code at the moment does nothing except try and pass the variables from the console. Please see below for my code:
import argparse
import os
import fnmatch
import pandas as pd
from pandas.tseries.offsets import BDay
import lzma
import numpy as np
import math
import datetime
def main():
print('Processing args....')
insampleLength,outsampleLength,rolls,step,threshold,minStocksPerSector,minMarketCap,minVolume,endDate = get_args()
print(insampleLength,outsampleLength,rolls,step,threshold,minStocksPerSector,minMarketCap,minVolume,endDate)
rawDataPath = 'C:/Users/simon/Documents/data/close_unadjusted/close_unadjusted/'
def get_args():
'''This function parses and return arguments passed in'''
insampleLength = 0
outsampleLength = 0
rolls = 0
step = 0
endDate =''
minStocksPerSector = 0
threshold = 0
parser = argparse.ArgumentParser(
description='Args to run VWAP Auction simulation')
''' Command line arguments'''
parser.add_argument('-in', '--inSampleDataLength', type=int, help='Number of historic epochs insample', required=True)
parser.add_argument('-out', '--outSampleDataLength', type=int, help='Number of historic epochs outsample', required=True)
parser.add_argument('-rolls', '--numberRolls', type=int, help='Number of rolls', required=True)
parser.add_argument('-step', '--rollStep', type=int, help='Number of historic epochs', required=True)
parser.add_argument('-t','--threshold', type=float, help='starting value', required=True)
parser.add_argument('-s','--sectorStocks', type=int, help='minimum number', required=True)
parser.add_argument('-m','--marketCapCutOff', type=int,help='market capitalisation', required=True)
parser.add_argument('-v','--volumeCutOff', type=int, help='daily volume', required = True)
parser.add_argument('-e', '--endDate', type=str,help='last day of testing',required = True)
args = parser.parse_args()
''' Assign args to variables'''
insampleLength = args.inSampleDataLength
outsampleLength = args.outSampleDataLength
rolls = args.numberRolls
step = args.rollStep
threshold = args.threshold
minStocksPerSector = args.sectorStocks
minMarketCap = args.marketCapCutOff
minVolume = args.volumeCutOff
endDate = datetime.datetime.strptime(args.endDate, "%d-%b-%Y")
return insampleLength,outsampleLength,rolls,step,threshold,minStocksPerSector,minMarketCap,minVolume,endDate
if __name__ == "__main__":
print ("AuctionStategy_1.0...25/03/16")
try:
main()
except KeyboardInterrupt:
print ("Ctrl+C pressed. Stopping...")
A single dash always identifies a single-character argument. But you are trying to define -step; this is interpreted as -s, which is redefined later by the actual -s argument.
You should either pick a different identifier for "step", or always use the double-dash version --rollStep.
The argument -s expects an integer, you gave a string, this causes the error you get.
BTW, I think it's better to add spaces between the names of the arguments and it's values, e.g.:
run AuctionStrategy_2.0.py -in 10 -out 5 -rolls 15 -step 3 -t .001 -s 5 -m 100 -v 50 -e '01/01/2016'
Hope this helps
I have to write a program that reads from a file and writes some analysis to a text file. The program has to take some information via the command line but I can't see, to figure it out even given the template. I wrote a test program to see if I could succesfully pass command line input to the class.
#!/usr/bin/env python3
########################################################################
# CommandLine
########################################################################
class CommandLine() :
'''
Handle the command line, usage and help requests.
CommandLine uses argparse, now standard in 2.7 and beyond.
it implements a standard command line argument parser with various argument options,
a standard usage and help, and an error termination mechanism do-usage_and_die.
attributes:
all arguments received from the commandline using .add_argument will be
avalable within the .args attribute of object instantiated from CommandLine.
For example, if myCommandLine is an object of the class, and requiredbool was
set as an option using add_argument, then myCommandLine.args.requiredbool will
name that option.
'''
def __init__(self, inOpts=None) :
'''
CommandLine constructor.
Implements a parser to interpret the command line argv string using argparse.
'''
import argparse
self.parser = argparse.ArgumentParser(description = 'Program prolog - a brief description of what this thing does',
epilog = 'Program epilog - some other stuff you feel compelled to say',
add_help = True, #default is True
prefix_chars = '-',
usage = '%(prog)s [options] -option1[default] <input >output'
)
self.parser.add_argument('inFile', action = 'store', help='input file name')
self.parser.add_argument('outFile', action = 'store', help='output file name')
self.parser.add_argument('-lG', '--longestGene', action = 'store', nargs='?', const=True, default=True, help='longest Gene in an ORF')
self.parser.add_argument('-mG', '--minGene', type=int, choices= range(0, 2000), action = 'store', help='minimum Gene length')
self.parser.add_argument('-s', '--start', action = 'append', nargs='?', help='start Codon') #allows multiple list options
self.parser.add_argument('-v', '--version', action='version', version='%(prog)s 0.1')
if inOpts is None :
self.args = self.parser.parse_args()
else :
self.args = self.parser.parse_args(inOpts)
########################################################################
#MAIN GOES HERE
########################################################################
def main(myCommandLine=None):
'''
Implements the Usage exception handler that can be raised from anywhere in process.
'''
myCommandLine = CommandLine(myCommandLine)
#myCommandLine.args.inFile #has the input file name
#myCommandLine.args.outFile #has the output file name
#myCommandLine.args.longestGene #is True if only the longest Gene is desired
#myCommandLine.args.start #is a list of start codons
#myCommandLine.args.minGene #is the minimum Gene length to include
print (myCommandLine.args) # print the parsed argument string .. as there is nothing better to do
if myCommandLine.args.longestGene:
print ('longestGene is', str(myCommandLine.args.longestGene) )
else :
pass
class Test:
def __init__(self):
print(myCommandLine.args.minGene)
if __name__ == "__main__":
main()
class Test:
def __init__(self):
self.test()
def test(self, infile = myCommandLine.args.inFile, outfile = myCommandLine.args.outFile, longest = myCommandLine.args.longestGene, start = myCommandLine.args.start, min = myCommandLine.args.minGene):
print(infile)
print(outfile)
print(longest)
print(start)
print(min)
new_obj = Test()
The command line input should look like: python testcommand.py -minG 100 -longestG -starts ATG tass2ORFdata-ATG-100.txt
Supposedly the main program goes where it says "MAIN GOES HERE" but when I tried that I got an error that "myCommandline is not defined". So I moved the program to the end. But I get the error 'the '>' operator is reserved for future use"
I'm using Powershell if that matters. How do I get this data into my class?
You don't need CommandLine class. As suggested by James Mills, here is an example:
import argparse
class Test:
def __init__(self, infile, outfile, longest, start, min):
self.infile = infile
self.test()
def test(self):
print(self.infile)
def main():
parser = argparse.ArgumentParser(description = 'Program prolog',
epilog = 'Program epilog',
add_help = True, #default is True
prefix_chars = '-',
usage = 'xxx')
parser.add_argument('-i', '--inFile', action = 'store', help='input file name')
parser.add_argument('-o', '--outFile', action = 'store', help='output file name')
parser.add_argument('-lG', '--longestGene', action = 'store', nargs='?', const=True, default=True, help='longest Gene in an ORF')
parser.add_argument('-mG', '--minGene', type=int, choices= range(0, 20), action = 'store', help='minimum Gene length')
parser.add_argument('-s', '--start', action = 'append', nargs='?', help='start Codon') #allows multiple list options
parser.add_argument('-v', '--version', action='version', version='%(prog)s 0.1')
args = parser.parse_args()
test = Test(args.inFile, args.outFile, args.longestGene, args.minGene, args.start)
if __name__ == '__main__':
main()