Sending changed parameters into nested generators
John O'Hagan
research at johnohagan.com
Sat Nov 13 01:52:00 EST 2010
On Sat, 13 Nov 2010, Steven D'Aprano wrote:
> On Fri, 12 Nov 2010 09:47:26 +0000, John O'Hagan wrote:
> > I have a generator function which takes as arguments another generator
> > and a dictionary of other generators like this:
> >
> > def modgen(gen, gendict):
> > for item in gen():
> > for k, v in gendict:
> > do_something_called_k(item, v.next())
> >
> > yield item
>
> [snip]
>
> > If anyone's still reading :) , how can I send new values to arbitrary
> > sub- generators?
>
> I have a headache after reading your problem :(
>
> I think it's a good time to point you at the Zen, particularly these five
> maxims:
>
> Beautiful is better than ugly.
> Simple is better than complex.
> Complex is better than complicated.
> Flat is better than nested.
> If the implementation is hard to explain, it's a bad idea.
>
>
> I'm afraid that your nested generators inside another generator idea
> fails all of those... it's not elegant (beautiful), it's complicated,
> it's nested, and the implementation is hard to explain.
>
> You could probably replace generators with full-blown iterators, but I
> wonder what you're trying to accomplish that is so complicated that it
> needs such complexity to solve it. What are you actually trying to
> accomplish? Can you give a simple example of what practical task you hope
> to perform? I suspect there's probably a more elegant way to solve the
> problem.
I hope there is!
The project not practical but artistic; it's a real-time musical composition
program.
A (simplified) description: one module contains number-list generating
functions, others contain functions designed to filter and modify the number
lists produced, according to various parameters. Each such stream of number
lists is assigned a musical meaning (e.g. pitch, rhythm, volume, etc) and they
are combined to produce representations of musical phrases, which are sent to
a backend which plays the music as it is produced, and makes PDF scores. Each
such "instrument" runs as a separate thread, so several can play together in a
coordinated fashion.
All the compositional interest lies in the selection of number-list generators
and how their output is modified. For example, if I say "Play every third note
up an octave" it's not very interesting, compared to "Play every nth note up
an interval of m", where n and m vary according to some pattern. It gets even
more interesting when that pattern is a function of x and y, which also vary
according to another pattern, and so on.
To that end, I have each parameter of each modifier set by another generator,
such that the value may change with each iteration. This may continue
recursively, until at some level we give a parameter a simple value.
That's all working, but I also want it to be interactive. Each thread opens a
terminal where new options can be entered, but so far it only works, as I
mentioned, for changing the values in a top-level mutable object.
I agree that as a piece of code this is complicated, nested and hard to
explain, but I don't agree that it's ugly. In fact, it was my existing
interest in a "patterns within patterns" style of composition that got me
learning python in the first place, as the patterns got too hard to keep track
of manually.
I'm not attached to using nested generators, and would be happy with any
solution which enables me to do what I've described. It seems to me that the
concept is inherently nested, but I'd be glad to be proved wrong.
Regards,
John
More information about the Python-list
mailing list