generators in the field...
Wes asked (a couple posts back): is a generator a type of callable? Those copy/deepcopy links were helpful, I hope to any Python students trekking through here. edu-sig is a great climb for those into learning curves. Most definitely a generator is a "callable" as, in my Python for Kids (not a trademark [nTM]), a callable is simply "something with a mouth" where "a mouth" is an open-closed paren, with or without arguments. In a course or presentation, one might go into "emoticons" here, as distinct from emoji, coming before emoji in the evolution e.g. :-D and :-( were part of "ascii email" early on (SMTP etc.). In this older emoticon language, :-() shows "()" as a "mouth" i.e. parens are lips, and a callable is "that which may have a mouth" in this sense (albeit a sideways one). The rule "no keyword is a callable" is the same as saying, no keyword has a mouth. There's no True() or if() and print() is not a keyword (used to be, in older Pythons). print is a function, and as such is a callable. Generator function:
new_gen = pi() # returns digits of pi [1] next(new_gen) 3 next(new_gen) 1 next(new_gen) 4 next(new_gen) 1 next(new_gen) 9 ...
One of my favorite decorators comes from a David Beazely Youtube I watched where he goes something like: def nudge(f): "nudger" def started(): g = f() g.send(None) # or next(g) -- goes to first yield and waits return g return started What this does is take a generator object at define time and replace it with a proxy wherein it has already been "nudged" to the first yield, and is now waiting to be fed to next() or to have send() fire, which will at this point, after nudging, have a corresponding yield queued up to receive whatever. As ya'll recall, a generator on birth has its execution pointer still at the top, no steps taken, and the first next or send(None) takes it to the first yield, where it may output, and then "waits" (actually suspends execution and returns control to the caller thread). next(gen) always means: take steps to the next yield, or: raise a StopIteration if hitting return or falling off the end. In other words, at birth, a generator is not ready for any substantive obj.send(arg) because it's not at a yield yet. nudge (above) takes care of that for us, returning a proxy generator with "its pump already primed" so to speak, g.send(None) having taken g to the first yield already. In action: @nudge def get_mail(): "Get mail!" pickup = "nothing yet..." while True: pickup = (yield "Thank you for sending me {}".format(pickup)) if pickup == "q": break gm = get_mail() # a generator function try: while True: email = input("What to send? (q to quit): ") output = gm.send(email) print(output) except StopIteration: print("We appreciate your business") RUNTIME: What to send? (q to quit): birthday card Thank you for sending me birthday card What to send? (q to quit): postcard Thank you for sending me postcard What to send? (q to quit): q We appreciate your business Note: David Beazely is not in favor of having having a single yield both output and take input, as above, regarding such a double-duty yield as too confusing. My code might count as demented in his book. One of my favorite use of the generator-with-send ability patterns is what I call Tractor in a Farm [nTM]. Farm(ville) is an n x m array of dots or other character, could be numbers, and a Tractor is an iterator following some raster pattern, of row: each column, next row: each column and so on. When it finishes row 0 it jumps to the start of row 1, so not really a tractor -- more like how people read these left-to-right languages (like you're reading now). If the field were a cylinder, with East and West connecting, the tractor would go in a North to South spiral. At the bottom right, a Tractor starts over at the top left (so a donut?). Change in [row][column] (position) is what next() has the tractor do (there's a __next__ method). But then "fuel level" is dropping with each advance in some models, and without the occasional "send" of more fuel, the tractor will come to a grinding halt in the middle of a field somewhere (demented, but good for learning purposes). What's useful about this pattern is it's all "ASCII art" or "Unicode art" at first, but yet gives the idea of "pixels" (row, column) and therefore "pixel depth" (the bits needed to define a character), so the transition to a discussion of binary files, say with R, G, B layers, is pretty easy. The iterator : iterable relationship, between Tractor(s) : Field is pretty intuitive also, owing to the extended metaphor. The tractor is even simpler than the turtle concept deriving from Logo, as the tractor has a fixed and closed path. Finally, said tractors have a "read" and "write" verbs, or "sense" and "plant", meaning they're able to "write" to whatever cell (patch of Field) they're in (over), replacing the current character with another if need be, according to whatever rule. In Pythonic Andragogy slides, a TextWriterTractor (subclass of Tractor) starts writing a user-provided phrase at whatever initially passed-in (x,y) position in the field. Example: Just Use It. A CropCircleTractor (another subclass) reads the Field as complex numbers and plants "@" where z = z * z + current(row, column) doesn't spiral out after n iterations. Result: A Mandelbrot Set. https://flic.kr/p/9AWnC2 (results of plowing) Pythonic Andragogy slides: http://4dsolutions.net/presentations/pycon2013.pdf (not saying "not for kids") An ongoing theme: http://opensourcebridge.org/proposals/1102 Kirby [1] https://github.com/4dsolutions/Python5/blob/master/Pi%20Day%20Fun.ipynb (see last code cell for mysterious Pi generator discussed here on edu-sig in chapters past)
In Pythonic Andragogy slides, a TextWriterTractor (subclass of Tractor) starts writing a user-provided phrase at whatever initially passed-in (x,y) position in the field. Example: Just Use It.
A CropCircleTractor (another subclass) reads the Field as complex numbers and plants "@" where z = z * z + current(row, column) doesn't spiral out after n iterations. Result: A Mandelbrot Set.
https://flic.kr/p/9AWnC2 (results of plowing)
My apologies if the above link does not work for you. The Flickr shortcut feature seems to be more problematic that it used to be, don't know why. https://www.flickr.com/photos/kirbyurner/5646223789/sizes/l ... is another option. Shows some ASCII art made using Tractors in a Field pattern. Kirby
participants (1)
-
kirby urner