SyntaxError: "+=" is an unexpected token - python

First time working with Python and can't get the add and assign operator working. The interpreter keeps saying SyntaxError: invalid syntax. Does anyone know how to fix this?
def addRead(self, i=1):
if(i<1):
return self.getNumPages += i
Also tried to no avail.
def addRead(self, i=1):
if(i<1):
return
self.getNumPages += i

As you get the message that getNumPages is a method, the most intuitive way would be to call it to get its result.
But this contradicts to what you are doing:
If it is a data attribute, += would work. But you can't re-assign something to the result of a method call.
So, depending what you try to do, one of the following things are the way to go:
numpages = self.getNumPages() # first step: get the result
numpages += i # get the new value
# or just: numpages = self.getNumPages() + i
self.setNumPages(numpages) # set the new value would be the equivalent of the += stuff.
return numpages
If you don't want to reassign the value, you'd just do
return self.getNumPages() + i
Be aware, however, that getter and setter methods in Python are very unusual. You either use the attributes directly, or you wrap them in a property which is essentialy a kind of "built-in getter/setter" stuff.
class Whatever:
def getNumPages(self):
return self._numpages
def setNumPages(self, newone)
self._numpages = newone
# now the property stuff:
#property
def numpages(self): # the getter
return self.getNumPages()
#numpages.setter
def numpages(self, newone)
self.setNumPages(newone)
This property (which is essentially useless and would only be used if setting or getting is supposed to have side-effects or to modify/calculate something else as well) enables us to do
self.numpages += i
return self.numpages
which could be what you want.

a += b is a statement, so does not evaluate to a value. Thus it does not make sense to return it. Split it over lines, returning the wanted portion:
self.getNumPages += i
return self.getNumPages

Related

Why using the returned value of a method as the value of an optional parameter is not allowed in a Python function definition?

Following is my code:
def find_first_occurance(s, c, start=0, end=len(s) ):
while start<end:
if s[start] ==c: # whether they are the same or not
return start
else:
start+=1
return -1
print(find_first_occurance("the days make us happy make us wise","s"))
I got an error, name "s" is not defined.
I kind of understand what is going on. While on the other hand, it would be so nice if this feature was allowed in Python, right?
What do you think? Or did I miss something here?
s is not defined when you define the function, thus the error.
You can try initialize within the function
def find_first_occurance(s, c, start=0, end=None ):
if end is None:
end = len(s)

Can I implement a function or better a decorator that makes func(a1)(a2)(a3)...(an) == func(a1, a2, a3,...,an)? [duplicate]

