Python on background for data analyst track

kirby urner <[email protected]> Wed, 1 Mar 2023 08:51:06 -0800
Newsgroups gmane.comp.python.education
Message-ID <CAPJgG3QKs-OSmckwDWtd0iw2bYQF6De+B9qqkX5B5mFpkKqw6A@mail.gmail.com>
--===============6504232866710720884==
Content-Type: multipart/alternative; boundary="0000000000006fefbe05f5d98578"

--0000000000006fefbe05f5d98578
Content-Type: text/plain; charset="UTF-8"

As some of us will have experienced, quite a few budding data analysts in
training will come to Python via numpy and pandas, heading towards seaborn
and dash, perhaps from past experience in R or Matlab, perhaps not.

They've never yet had a core Python class, but are likely to have one in
the near future, if they decide to stay within the Python ecosystem and/or
stick with data science.

I've got such a cohort coming my way and thought this time I would develop
some more explicit background content on Python, the core language, which
I'm calling "warm-up notebooks" and so far doing in Jupyter.

https://github.com/4dsolutions/clarusway_data_analysis/tree/main/python_warm_up

Here are some pedagogical features I incorporate that might be of interest
to others in a similar position of needing to develop curriculum:

1.  mention numpy and pandas early

There's nothing conceptually that hard about a rectangle of numbers,
addressable by row and column.  The mechanisms of installing 3rd party
packages may be addressed.

Introduce range, then why not arange and linspace for compare and contrast
purposes.

I go straight to numpy and pandas in notebook 2.  To see the sequence, see
here (home base for the class):

https://github.com/4dsolutions/clarusway_data_analysis/blob/main/DAwPy_S1_(Numpy_Arrays)/daily_schedule.ipynb

I'm still adding notebooks.

2.  functions are just another type of object

In exploring the various built-in types, with Python allowing us to make
new types, it becomes useful to see individual functions as instances of
the function type, where list, tuple, int, str.... function are all
built-in types.

We don't use keyword class to define a function, but keyword def (or maybe
lambda).

What makes function instances stand out is they're callable.  But so are
instances of classes implementing __call__.

[1] def f(x):
        return x * x  # return x times itself

[2] type(f)
function

[3] issubclass(type(f), object)
True

[4] isinstance(f, type(f))
True

3.  Use "composition of functions" to motivate drive a decorator syntax
intro

I've been doing this for a while now.  Most students will remember
composition of functions from high school, and if not, it's an easy concept.

def f(x):
    return 2 * x

def g(x):
    return x**2


print("f after g:", f(g(arg)))
print("g after f:", g(f(arg)))

Output:
f after g: 200
g after f: 400

What's not so easy, an may require active tutoring, is passing a function
into Composer type like this:

# where decorator syntax will come in handy
f = Composer(f)
g = Composer(g)

print("f after g:", (f * g)(arg))
print("g after f:", (g * f)(arg))

Output (same answers):
f after g: 200
g after f: 400

In other words, we repurpose the __mul__ operator (*) to become the compose
operator, which in LaTeX is usually \circ.

Kirby

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

<div dir=3D"ltr"><div class=3D"gmail_default" style=3D"font-family:arial,he=
lvetica,sans-serif;font-size:small"><br></div><div class=3D"gmail_default" =
style=3D"font-family:arial,helvetica,sans-serif;font-size:small"><br></div>=
<div class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-seri=
f;font-size:small">As some of us will have experienced, quite a few budding=
 data analysts in training will come to Python via numpy and pandas, headin=
g towards seaborn and dash, perhaps from past experience in R or Matlab, pe=
rhaps not.=C2=A0 <br></div><div class=3D"gmail_default" style=3D"font-famil=
y:arial,helvetica,sans-serif;font-size:small"><br></div><div class=3D"gmail=
_default" style=3D"font-family:arial,helvetica,sans-serif;font-size:small">=
They&#39;ve never yet had a core Python class, but are likely to have one i=
n the near future, if they decide to stay within the Python ecosystem and/o=
r stick with data science.</div><div class=3D"gmail_default" style=3D"font-=
family:arial,helvetica,sans-serif;font-size:small"><br></div><div class=3D"=
gmail_default" style=3D"font-family:arial,helvetica,sans-serif;font-size:sm=
all">I&#39;ve got such a cohort coming my way and thought this time I would=
 develop some more explicit background content on Python, the core language=
