Using "from" as a script argument in Python - python

My assignment requires that "from" be used as an argument for the command line input.
p = optparse.OptionParser()
p.add_option("--from")
p.add_option("--to")
p.add_option("--file", default="carla_coder.ics")
options, arguments = p.parse_args()
print options.from
obviously, "from" is a Python keyword... is there any way to get around this? Basically, the script should be run using
file.py --from=dd/mm/yyyy --to=dd/mm/yyyy --file=file

Use the dest attribute to specify a name:
p.add_option("--from", dest="foo")
print options.foo

Use Python's getattr function:
getattr(options, 'from')
Will behave like options.from, except that the attribute name doesn't have to follow Python's usual variable naming rules (including keyword conflicts).

Related

Pass argument store in variable to argparse

This is my script mytest.py.
import argparse
parser = argparse.ArgumentParser(description="Params")
parser.add_argument(
"--value")
def test(args):
print(args.value)
args = parser.parse_args()
test(args)
I want to pass argument store in variable val
val =1
!python mytest.py --value val
instead of printing 1 it print val. How to send 1 stored in variable val.
argparse always get argument as string, or list of strings on default, and what you do on your shell is irrelevant with python program. It is no wonder val is printed.
Use file that contains "1" and read that file to do what you intended to.
As jueon park said naming a variable in commandline wont work
It would create an error like the above one.If you are calling the command from any programer will work but in cmd it won't work
I'm very late for this but your python code works just fine. The problem you have is that you are not passing the arguments correctly.
For this to work first you need to correctly set the variable:
val=1
(note that the "=" must be next to both the variable name and the value)
and the you can simply use $ to get the value from the variable. So:
python mytest.py --value $val

python: SyntaxError: invalid syntax Expected member name after "."

I'm using argparse to parse the parameters, but when I get args.global, a strange error appears, I don't know where I did it wrong
...
parser.add_argument('-u','--update', action='store_true', default=None)
parser.add_argument('-g','--global', action='store_true', default=None)
args = parser.parse_args()
...
if args.update:
print(args)
print( args.global )
print( args.update )
$ python ./anpm.py -g -u
File "./anpm.py", line 67
print( args.global )
^
SyntaxError: invalid syntax
This is the error given by vscode
$ python --version
Python 3.6.8
global is a keyword in Python (as are if, while, etc.) and you cannot use these as attribute names, which means they also don't work in a NameSpace object.
More on that here:
https://docs.python.org/3/reference/lexical_analysis.html#keywords
However, you can still access these values if you need to use these names:
my_args = vars(args)
print(my_args['global'])
This works because it doesn't use the reserved word, instead it just uses a string (containing the reserved word) to access its value.
If you only need access once, or infrequently and you don't want to keep the vars() result around, you can also just:
print(vars(args)['global'])
Use getattr:
print(getattr(args, 'global'))
This would get the attribute global.
Global Explanation
Global is a reserved keyword in python that is used to declare a variable globally inside the functional scope.
Example:
def p():
global x
x=23
p()
print(x)
//returns 23
Keywords and example
A keyword can't be used as an argument or a variable in python. you can have other examples like
yield=23
return=34
pass=34
continue=23
.....
All these make an error.
Solution
Try changing the name from global to __global or _global or something like this.

argparse: how to parse a single string argument OR a file listing many arguments?

