Python 2: someIterator.next() vs. next(someIterator) :Python 3 - python-2.7

In Python 2 iterators offer .next(), a callable method:
it = iter(xrange(10))
it.next()
> 0
it.next()
> 1
...
In Python 3 one has to use the built-in function next():
it = iter(range(10))
next(it)
> 0
next(it)
> 1
...
Is this just "syntactic sugar"? Like making it more obvious to use next() by moving it into the built-in functions? Or does any advanced concept hide behind this change?

You are directly asking about PEP 3114
consider the following code:
class test:
def __iter__(self):
return self
def next(self):
return "next"
def __next__(self):
return "__next__"
x = test()
for i,thing in enumerate(x):
print(thing)
if i>4:
break
in python 2 next is printed but in python 3 __next__ is printed, since the method is being called implicitly it makes way more sense to match other implicit methods such as __add__ or __getitem__, which is described in the PEP.
If you are planning on using next explicitly then much like len, iter, getattr, hash etc. then python provides a built in function to call the implicit function for you. At least... after PEP 3114. 😀
Also, the next built-in allows you pass a default value if you don't want to throw an error if the iterable is finished which is frequently useful:
it = iter([])
x = next(it, "pls don't crash")
which couldn't really be standardized for a .next() method call. As well objects such as a random number generator may define a .next (next number) method without necessarily wanting to be an iterator which could have left ambiguity / confusion.

Related

What is the idiomatic (and fast) way of treating the empty list/Seq as failure in a short-circuiting operation?

I have a situation where I am using functions to model rule applications, with each function returning the actions it would take when applied, or, if the rule cannot be applied, the empty list. I have a number of rules that I would like to try in sequence and short-circuit. In other languages I am used to, I would treat the empty sequence as false/None and chain them with orElse, like this:
def ruleOne(): Seq[Action] = ???
def ruleTwo(): Seq[Action] = ???
def ruleThree(): Seq[Action] = ???
def applyRules(): Seq[Action] = ruleOne().orElse(ruleTwo).orElse(ruleThree)
However, as I understand the situation, this will not work and will, in fact, do something other than what I expect.
I could use return which feels bad to me, or, even worse, nested if statements. if let would have been great here, but AFAICT Scala does not have that.
What is the idiomatic approach here?
You have different approaches here.
One of them is combining all the actions inside a Seq (so creating a Seq[Seq[Action]]) and then using find (it will return the first element that matches a given condition). So, for instance:
Seq(ruleOne, ruleTwo, ruleThree).find(_.nonEmpty).getOrElse(Seq.empty[Action])
I do not know clearly your domain application, but the last getOrElse allows to convert the Option produced by the find method in a Seq. This method though eval all the sequences (no short circuit).
Another approach consists in enriching Seq with a method that simulated your idea of orElse using pimp my library/extensions method:
implicit class RichSeq[T](left: Seq[T]) {
def or(right: => Seq[T]): Seq[T] = if(left.isEmpty) { right } else { left }
}
The by name parameter enable short circuit evaluation. Indeed, the right sequence is computed only if the left sequence is empty.
Scala 3 has a better syntax to this kind of abstraction:
extension[T](left: Seq[T]){
def or(rigth: => Seq[T]): Seq[T] = if(left.nonEmpty) { left } else { rigth }
}
In this way, you can call:
ruleOne or ruleTwo or ruleThree
Scastie for scala 2
Scastie for scala 3

Python - Classes and objects