, which I&#39;m calling &quot;warm-up notebooks&quot; and so far doing in J=
upyter.</div><div class=3D"gmail_default" style=3D"font-family:arial,helvet=
ica,sans-serif;font-size:small"><br></div><div class=3D"gmail_default" styl=
e=3D"font-family:arial,helvetica,sans-serif;font-size:small"><a href=3D"htt=
ps://github.com/4dsolutions/clarusway_data_analysis/tree/main/python_warm_u=
p">https://github.com/4dsolutions/clarusway_data_analysis/tree/main/python_=
warm_up</a></div><div class=3D"gmail_default" style=3D"font-family:arial,he=
lvetica,sans-serif;font-size:small"><br></div><div class=3D"gmail_default" =
style=3D"font-family:arial,helvetica,sans-serif;font-size:small">Here are s=
ome pedagogical features I incorporate that might be of interest to others =
in a similar position of needing to develop curriculum:<br></div><div class=
=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-serif;font-siz=
e:small"><br></div><div class=3D"gmail_default" style=3D"font-family:arial,=
helvetica,sans-serif;font-size:small">1.=C2=A0 mention numpy and pandas ear=
ly</div><div class=3D"gmail_default" style=3D"font-family:arial,helvetica,s=
ans-serif;font-size:small"><br></div><div class=3D"gmail_default" style=3D"=
font-family:arial,helvetica,sans-serif;font-size:small">There&#39;s nothing=
 conceptually that hard about a rectangle of numbers, addressable by row an=
d column.=C2=A0 The mechanisms of installing 3rd party packages may be addr=
essed.</div><div class=3D"gmail_default" style=3D"font-family:arial,helveti=
ca,sans-serif;font-size:small"><br></div><div class=3D"gmail_default" style=
=3D"font-family:arial,helvetica,sans-serif;font-size:small">Introduce range=
, then why not arange and linspace for compare and contrast purposes.=C2=A0=
 <br></div><div class=3D"gmail_default" style=3D"font-family:arial,helvetic=
a,sans-serif;font-size:small"><br></div><div class=3D"gmail_default" style=
=3D"font-family:arial,helvetica,sans-serif;font-size:small">I go straight t=
o numpy and pandas in notebook 2.=C2=A0 To see the sequence, see here (home=
 base for the class):</div><div class=3D"gmail_default" style=3D"font-famil=
y:arial,helvetica,sans-serif;font-size:small"><br></div><div class=3D"gmail=
_default" style=3D"font-family:arial,helvetica,sans-serif;font-size:small">=
<a href=3D"https://github.com/4dsolutions/clarusway_data_analysis/blob/main=
/DAwPy_S1_(Numpy_Arrays)/daily_schedule.ipynb">https://github.com/4dsolutio=
ns/clarusway_data_analysis/blob/main/DAwPy_S1_(Numpy_Arrays)/daily_schedule=
.ipynb</a></div><div class=3D"gmail_default" style=3D"font-family:arial,hel=
vetica,sans-serif;font-size:small"><br></div><div class=3D"gmail_default" s=
tyle=3D"font-family:arial,helvetica,sans-serif;font-size:small">I&#39;m sti=
ll adding notebooks.<br></div><div class=3D"gmail_default" style=3D"font-fa=
mily:arial,helvetica,sans-serif;font-size:small"><br></div><div class=3D"gm=
ail_default" style=3D"font-family:arial,helvetica,sans-serif;font-size:smal=
l">2.=C2=A0 functions are just another type of object</div><div class=3D"gm=
ail_default" style=3D"font-family:arial,helvetica,sans-serif;font-size:smal=
l"><br></div><div class=3D"gmail_default" style=3D"font-family:arial,helvet=
ica,sans-serif;font-size:small">In exploring the various built-in types, wi=
th Python allowing us to make new types, it becomes useful to see individua=
l functions as instances of the function type, where list, tuple, int, str.=
... function are all built-in types.</div><div class=3D"gmail_default" styl=
e=3D"font-family:arial,helvetica,sans-serif;font-size:small"><br></div><div=
 class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-serif;fo=
nt-size:small">We don&#39;t use keyword class to define a function, but key=
word def (or maybe lambda).=C2=A0 <br></div><div class=3D"gmail_default" st=
yle=3D"font-family:arial,helvetica,sans-serif;font-size:small"><br></div><d=
iv class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-serif;=
font-size:small">What makes function instances stand out is they&#39;re cal=
lable.=C2=A0 But so are instances of classes implementing __call__.</div><d=
iv class=3D"gmail_default" style=3D"font-size:small"><span style=3D"font-fa=
mily:monospace"><br></span></div><div class=3D"gmail_default" style=3D"font=
-size:small"><span style=3D"font-family:monospace">[1] def f(x):<br>=C2=A0 =
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return x * x =C2=A0# return x times itself</=
span></div><div class=3D"gmail_default" style=3D"font-size:small"><span sty=
le=3D"font-family:monospace"><br></span></div><div class=3D"gmail_default" =
style=3D"font-size:small"><span style=3D"font-family:monospace">[2] type(f)=
</span></div><div class=3D"gmail_default" style=3D"font-size:small"><span s=
tyle=3D"font-family:monospace">function</span></div><div class=3D"gmail_def=
ault" style=3D"font-size:small"><span style=3D"font-family:monospace"><br><=
/span></div><div class=3D"gmail_default" style=3D"font-size:small"><span st=
yle=3D"font-family:monospace">[3] issubclass(type(f), object)</span></div><=
div class=3D"gmail_default" style=3D"font-size:small"><span style=3D"font-f=
amily:monospace">True</span></div><div class=3D"gmail_default" style=3D"fon=
t-size:small"><span style=3D"font-family:monospace"><br></span></div><div c=
lass=3D"gmail_default" style=3D"font-size:small"><span style=3D"font-family=
:monospace">[4] isinstance(f, type(f))</span></div><div class=3D"gmail_defa=
ult" style=3D"font-family:arial,helvetica,sans-serif;font-size:small"><span=
 style=3D"font-family:monospace">True</span></div><div class=3D"gmail_defau=