On Codewars.com I encountered the following task:
Create a function add that adds numbers together when called in succession. So add(1) should return 1, add(1)(2) should return 1+2, ...
While I'm familiar with the basics of Python, I've never encountered a function that is able to be called in such succession, i.e. a function f(x) that can be called as f(x)(y)(z).... Thus far, I'm not even sure how to interpret this notation.
As a mathematician, I'd suspect that f(x)(y) is a function that assigns to every x a function g_{x} and then returns g_{x}(y) and likewise for f(x)(y)(z).
Should this interpretation be correct, Python would allow me to dynamically create functions which seems very interesting to me. I've searched the web for the past hour, but wasn't able to find a lead in the right direction. Since I don't know how this programming concept is called, however, this may not be too surprising.
How do you call this concept and where can I read more about it?
I don't know whether this is function chaining as much as it's callable chaining, but, since functions are callables I guess there's no harm done. Either way, there's two ways I can think of doing this:
Sub-classing int and defining __call__:
The first way would be with a custom int subclass that defines __call__ which returns a new instance of itself with the updated value:
class CustomInt(int):
def __call__(self, v):
return CustomInt(self + v)
Function add can now be defined to return a CustomInt instance, which, as a callable that returns an updated value of itself, can be called in succession:
>>> def add(v):
... return CustomInt(v)
>>> add(1)
1
>>> add(1)(2)
3
>>> add(1)(2)(3)(44) # and so on..
50
In addition, as an int subclass, the returned value retains the __repr__ and __str__ behavior of ints. For more complex operations though, you should define other dunders appropriately.
As #Caridorc noted in a comment, add could also be simply written as:
add = CustomInt
Renaming the class to add instead of CustomInt also works similarly.
Define a closure, requires extra call to yield value:
The only other way I can think of involves a nested function that requires an extra empty argument call in order to return the result. I'm not using nonlocal and opt for attaching attributes to the function objects to make it portable between Pythons:
def add(v):
def _inner_adder(val=None):
"""
if val is None we return _inner_adder.v
else we increment and return ourselves
"""
if val is None:
return _inner_adder.v
_inner_adder.v += val
return _inner_adder
_inner_adder.v = v # save value
return _inner_adder
This continuously returns itself (_inner_adder) which, if a val is supplied, increments it (_inner_adder += val) and if not, returns the value as it is. Like I mentioned, it requires an extra () call in order to return the incremented value:
>>> add(1)(2)()
3
>>> add(1)(2)(3)() # and so on..
6
You can hate me, but here is a one-liner :)
add = lambda v: type("", (int,), {"__call__": lambda self, v: self.__class__(self + v)})(v)
Edit: Ok, how this works? The code is identical to answer of #Jim, but everything happens on a single line.
type can be used to construct new types: type(name, bases, dict) -> a new type. For name we provide empty string, as name is not really needed in this case. For bases (tuple) we provide an (int,), which is identical to inheriting int. dict are the class attributes, where we attach the __call__ lambda.
self.__class__(self + v) is identical to return CustomInt(self + v)
The new type is constructed and returned within the outer lambda.
If you want to define a function to be called multiple times, first you need to return a callable object each time (for example a function) otherwise you have to create your own object by defining a __call__ attribute, in order for it to be callable.
The next point is that you need to preserve all the arguments, which in this case means you might want to use Coroutines or a recursive function. But note that Coroutines are much more optimized/flexible than recursive functions, specially for such tasks.
Here is a sample function using Coroutines, that preserves the latest state of itself. Note that it can't be called multiple times since the return value is an integer which is not callable, but you might think about turning this into your expected object ;-).
def add():
current = yield
while True:
value = yield current
current = value + current
it = add()
next(it)
print(it.send(10))
print(it.send(2))
print(it.send(4))
10
12
16
Simply:
class add(int):
def __call__(self, n):
return add(self + n)
If you are willing to accept an additional () in order to retrieve the result you can use functools.partial:
from functools import partial
def add(*args, result=0):
return partial(add, result=sum(args)+result) if args else result
For example:
>>> add(1)
functools.partial(<function add at 0x7ffbcf3ff430>, result=1)
>>> add(1)(2)
functools.partial(<function add at 0x7ffbcf3ff430>, result=3)
>>> add(1)(2)()
3
This also allows specifying multiple numbers at once:
>>> add(1, 2, 3)(4, 5)(6)()
21
If you want to restrict it to a single number you can do the following:
def add(x=None, *, result=0):
return partial(add, result=x+result) if x is not None else result
If you want add(x)(y)(z) to readily return the result and be further callable then sub-classing int is the way to go.
The pythonic way to do this would be to use dynamic arguments:
def add(*args):
return sum(args)
This is not the answer you're looking for, and you may know this, but I thought I would give it anyway because if someone was wondering about doing this not out of curiosity but for work. They should probably have the "right thing to do" answer.

Pythonic way to maintain variable assignment