This may appear like a very trivial question but I have just started learning python classes and objects. I have a code like below.
class Point(object):
def __init__(self,x,y):
self.x = float(x)
self.y = float(y)
def __str__(self):
return '('+str(self.x)+','+str(self.y)+')'
def main():
p1 = Point(pt1,pt2)
p2 = Point(pt3,pt4)
p3 = Point(pt5,pt6)
p4 = Point(pt7,pt8)
parray = [p1,p2,p3,p4]
print " Points are", p1,p2,p3,p4
print "parray",parray
I m getting the below Output :
Points are (4.0,2.0) (4.0,8.0) (4.0,-1.0) (100.0,1.0)
parray - intersection.Point object at 0x7ff09f00a550, intersection.Point object at 0x7ff09f00a410, intersection.Point object at 0x7ff09f00a590
My question is why are the addresses of objects assigned to array while I get the values while printing the objects?
Can someone suggest a way to get the values returned by class in array in main function?
When you print an object as an individual argument to a print statement in Python 2 or the print() function in Python 3, Python calls str on the object before printing it out.
When you put the object inside a container like a list and print the list, the list gets str called on it, but it in turn calls repr on each of the items it contains, rather than str. To understand why, look at the list [1, '2, 3', 4] and imagine what it would look like if the quotation marks were not included in the output when it was printed. The quotation marks are part of the '2, 3' string's repr.
So to make your class work the way you want, either rename your __str__ method to __repr__ (which will also work for str calls, since the default implementation of __str__ is to call __repr__), or add an additional __repr__ method. Sometimes it's useful to have a __repr__ that returns a less ambiguous string than __str__ does (for instance, it might name the class as well as the arguments). One common convention is to make __repr__ return a string that could be evaled to get an equivalent object again. For your class, that could look like:
def __repr__(self):
return "{}({!r}, {!r})".format(type(self).__name__, self.x, self.y)
I'd also recommend using string formatting like this (or the older %s style if you prefer), rather than concatenating lots of strings together to build your result.
Python containers, e.g. lists use an objects __repr__ method when printing their contents, not their __str__, Define __repr__ instead:
def __repr__(self):
return '('+str(self.x)+','+str(self.y)+')'
If you want a more detailed explanation of __repr__ vs __str__ see here

Hybrid Generator/Function in Python