lt" style=3D"font-family:arial,helvetica,sans-serif;font-size:small"><br></=
div><div class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-=
serif;font-size:small">3.=C2=A0 Use &quot;composition of functions&quot; to=
 motivate drive a decorator syntax intro</div><div class=3D"gmail_default" =
style=3D"font-family:arial,helvetica,sans-serif;font-size:small"><br></div>=
<div class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-seri=
f;font-size:small">I&#39;ve been doing this for a while now.=C2=A0 Most stu=
dents will remember composition of functions from high school, and if not, =
it&#39;s an easy concept.</div><div class=3D"gmail_default" style=3D"font-s=
ize:small"><span style=3D"font-family:monospace"><br></span></div><div clas=
s=3D"gmail_default" style=3D"font-size:small"><span style=3D"font-family:mo=
nospace">def f(x):</span></div><div class=3D"gmail_default" style=3D"font-s=
ize:small"><span style=3D"font-family:monospace">=C2=A0=C2=A0=C2=A0 return =
2 * x</span></div><div class=3D"gmail_default" style=3D"font-size:small"><s=
pan style=3D"font-family:monospace"><br></span></div><div class=3D"gmail_de=
fault" style=3D"font-size:small"><span style=3D"font-family:monospace">def =
g(x):</span></div><div class=3D"gmail_default" style=3D"font-family:arial,h=
elvetica,sans-serif;font-size:small"><span style=3D"font-family:monospace">=
=C2=A0=C2=A0=C2=A0 return x**2</span><br></div><div class=3D"gmail_default"=
 style=3D"font-family:arial,helvetica,sans-serif;font-size:small"><br></div=
><div class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-ser=
if;font-size:small"><br></div><span style=3D"font-family:monospace">print(&=
quot;f after g:&quot;, f(g(arg)))<br>print(&quot;g after f:&quot;, g(f(arg)=
))</span><div class=3D"gmail_default" style=3D"font-size:small"><span style=
=3D"font-family:monospace"><br></span></div><div class=3D"gmail_default" st=
yle=3D"font-size:small"><span style=3D"font-family:monospace">Output:<br></=
span></div><div class=3D"gmail_default" style=3D"font-size:small"><span sty=
le=3D"font-family:monospace">f after g: 200<br>g after f: 400</span></div><=
div class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-serif=
;font-size:small"><br></div><div class=3D"gmail_default" style=3D"font-fami=
ly:arial,helvetica,sans-serif;font-size:small">What&#39;s not so easy, an m=
ay require active tutoring, is passing a function into Composer type like t=
his:</div><div class=3D"gmail_default" style=3D"font-family:arial,helvetica=
,sans-serif;font-size:small"><br></div><div class=3D"gmail_default" style=
=3D"font-size:small"><span style=3D"font-family:monospace"># where decorato=
r syntax will come in handy<br></span></div><div class=3D"gmail_default" st=
yle=3D"font-size:small"><span style=3D"font-family:monospace">f =3D Compose=
r(f)</span></div><div class=3D"gmail_default" style=3D"font-size:small"><sp=
an style=3D"font-family:monospace">g =3D Composer(g)</span></div><div class=
=3D"gmail_default" style=3D"font-size:small"><span style=3D"font-family:mon=
ospace"><br></span></div><span style=3D"font-family:monospace">print(&quot;=
f after g:&quot;, (f * g)(arg))<br></span><div><span style=3D"font-family:m=
onospace">print(&quot;g after f:&quot;, (g * f)(arg))</span></div><div><spa=
n style=3D"font-family:monospace"><br></span></div><div><span style=3D"font=
-family:monospace">Output<span class=3D"gmail_default" style=3D"font-size:s=
mall"> (same answers)</span>:</span></div><div><span style=3D"font-family:m=
onospace">f after g: 200<br>g after f: 400</span></div><div class=3D"gmail_=
default" style=3D"font-family:arial,helvetica,sans-serif;font-size:small"><=
br></div><div class=3D"gmail_default" style=3D"font-family:arial,helvetica,=
sans-serif;font-size:small">In other words, we repurpose the __mul__ operat=
or (*) to become the compose operator, which in LaTeX is usually \circ.</di=
v><div class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-se=
rif;font-size:small"><br></div><div class=3D"gmail_default" style=3D"font-f=
amily:arial,helvetica,sans-serif;font-size:small">Kirby</div><div class=3D"=
gmail_default" style=3D"font-family:arial,helvetica,sans-serif;font-size:sm=
all"><br></div></div>

--0000000000006fefbe05f5d98578--

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

_______________________________________________
Edu-sig mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/edu-sig.python.org/
Member address: [email protected]

--===============6504232866710720884==--