I have a use case where I'd like the user to be able to provide, as an argument to argparse, EITHER a single string OR a filename where each line has a string.
Assume the user launches ./myscript.py -i foobar
The logical flow I'm looking for is something like this:
The script determines whether the string foobar is a readable file.
IF it is indeed a readable file, we call some function from the script, passing each line in foobar as an argument to that function. If foobar is not a readable file, we call the same function but just use the string foobar as the argument and return.
I have no ability to guarantee that a filename argument will have a specific extension (or even an extension at all).
Is there a more pythonic way to do this OTHER than just coding up the logic exactly as I've described above? I looked through the argparse tutorial and didn't see anything, but it also seems reasonable to think that there would be some specific hooks for filenames as arguments, so I figured I'd ask.
A way would be:
Let's say that you have created a parser like this:
parser.add_argument('-i',
help='...',
type=function)
Where type points to the function which will be an outer function that evaluates the input of the user and decides if it is a string or a filename
More information about type you can find in the documentation.
Here is a minimal example that demonstrates this use of type:
parser.add_argument('-d','--directory',
type=Val_dir,
help='...')
# ....
def Val_dir(dir):
if not os.path.isdir(dir):
raise argparse.ArgumentTypeError('The directory you specified does not seem to exist!')
else:
return dir
The above example shows that with type we can control the input at parsing time. Of course in your case the function would implement another logic - evaluate if the input is a string or a filename.
This doesn't look like an argparse problem, since all you want from it is a string. That string can be a filename or a function argument. To a parser these will look the same. Also argparse isn't normally used to run functions. It is used to parse the commandline. Your code determines what to do with that information.
So here's a script (untested) that I think does your task:
import argparse
def somefunction(*args):
print(args)
if __name__=='__main__':
parser=argparse.ArgumentParser()
parser.add_argument('-i','--input')
args = parser.parse_args()
try:
with open(args.input) as f:
lines = f.read()
somefunction(*lines)
# or
# for line in lines:
# somefuncion(line.strip())
except:
somefunction(arg.input)
argparse just provides the args.input string. It's the try/except block that determines how it is used.
================
Here's a prefix char approach:
parser=argparse.ArgumentParser(fromfile_prefix_chars='#',
description="use <prog -i #filename> to load values from file")
parser.add_argument('-i','--inputs')
args=parser.parse_args()
for arg in args.inputs:
somefunction(arg)
this is supposed to work with a file like:
one
two
three
https://docs.python.org/3/library/argparse.html#fromfile-prefix-chars

Postion of argument will be fixed

in command line if I run my program
python parse.py config=abc.txt factor_date=20151001 like this
I want the position of argument will be fixed. That means if I pass argument like below
python parse.py factor_date=20151001 config=abc.txt
it has to show error.
import sys
config_file=sys.argv[1]
factor_date = sys.argv[2]
argstring=""+config_file+" "+factor_date+""
arg_list = argstring.split(' ')
input={}
for arg in arg_list:
#x=arg.split("--")
key,val=arg.split("=")[0],arg.split("=")[1]
if key == "config":
input[key]=val
if key =="factor_date":
input[key]=val
print input
You can have a look at click. It let's you create command line interfaces pretty much effortlessly. It's bases on using decorators.
You should have a look at argparse. Your use case is for positional arguments. If you specify the name of the argument (optional arguments with argparse) then it does not make sense to force a specific order.
Still, when using positional arguments one could call the program with worng arguments, you will have to check by yourself the values provided by the user. However, you can force a type and it will automagically convert the strings, which in the case you describe would solve the problem.

Python: SyntaxError: keyword can't be an expression

In a Python script I call a function from rpy2, but I get this error:
#using an R module
res = DirichletReg.ddirichlet(np.asarray(my_values),alphas,
log=False, sum.up=False)
SyntaxError: keyword can't be an expression
What exactly went wrong here?
sum.up is not a valid keyword argument name. Keyword arguments must be valid identifiers. You should look in the documentation of the library you are using how this argument really is called – maybe sum_up?
I guess many of us who came to this page have a problem with Scikit Learn, one way to solve it is to create a dictionary with parameters and pass it to the model:
params = {'C': 1e9, 'gamma': 1e-07}
cls = SVC(**params)
It's python source parser failure on sum.up=False named argument as sum.up is not valid argument name (you can't use dots -- only alphanumerics and underscores in argument names).
Using the Elastic search DSL API, you may hit the same error with
s = Search(using=client, index="my-index") \
.query("match", category.keyword="Musician")
You can solve it by doing:
s = Search(using=client, index="my-index") \
.query({"match": {"category.keyword":"Musician/Band"}})
I just got that problem when converting from % formatting to .format().
Previous code:
"SET !TIMEOUT_STEP %{USER_TIMEOUT_STEP}d" % {'USER_TIMEOUT_STEP' = 3}
Problematic syntax:
"SET !TIMEOUT_STEP {USER_TIMEOUT_STEP}".format('USER_TIMEOUT_STEP' = 3)
The problem is that format is a function that needs parameters. They cannot be strings.
That is one of worst python error messages I've ever seen.
Corrected code:
"SET !TIMEOUT_STEP {USER_TIMEOUT_STEP}".format(USER_TIMEOUT_STEP = 3)

Categories