<div dir="ltr"><div>Hi Danilo, <br></div><div><br></div><div>The idea of decorating a function to show that the return variables could be fed back in in a scan form is interesting and could solve my problem in a nice way without new syntax.</div><div><br></div><div>I looked at your code but got a bit confused as to how it works (there seems to be some magic where the decorator injects the scanned variable into the namespace).  Are you able to show how you'd implement the moving average example with your package?</div><div><br></div><div>I tried: </div><div><br></div><div><div>    @enable_scan("average")</div><div>    def exponential_moving_average_pyscan(signal, decay, initial=0):</div><div>        yield from ((1-decay)*(average or initial) + decay*x for x in signal)</div><div>    </div><div>    </div><div>    smooth_signal_9 = list(exponential_moving_average_pyscan(signal, decay=decay))[1:]</div></div><div><br></div><div>Which almost gave the right result, but seemed to get the initial conditions wrong.  </div><div><br></div><div>- Peter</div><div><br></div><div><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Apr 14, 2018 at 3:57 PM, Danilo J. S. Bellini <span dir="ltr"><<a href="mailto:danilo.bellini@gmail.com" target="_blank">danilo.bellini@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><span class="gmail-m_-7145660737251500606m_-5774532688697618044gmail-"><div class="gmail_quote">On 5 April 2018 at 13:52, Peter O'Connor <span dir="ltr"><<a href="mailto:peter.ed.oconnor@gmail.com" target="_blank">peter.ed.oconnor@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">I was thinking it would be nice to be able to encapsulate this common type of operation into a more compact comprehension.<div><br></div><div>I propose a new "Reduce-Map" comprehension that allows us to write: </div><div><pre style="font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial;background-color:rgb(43,43,43);color:rgb(169,183,198);font-family:Menlo;font-size:9pt"><pre style="background-color:rgb(43,43,43);color:rgb(169,183,198);font-family:Menlo;font-size:9pt">signal = [math.<span style="color:rgb(204,120,51)">sin</span>(i*<span style="color:rgb(104,151,187)">0.01</span>) + random.<span style="color:rgb(204,120,51)">normalvariate</span>(<span style="color:rgb(104,151,187)">0</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(104,151,187)">0.1</span>) <span style="color:rgb(70,126,183);font-weight:bold">for </span>i <span style="color:rgb(70,126,183);font-weight:bold">in </span><span style="color:rgb(136,136,198)">range</span>(<span style="color:rgb(104,151,187)">1000</span>)]<br>smooth_signal = [average = (<span style="color:rgb(104,151,187)">1</span>-decay)*average + decay*x <span style="color:rgb(70,126,183);font-weight:bold">for </span>x <span style="color:rgb(70,126,183);font-weight:bold">in </span>signal <span style="color:rgb(70,126,183);font-weight:bold">from </span>average=<span style="color:rgb(104,151,187)">0.</span>]</pre></pre></div><div>Instead of:</div><div><pre style="background-color:rgb(43,43,43);color:rgb(169,183,198);font-family:Menlo;font-size:9pt"><pre style="background-color:rgb(43,43,43);color:rgb(169,183,198);font-family:Menlo;font-size:9pt"><pre style="background-color:rgb(43,43,43);color:rgb(169,183,198);font-family:Menlo;font-size:9pt"><span style="color:rgb(70,126,183);font-weight:bold">def </span><span style="font-weight:bold">exponential_moving_average</span>(sig<wbr>nal: Iterable[<span style="color:rgb(136,136,198)">float</span>]<span style="color:rgb(204,120,50)">, </span>decay: <span style="color:rgb(136,136,198)">float</span><span style="color:rgb(204,120,50)">, </span>initial_value: <span style="color:rgb(136,136,198)">float</span>=<span style="color:rgb(104,151,187)">0.</span>):<br>    average = initial_value<br>    <span style="color:rgb(70,126,183);font-weight:bold">for </span>xt <span style="color:rgb(70,126,183);font-weight:bold">in </span>signal:<br>        average = (<span style="color:rgb(104,151,187)">1</span>-decay)*average + decay*xt<br>        <span style="color:rgb(70,126,183);font-weight:bold">yield </span>average<br><br>signal = [math.<span style="color:rgb(204,120,51)">sin</span>(i*<span style="color:rgb(104,151,187)">0.01</span>) + random.<span style="color:rgb(204,120,51)">normalvariate</span>(<span style="color:rgb(104,151,187)">0</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(104,151,187)">0.1</span>) <span style="color:rgb(70,126,183);font-weight:bold">for </span>i <span style="color:rgb(70,126,183);font-weight:bold">in </span><span style="color:rgb(136,136,198)">range</span>(<span style="color:rgb(104,151,187)">1000</span>)]<br>smooth_signal = <span style="color:rgb(136,136,198)">list</span>(<span style="color:rgb(204,120,51)">exponential_moving_averag<wbr>e</span>(signal<span style="color:rgb(204,120,50)">, </span><span style="color:rgb(170,73,38)">decay</span>=<span style="color:rgb(104,151,187)">0.05</span>))</pre></pre></pre></div></div></blockquote></div></span>I wrote in this mail list the very same proposal some time ago. I was trying to let the scan higher order function (itertools.accumulate with a lambda, or what was done in the example above) fit into a simpler list comprehension.<br><br>As a result, I wrote this project, that adds the "scan" feature to Python comprehensions using a decorator that performs bytecode manipulation (and it had to fit in with a valid Python syntax): <a href="https://github.com/danilobellini/pyscanprev" target="_blank">https://github.com/danilobelli<wbr>ni/pyscanprev</a><br></div><div class="gmail_extra"></div><div class="gmail_extra"><br>In that GitHub page I've wrote several examples and a rationale on why this would be useful.<span class="gmail-m_-7145660737251500606m_-5774532688697618044gmail-HOEnZb"><font color="#888888"><br clear="all"></font></span></div><span class="gmail-m_-7145660737251500606m_-5774532688697618044gmail-HOEnZb"><font color="#888888"><div class="gmail_extra"><br>-- <br><div class="gmail-m_-7145660737251500606m_-5774532688697618044gmail-m_2664081634496065719m_-7844121854541913432m_-9143691218472671942gmail_signature">Danilo J. S. Bellini<br>---------------<br>"<i>It is not our business to set up prohibitions, but to arrive at conventions.</i>" (R. Carnap)<br></div>
</div></font></span></div>
</blockquote></div><br></div></div>