<div dir="ltr">To give this old horse a kick: The "given" syntax in the recent thread could give a nice solution for the problem that started this thread.<div><br></div><div>Instead of my proposal of:</div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;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;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"> smooth_signal = [average := (1-decay)*average + decay*x for x in signal from average=0.]</span><br><div><br></div><div>We could use given for both the in-loop variable update and the variable initialization:</div><div> <span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;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;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">smooth_signal =<span> </span></span> [<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;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;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">average</span> given <span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;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;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">average</span>=(1-decay)*<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;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;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">average</span> + decay*x for x in signal]<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;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;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span> </span>given<span> </span></span><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;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;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial;background-color:rgb(255,255,255);float:none;display:inline">average</span><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;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;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">=0.</span></div></div><div><br></div><div>This especially makes sense for the extended syntax, where my proposal of:</div><div><div> (z, y := f(z, x) -> y for x in iter_x from z=initial_z)</div></div><div><br></div><div>Becomes: </div><div> <span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;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;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">(y given z, y = f(z, x) for x in iter_x)<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;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;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span> </span>given z=initial_z</span></span></div><div> </div><div>So in stead of adding 2 symbols and a keyword, we just need to add the one "given" keyword.</div><div><br></div><div>It's worth noting, as Serhiy pointed out, that this is already supported in python, albeit with a very clunky syntax:</div><div><br></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:12.8px;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;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"> smooth_signal = [average for average in [0] for x in signal </span><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:12.8px;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;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">for average in [(1-decay)*average + decay*x]]</span></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:12.8px;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;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><br></span></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:12.8px;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;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;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;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial"><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:12.8px;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;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"> </span><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;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;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">(y for <span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;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;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">z in [initial_z] </span>for x in iter_x for z, y in [<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;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;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">f(z, x)]</span>)</span><br></div><br class="gmail-Apple-interchange-newline"></span></div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Apr 17, 2018 at 12:02 AM, 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:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="">On 16 April 2018 at 10:49, 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"><div>Are you able to show how you'd implement the moving average example with your package?</div></div></blockquote><div><br></div></span><div>Sure! The single pole IIR filter you've shown is implemented here:<br><a href="https://github.com/danilobellini/pyscanprev/blob/master/examples/iir-filter.rst" target="_blank">https://github.com/<wbr>danilobellini/pyscanprev/blob/<wbr>master/examples/iir-filter.rst</a><br><br></div><span class=""><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>I tried: </div><div><br></div><div><div> @enable_scan("average")</div><div> def exponential_moving_average_pys<wbr>can(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_averag<wbr>e_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. <br></div><span class="m_-62524338134017710gmail-HOEnZb"><font color="#888888"></font></span></div></blockquote><div><br></div></span><div>I'm not sure what you were expecting. A sentinel as the first "average" value?<br><br>Before the loop begins, this scan-generator just echoes the first input, like itertools.accumulate.<br>That is, the first value this generator yields is the first "signal" value, which is then the first "average" value.<br></div><br>To put an initial memory state, you should do something like this (I've removed the floating point trailing noise):<br><div><br></div><div><span style="font-family:monospace,monospace">>>> from pyscanprev import enable_scan, prepend<br></span></div><div><span style="font-family:monospace,monospace">>>><br></span></div><div><div><span style="font-family:monospace,monospace">>>> @enable_scan("y")</span></div><div><span style="font-family:monospace,monospace">>>> def iir_filter(signal, decay, memory=0):<br></span></div><div><span style="font-family:monospace,monospace">... return ((1 - decay) * y + decay * x for x in prepend(memory, signal))<br><div><span style="font-family:monospace,monospace">...<br>>>> list(iir_filter([1, 2, 3, 2, 1, -1, -2], decay=.1, memory=5))<br>[5, 4.6, 4.34, 4.206, 3.9854, 3.68686, 3.218174, 2.6963566]<br><br></span></div><div><div><span style="font-family:monospace,monospace"></span></div></div></span></div></div></div>In that example, "<span style="font-family:monospace,monospace">y"</span> is the "previous result" (a.k.a. accumulator, or what had been called "<span style="font-family:monospace,monospace">average</span>" here).<br></div><span class=""><div class="gmail_extra"><br>--<br><div class="m_-62524338134017710gmail_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></span></div>
</blockquote></div><br></div>