Re: Changing functions in a running program?

Wes Turner <[email protected]> Mon, 14 Jan 2019 11:02:38 -0500
Newsgroups gmane.comp.python.ipython.devel
Message-ID <CACfEFw8CbR7eSHjrCO2S22ZWDSCS01UBXDwhWLVnhKdPU7TEDw@mail.gmail.com>
--===============5637552339382613834==
Content-Type: multipart/alternative; boundary="0000000000009c41c0057f6d2c39"

--0000000000009c41c0057f6d2c39
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

There are likely more convenient patterns for a functionally composed
signal processing pipeline; though ipdb may be good enough.
https://pypi.org/project/pdbpp/ supports {tab-completion,}

Decomposing to functions that accept state with a standard interface like
{data: [], kwargs: {}} may have advantages.
You can assign the output of one step of the pipeline to a global; or, more
ideally, a key of a dict (or an attribute of a class instance); so you
don't need to modify globals() from a different scope.

The Jupyter notebook way to do this would be to put the first processing
stage in one cell, and then work with it in the next. e g. Spyder and
VSCode support markers in Python sources so that you can execute a
top-level block of code at a time.

I'm not too familiar with signal processing. Someone has likely already
distilled the workflow into some standard interfaces like
sklearn.pipeline.Pipeline.steps?
https://scikit-learn.org/stable/modules/compose.html#pipeline

/q=3D"scikit signal"
- scipy.signal
- scikit-signal

/q=3D"python signal processing"
- http://greenteapress.com/thinkdsp/html/
- https://github.com/unpingco/Python-for-Signal-Processing (ipynb)



# This logs IPython input and output to a file;
# but not ipdb i/o AFAIU
%logstart -o example.py
%logstart -h

To avoid logging code that modifies globals(),
it's probably better and more convenient to pass print_name as an argument
to name():

def name(print_name=3Dprint_name):
    print_name()

With a config dict/object:

def name(conf):
    print_name =3D conf['print_name']
    print_name(conf['data'])


On Monday, January 14, 2019, Andreas Yankopolus <[email protected]> wrote:

> Thomas,
>
> If you define a function or variable at the breakpoint, it's
> probably making it a local variable inside main(), so it's not in scope f=
or
> name().
>
> You may be able to get round this by defining the new function and
> then explicitly making it a global variable, something like this:
>
> globals()['print_name'] =3D print_name
>
> Not exactly elegant, but hopefully it works.
>
>
> Yes=E2=80=94makes sense and does the trick! I=E2=80=99ll have to figure o=
ut an Emacs hook
> to automatically update globals in that manner. My output:
>
> In main.
> > /Users/ayank/Documents/programming/python/bar.py(13)main()
>      12     import ipdb; ipdb.set_trace()
> ---> 13     name()
>      14
>
> ipdb> name()
> Alice
> ipdb> !def print_name(): print ("Bob")
> ipdb> name()
> Alice
> ipdb> globals()['print_name'] =3D print_name
> ipdb> name()
> Bob
> ipdb>
>
> To follow up on Wes=E2=80=99s comment regarding TDD=E2=80=94I=E2=80=99m w=
riting signal processing
> code and using Python + SciPy like Matlab. There are some calculations wh=
en
> the code starts that take a few minutes. I have a breakpoint there and am
> experimenting with the next steps of the processing chain.
>

--0000000000009c41c0057f6d2c39
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

There are likely more convenient patterns for a functionally composed signa=
l processing pipeline; though ipdb may be good enough.<div><a href=3D"https=
://pypi.org/project/pdbpp/">https://pypi.org/project/pdbpp/</a> supports {t=
ab-completion,}<br></div><div><br></div><div>Decomposing to functions that =
accept state with a standard interface like {data: [], kwargs: {}} may have=
 advantages.</div><div>You can assign the output of one step of the pipelin=