I was writing a small file utility earlier, and ran into an issue with passing by reference. After reading How do I pass a variable by reference?, I set the variable I wanted to pass through as an argument and also as the return value. Within the code below, it is the line:
diff = compareDir(path0, path0List, path1, path1List, diff)
where diff is the variable I wished to pass by reference.
While this works, it feels rather awkward. I think there must be a better way. In many other languages, I could just set compareLists() to have no return value, and use the side-effect of modifying the pass-by-reference argument. Python's pass-by-assignment seems to disallow this.
I am relatively new to python, and would like to know if there is a more pythonic way to resolve my issue. Would it require rethinking the functions entirely? Or is there a nice statement I am unaware of? I'd like to stay away from global variables.
I welcome any and all constructive criticisms and comments. Thanks!
Relevant Code:
def comparePaths(path0, path1):
path0List = os.listdir(path0)
path1List = os.listdir(path1)
diff = False
diff = compareDir(path0, path0List, path1, path1List, diff)
print()
diff = compareDir(path1, path1List, path0, path0List, diff)
return diff
def compareDir(basePath, baseList, comparePath, compareDir, diffVar):
for entry in baseList:
#compare to the other folder
if (not (entry in compareDir)):
if (not (diffVar)):
diffVar = True
print ("Discreptancies found. The following files are different:")
print (str(entry) + " doesn\'t exist in " + str(comparePath))
else:
print (str(entry) + " doesn\'t exist in " + str(comparePath))
return diffVar
Since in Python, the bool type is by definition immutable, the only way to modify a bool variable inside a function without reassigning it (and without defining it as a global variable) is to store it in a mutable type instance. ie:
Storing it in a mutable data structure (list, dict, ...) and pass this data structure to the function.
Having it as an attribute of a mutable object, and pass this object to the function.
Your problem has multiple possible solutions.
You can add nonlocal modifier (global prior to python3) for your diff variable to modify from inside function and have changes visible from outside.
diff = False
def compareDir(basePath, baseList, comparePath, compareDir):
nonlocal diff
for entry in baseList:
...
diff = True
compareDir(path0, path0List, path1, path1List)
print()
compareDir(path1, path1List, path0, path0List)
return diff
Or you can have OOP solution with differ object and self.diff as explicit state of that object.
class differ(object):
def __init__(self):
self.diff = False
def compareDir(self, basePath, baseList, comparePath, compareDir):
...
self.diff = True
...
def comparePaths(self, path0, path1):
Latter solution is super helpful if you need to do a lot of work in some 'context' and frequently need to change shared state.

Any method to denote object assignment?

I've been studying magic methods in Python, and have been wondering if there's a way to outline the specific action of:
a = MyClass(*params).method()
versus:
MyClass(*params).method()
In the sense that, perhaps, I may want to return a list that has been split on the '\n' character, versus dumping the raw list into the variable a that keeps the '\n' intact.
Is there a way to ask Python if its next action is about to return a value to a variable, and change action, if that's the case? I was thinking:
class MyClass(object):
def __init__(params):
self.end = self.method(*params)
def __asgn__(self):
return self.method(*params).split('\n')
def __str__(self):
"""this is the fallback if __asgn__ is not called"""
return self.method(*params)
No. You cannot change what happens when you assign to a bare name.
You can change what happens if the assignment target on the left hand side is an attribute or item of an object. You can override a[blah] = ... with __setitem__ and a.blah = ... with __setattr__ (although you can only hook into these on a, not on the object being assigned). But you can't override or in any way influence a = ....
Note that having the right-hand side change based on what is "going to happen" would be even stranger, and very bad. That would mean that
someFunc(MyClass().method())
could be different than
a = MyClass().method()
someFunc(a)
In Python names are just labels attached to objects. Objects don't get to know what labels are attached to them, and that's a good thing. You might assign the result a computation to an intermediate variable just to make subsequent lines more readable, and you don't want that assignment to change the result of that computation.
There should be no difference between calling MyClass(*params).method() directly and assigning it to a variable. What you may be seeing here is your interpreter automatically printing return results, which is why it appears to be split while the variable value contains EOL markers.
There is no way to override default assignment to a variable. However, by using an object, you can easily provide your own hooks:
class Assigner(object):
def __init__(self, assignment_callback):
self.assignment = assignment_callback
def __setattr__(self, key, value):
if hasattr(self, 'assignment'):
value = self.assignment(value)
super(Assigner, self).__setattr__( key, value )
def uppercase(value):
# example function to perform on each attribute assignment
return value.upper()
Then in your code, rather than assigning to a variable directly you assign to attributes on your object:
>>> my = Assigner(uppercase)
>>> my.a = 'foo'
>>> print my.a
FOO
Yes.* Python allows inspecting its own stack, which can be used to peek ahead at the next instruction.
#!/usr/bin/env python3
import dis
import inspect
from itertools import dropwhile
class MyClass(object):
def method(self):
# inspect the stack to get calling line of code
frame = inspect.stack()[1].frame
# disassemble stack frame
ins = dis.get_instructions(frame.f_code)
# move to last instruction
ins = dropwhile(lambda x: x.offset < frame.f_lasti, ins)
# the last call would have been to this method/function
current_instruction = ins.__next__()
assert current_instruction.opname.startswith('CALL_')
# peek ahead at the next instruction
next_instruction = ins.__next__()
# vary behaviour depending on the next instruction
if next_instruction.opname.startswith('STORE_'):
return "returning to assignment"
elif next_instruction.opname.startswith('CALL_'):
return "returning to function/method call"
elif next_instruction.opname == 'POP_TOP':
print("return value thrown away")
return "return ignored"
elif next_instruction.opname == 'PRINT_EXPR':
return "return to interactive console"
else:
return "return to {}".format(next_instruction.opname)
This will result in the following behaviour:
a = MyClass().method()
print(a)
# returning to assignment
def someFunc(x):
return x.split()
b = someFunc(MyClass().method())
print(b)
# ['returning', 'to', 'function/method', 'call']
MyClass().method()
# return value thrown away (if called as program)
# return to interactive console (if run interactively)
* Though as the accepted answer points out, doing so is "very bad". It's also fragile, as it can be affected by bytecode optimisation. See also: Nested dictionary that acts as defaultdict when setting items but not when getting items

