Python: SyntaxError: keyword can't be an expression - python

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)

Related

Parameter naming conflict with Python

While implementing a third-party API (mollie), it seems they've named one of the parameters to support pagination "from" which conflicts with the built in python from.
Is there a way for me to use this properly? Am I not passing the parameters correctly? Note: they're written as **params.
The only parameters it supports are: from and limit.
from mollie.api.client import Client
c = Client().set_api_key(**KEY**)
c.subscriptions.list() # This works
c.subscriptions.list(limit=5) # This works
c.subscriptions.list(from="customer_code")
Gives:
File "main.py", line 7
c.subscriptions.list(from="customer_code")
^
SyntaxError: invalid syntax
Assuming that the Client is defined something like:
def list(**params):
# some stuff with params
print(params.get('from'))
print(params.get('limit'))
Then indeed calling list(from=5) will give a syntax error. But as the function packs all arguments to a kwargs dict and treats them as string keys, we can do the same thing on the other side - unpack a dict to the function arguments:
list(**{'from': 5, 'limit': 10})
Will indeed print:
5
10

In python, "request.args.get" returns what type of variable?

Please bear with me as I am a beginner in python. I'm using a framework to change values of my drone's parameters. One of the command I would like to use is vehicle.parameters['INJECT_TO_GPS']=100. When I use
vehicle.parameters['GPS_TO_INJECT']=100
It works well and changes it to 100. Now I want to include this in a function (I'm using flask to get the value of a from a web page), so If I use:
def change_value():
a = request.args.get('a', 0)
vehicle.parameters['INJECT_TO_GPS']=a
It does not work, printing me:
error: required argument is not a float
I also tried:
vehicle.parameters['INJECT_TO_GPS']=float(a)
But in this, it complains that it has to be a string...
What is wrong with it ? thanks a lot in advance
To know the type You can use inbuilt function type or isinstance to test that it belongs to that class:
print(type(a))
print(isinstance(a , class_or_type_you_want_check))

Not recognizing command line argument in Python

I am trying to add a command line argument depending on some values returned by the functions. When I am not giving that argument it says:
main.py: error: argument -opp/--operator is required
When I am giving the argument it says:
main.py: error: unrecognized arguments: -opp +
Following is the piece of EDITED code (as told in one of the answers):
parser.add_argument('-z', help='Help msg', required=True)
args, unknown = parser.parse_known_args()
value = some_functions(args.z)
if value == some_particular_value:
parser.add_argument('-opp','--operator',help='Some help msg',required=True)
args = parser.parse_args()
Please help me in adding this argument. Thanks!
There are, though, a couple of mistakes in your code. Here's the corrected version:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-z', help = 'Help msg', required = True)
args, _ = parser.parse_known_args()
# value = some_functions(args.z)
if value == some_particular_value:
parser.add_argument('-opp', '--operator', help = 'Some help msg', required = True)
# args2, _ = parser.parse_known_args()
# some_function2(args2.operator)
So, let's analyse your mistakes:
Assigning instead of comparing
That's typical newbie mistake. Within a conditional operator (if, case...) you set the value instead of checking it. The difference is in amount of the = sign.
If you assign value, the condition in the operator will be always True and test will always succeed (in most of programming languages and cases).
Check this out:
a = 1
if a = 2:
print a
This may print 2 in some languages (like C or Java; using the correct syntax). Why? You've just set it! Yet, Python is smart enough to tell you about your mistake:
File "<stdin>", line 1
if a = 2:
^
SyntaxError: invalid syntax
And compare it to this:
a = 1
if a == 2:
print a
This will not print anything. Because the if test did not pass.
Assigning value instead of calling method
You want to be using the method add_argument instead of re-defining the parser variable, right?
parser = add_argument(...)
That's something like I've described above. You should be calling a method of a parser variable, not defining its new value:
parser.add_argument(...)
Re-parsing arguments is missing?
You did not show the part of the code where you check for the operator argument. Note: you should parse your arguments again, when defined a new argument:
parser.add_argument(...)
args, _ = parser.parse_known_arguments()
Then you will get a new argument in the args variable.
Using the wrong name of argument?
Again, you are missing part of code, where you check for the operator argument' value. If you are trying to access it with
args.opp # whoops...
Then you'd just get an error saying There's no argument 'opp'!, because it has its full name and should be accessed with it:
args.operator # aaah, here it is!

Using "from" as a script argument in 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).

string.format() with optional placeholders

I have the following Python code (I'm using Python 2.7.X):
my_csv = '{first},{middle},{last}'
print( my_csv.format( first='John', last='Doe' ) )
I get a KeyError exception because 'middle' is not specified (this is expected). However, I want all of those placeholders to be optional. If those named parameters are not specified, I expect the placeholders to be removed. So the string printed above should be:
John,,Doe
Is there built in functionality to make those placeholders optional, or is some more in depth work required? If the latter, if someone could show me the most simple solution I'd appreciate it!
Here is one option:
from collections import defaultdict
my_csv = '{d[first]},{d[middle]},{d[last]}'
print( my_csv.format( d=defaultdict(str, first='John', last='Doe') ) )
"It does{cond} contain the the thing.".format(cond="" if condition else " not")
Thought I'd add this because it's been a feature since the question was asked, the question still pops up early in google results, and this method is built directly into the python syntax (no imports or custom classes required). It's a simple shortcut conditional statement. They're intuitive to read (when kept simple) and it's often helpful that they short-circuit.
Here's another option that uses the string interpolation operator %:
class DataDict(dict):
def __missing__(self, key):
return ''
my_csv = '%(first)s,%(middle)s,%(last)s'
print my_csv % DataDict(first='John', last='Doe') # John,,Doe
Alternatively, if you prefer using the more modern str.format() method, the following would also work, but is less automatic in the sense that you'll have explicitly define every possible placeholder in advance (although you could modify DataDict.placeholders on-the-fly if desired):
class DataDict(dict):
placeholders = 'first', 'middle', 'last'
default_value = ''
def __init__(self, *args, **kwargs):
self.update(dict.fromkeys(self.placeholders, self.default_value))
dict.__init__(self, *args, **kwargs)
my_csv = '{first},{middle},{last}'
print(my_csv.format(**DataDict(first='John', last='Doe'))) # John,,Doe
I faced the same problem as yours and decided to create a library to solve this problem: pyformatting.
Here is the solution to your problem with pyformatting:
>>> from pyformatting import defaultformatter
>>> default_format = defaultformatter(str)
>>> my_csv = '{first},{middle},{last}'
>>> default_format(my_csv, first='John', last='Doe')
'John,,Doe'
The only problem is pyformatting doesn't support python 2. pyformatting supports python 3.1+
If i see any feedback on the need for 2.7 support i think i will add that support.

Categories