e to a global; or, more ideally, a key of a dict (or an attribute of a clas=
s instance); so you don&#39;t need to modify globals() from a different sco=
pe.</div><div><br></div><div>The Jupyter notebook way to do this would be t=
o put the first processing stage in one cell, and then work with it in the =
next. e g. Spyder and VSCode support markers in Python sources so that you =
can execute a top-level block of code at a time.</div><div><br></div><div>I=
&#39;m not too familiar with signal processing. Someone has likely already =
distilled the workflow into some standard interfaces like sklearn.pipeline.=
Pipeline.steps?</div><div><a href=3D"https://scikit-learn.org/stable/module=
s/compose.html#pipeline">https://scikit-learn.org/stable/modules/compose.ht=
ml#pipeline</a><br></div><div><br></div><div>/q=3D&quot;scikit signal&quot;=
</div><div>- scipy.signal</div><div>- scikit-signal</div><div><br></div><di=
v>/q=3D&quot;python signal processing&quot;<br></div><div>-=C2=A0<a href=3D=
"http://greenteapress.com/thinkdsp/html/">http://greenteapress.com/thinkdsp=
/html/</a></div><div>-=C2=A0<a href=3D"https://github.com/unpingco/Python-f=
or-Signal-Processing">https://github.com/unpingco/Python-for-Signal-Process=
ing</a> (ipynb)</div><div><br></div><div><br></div><div><br></div><div># Th=
is logs IPython input and output to a file;</div><div># but not ipdb i/o AF=
AIU</div><div>%logstart -o example.py</div><div>%logstart -h</div><div><br>=
</div><div>To avoid logging code that modifies globals(),</div><div>it&#39;=
s probably better and more convenient to pass print_name as an argument to =
name():</div><div><br></div><div>def name(print_name=3Dprint_name):</div><d=
iv>=C2=A0 =C2=A0 print_name()</div><div><br></div><div>With a config dict/o=
bject:</div><div><br></div><div>def name(conf):</div><div>=C2=A0 =C2=A0 pri=
nt_name =3D conf[&#39;print_name&#39;]</div><div>=C2=A0 =C2=A0 print_name(c=
onf[&#39;data&#39;])</div><div><br></div><div><br>On Monday, January 14, 20=
19, Andreas Yankopolus &lt;<a href=3D"mailto:[email protected]">andreas@yank.=
to</a>&gt; wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 =
0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap=
:break-word;line-break:after-white-space">Thomas,<br><div><br></div><div><b=
lockquote type=3D"cite"><div><div>If you define a function or variable at t=
he breakpoint, it&#39;s probably=C2=A0making it a local variable inside mai=
n(), so it&#39;s not in scope for name().<br><br>You may be able to get rou=
nd this by defining the new function and then=C2=A0explicitly making it a g=
lobal variable, something like this:<br><br>globals()[&#39;print_name&#39;]=
 =3D print_name<br><br>Not exactly elegant, but hopefully it works.<br></di=
v></div></blockquote><div><br></div><div>Yes=E2=80=94makes sense and does t=
he trick! I=E2=80=99ll have to figure out an Emacs hook to automatically up=
date globals in that manner. My output:</div><div><br></div><div><div style=
=3D"margin:0px;font-stretch:normal;font-size:11px;line-height:normal;font-f=
amily:Menlo">In main.</div><div style=3D"margin:0px;font-stretch:normal;fon=
t-size:11px;line-height:normal;font-family:Menlo;color:rgb(47,180,29)"><spa=
n style=3D"color:#000000">&gt; </span><span>/Users/ayank/Documents/<wbr>pro=
gramming/python/bar.py</span><span style=3D"color:#000000">(13)</span><span=
 style=3D"color:#2eaebb">m<wbr>ain</span><span style=3D"color:#400bd9">()</=
span></div><div style=3D"margin:0px;font-stretch:normal;font-size:11px;line=
-height:normal;font-family:Menlo"><span style=3D"color:#2fb41d">=C2=A0=C2=
=A0 =C2=A0 12 </span><span style=3D"color:#b42419">=C2=A0 =C2=A0 </span><sp=
an style=3D"color:#2fb41d">import</span><span> ipdb</span><span style=3D"co=
lor:#400bd9">;</span><span> ipdb</span><span style=3D"color:#400bd9">.</spa=
n><span>set_trace</span><span style=3D"color:#400bd9">()</span></div><div s=
tyle=3D"margin:0px;font-stretch:normal;font-size:11px;line-height:normal;fo=
nt-family:Menlo;color:rgb(47,180,29)"><span>---&gt; 13 </span><span style=
=3D"color:#b42419">=C2=A0 =C2=A0 </span><span style=3D"color:#000000">name<=
/span><span style=3D"color:#400bd9">()</span></div><div style=3D"margin:0px=
;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;co=
lor:rgb(47,180,29)"><span>=C2=A0=C2=A0 =C2=A0 14=C2=A0</span></div><div sty=
le=3D"margin:0px;font-stretch:normal;font-size:11px;line-height:normal;font=
-family:Menlo;min-height:13px"><span></span><br></div><div style=3D"margin:=
0px;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo=
"><span style=3D"color:#2d961e">ipdb&gt; </span><span>name()</span></div><d=
iv style=3D"margin:0px;font-stretch:normal;font-size:11px;line-height:norma=
l;font-family:Menlo"><span>Alice</span></div><div style=3D"margin:0px;font-=
stretch:normal;font-size:11px;line-height:normal;font-family:Menlo"><span s=
tyle=3D"color:#2d961e">ipdb&gt; </span><span>!def print_name(): print (&quo=
t;Bob&quot;)</span></div><div style=3D"margin:0px;font-stretch:normal;font-=
size:11px;line-height:normal;font-family:Menlo"><span style=3D"color:#2d961=
e">ipdb&gt; </span><span>name()</span></div><div style=3D"margin:0px;font-s=
tretch:normal;font-size:11px;line-height:normal;font-family:Menlo"><span>Al=
ice</span></div><div style=3D"margin:0px;font-stretch:normal;font-size:11px=
;line-height:normal;font-family:Menlo"><span style=3D"color:#2d961e">ipdb&g=
t; </span><span>globals()[&#39;print_name&#39;] =3D print_name</span></div>=
<div style=3D"margin:0px;font-stretch:normal;font-size:11px;line-height:nor=
mal;font-family:Menlo"><span style=3D"color:#2d961e">ipdb&gt; </span><span>=
name()</span></div><div style=3D"margin:0px;font-stretch:normal;font-size:1=
1px;line-height:normal;font-family:Menlo"><span>Bob</span></div><div style=
=3D"margin:0px;font-stretch:normal;font-size:11px;line-height:normal;font-f=
amily:Menlo;color:rgb(45,150,30)"><span>ipdb&gt;=C2=A0</span></div><div><sp=
an><br></span></div><div>To follow up on Wes=E2=80=99s comment regarding TD=
D=E2=80=94I=E2=80=99m writing signal processing code and using Python + Sci=
Py like Matlab. There are some calculations when the code starts that take =
a few minutes. I have a breakpoint there and am experimenting with the next=
 steps of the processing chain.</div></div></div></div></blockquote></div>

--0000000000009c41c0057f6d2c39--

--===============5637552339382613834==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
IPython-dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/ipython-dev

--===============5637552339382613834==--