TypeError: object.__new__() takes no parameters when using inheritance

Hey,
I'm having a hard time implementing something, that I guess shouldn't be hard. I've been reading many posts, and I still can't figure it out, though it is probably answered, and I might just simply not understand the answer :/
So, I have a class, defining an algorithm file three_dpll.py in logics/ and a couple of helper functions
class three_dpll(object):
...
def __extend__(self, symbol, value, mod):
""" __extend__(symbol, value) - extends the model
...
"""
def three_dpll(self, formula, symbols, mod):
""" three_dpll(formula, symbols, mod) - calculates 3-DPLL \n
NOTE: This algorithm should not be overwritten in any derived class!!"""
...
# find unit clause
curr_data = self.__find_unit_clause__(formula, mod)
current_symbol = curr_data[0]
current_symbol_set.add(current_symbol)
current_value = curr_data[1]
if current_symbol != None:
return three_dpll(formula, symbols - current_symbol_set,
self.__extend__(current_symbol, current_value, mod))
...
and a logic that should implement the algorithm for a certain logic, where I might redefine certain methods like from logics.three_dpll.py (or any other helper function for that matter )
from three_dpll import three_dpll
class kleene_logic(three_dpll):
""" This is the definition of Kleene logic """
pass
and now calling it from a function in another file:
def satisfiable(logic, formula):
""" satisfiable - \
takes a logic and a set of formula and returns true or false"""
# model is empty dictionary
model = {}
# symbols is a set
symbols = set()
my_logic = "logics."+logic # logic is passed as string to the script
__import__(my_logic, fromlist=['three_dpll'])
log = modules[my_logic]
used_logic = log.kleene_logic()
for clause in formula:
ite = iter(clause)
for literal in ite:
symbols.add(abs(literal))
try:
return used_logic.three_dpll(formula, symbols, model)
except FormulaValid.FormulaValid:
return True
The error I get is:
in three_dpll
self.__extend__(current_symbol, current_value, mod)) TypeError: object.__new__() takes no parameters
Any ideas on how to fix this?
Your class three_dpll also has a method three_dpll. When you
return three_dpll(...)
you are creating an instance of that class (instead of calling the method, which is probably what you wanted to do). The class has no __init__() function that could handle the arguments that you are giving. That is what the error message tells you.
What you want is probably something like
return self.three_dpll(...)
which would call the method. Not shure if it solves your problem, but that should explain something.

Categories

Resources