Is is possible in Python to have a generator that yields values in a loop be alternatively called as a normal function where the final value of that loop is returned? I tried setting a flag as argument and then choose to yield or return depending on that flag. But the mere existence of the keyword yield in a function transforms it automatically into a generator and Python complains that there was a return statement in a generator.
Here an example of such a function:
def function(generator=True):
a = 0
for i in range(10):
a = i
if generator:
yield a
if not generator:
return a
Such a function would be useful for me when in some cases I just need the final result (eg. using it as residual function for optimization) while in other cases I need the incremental results after each iteration (for example using a differential model for a robot, updating the robot's pose with each new velocity command). For now I am having two functions where one has the yield and the other has the return. So is it possible to combine those two?
You'll still have to iterate over it to get its single value, but you can use yield again instead of return to accomplish this.
>>> def function(generator=True):
... a = 0
... for i in range(10):
... a = i
... if generator:
... yield a
... if not generator:
... yield a
...
>>> a = function()
>>> print(*a)
0 1 2 3 4 5 6 7 8 9
>>> a = function(0)
>>> print(a)
<generator object function at 0x0000000001603240>
>>> print(*a)
9
>>> a = function(0)
Note that having return inside a generator is a SyntaxError in Python 2, but not Python 3. Replacing the return with yield produces the same result in 2 and 3.
it's still a generator, even calling return.
I'd to not mix both generator/regular function anyway.
You can wrap something on top of the iterator, in case you need to loop through the results anyway.
A simple code that could do what you want:
last = None
for last in function(): pass
Now last holds the value you want and you can use it on your code.
The return inside a generator was added to Python 3.3
And it's equivalent to StopIteration(value)
return expr in a generator causes StopIteration(expr) to be raised
upon exit from the generator.
In a generator, the statement
return value is semantically equivalent to
raise StopIteration(value) except that, as currently, the exception
cannot be caught by except clauses within the returning generator.

Python - null object pattern with generators

It is apparently Pythonic to return values that can be treated as 'False' versions of the successful return type, such that if MyIterableObject: do_things() is a simple way to deal with the output whether or not it is actually there.
With generators, bool(MyGenerator) is always True even if it would have a len of 0 or something equally empty. So while I could write something like the following:
result = list(get_generator(*my_variables))
if result:
do_stuff(result)
It seems like it defeats the benefit of having a generator in the first place.
Perhaps I'm just missing a language feature or something, but what is the pythonic language construct for explicitly indicating that work is not to be done with empty generators?
To be clear, I'd like to be able to give the user some insight as to how much work the script actually did (if any) - contextual snippet as follows:
# Python 2.7
templates = files_from_folder(path_to_folder)
result = list(get_same_sections(templates)) # returns generator
if not result:
msg("No data to sync.")
sys.exit()
for data in result:
for i, tpl in zip(data, templates):
tpl['sections'][i]['uuid'] = data[-1]
msg("{} sections found to sync up.".format(len(result)))
It works, but I think that ultimately it's a waste to change the generator into a list just to see if there's any work to do, so I assume there's a better way, yes?
EDIT: I get the sense that generators just aren't supposed to be used in this way, but I will add an example to show my reasoning.
There's a semi-popular 'helper function' in Python that you see now and again when you need to traverse a structure like a nested dict or what-have-you. Usually called getnode or getn, whenever I see it, it reads something like this:
def get_node(seq, path):
for p in path:
if p in seq:
seq = seq[p]
else:
return ()
return seq
So in this way, you can make it easier to deal with the results of a complicated path to data in a nested structure without always checking for None or try/except when you're not actually dealing with 'something exceptional'.
mydata = get_node(my_container, ('path', 2, 'some', 'data'))
if mydata: # could also be "for x in mydata", etc
do_work(mydata)
else:
something_else()
It's looking less like this kind of syntax would (or could) exist with generators, without writing a class that handles generators in this way as has been suggested.
A generator does not have a length until you've exhausted its iterations.
the only way to get whether it's got anything or not, is to exhaust it
items = list(myGenerator)
if items:
# do something
Unless you wrote a class with attribute nonzero that internally looks at your iterations list
class MyGenerator(object):
def __init__(self, items):
self.items = items
def __iter__(self):
for i in self.items:
yield i
def __nonzero__(self):
return bool(self.items)
>>> bool(MyGenerator([]))
False
>>> bool(MyGenerator([1]))
True
>>>

Is it possible to use User Defined Attributes to get values at runtime?

What I really would like to do is cache/memoize certain function arguments and results. I understand in d there's User Defined Attributes, but it appears theres no way to get runtime values with it. Am I mistaken? Is there another similar design pattern I could use here to get similar results?
#memoize("expensiveCalc")
int expensiveCalc(string foo){
///bar
}
So memoize is actually a function that gets called. However, it utilizes the value of my arguments to quickly hash parameters and call the actual function.
Similar to this:
def memoize(iden, time = 0, stale=False, timeout=30):
def memoize_fn(fn):
def new_fn(*a, **kw):
#if the keyword param _update == True, the cache will be
#overwritten no matter what
update = kw.pop('_update', False)
key = make_key(iden, *a, **kw)
res = None if update else memoizecache.get(key)
if res is None:
# okay now go and actually calculate it
res = fn(*a, **kw)
memoizecache.set(key, res, time=time)
return res
new_fn.memoized_fn = fn
return new_fn
return memoize_fn
For what you're trying to do, you'll want a wrapper template rather than a UDA. Phobos actually has one for memoization: http://dlang.org/phobos/std_functional.html#memoize
UDAs in D are used to add information to a function (or other symbol, types and variables too), but they don't actually modify it. The pattern is to have some other code read all the names with reflection, look at the UDAs, and generate the new code that way. If you want to get runtime values from a UDA, you'd write a function that reads it with compile time reflection, then returns the value. Calling that function at runtime gives the UDA there. If you'd like to know more, I can write it up, but I think std.functional.memoize will do what you want here. Remember, UDAs in D add information, they don't change or create code.