Christalee Bieber - Teal Labs, Inc./2023-10-07T00:00:00-04:00deploying with github actions2023-10-07T00:00:00-04:002023-10-07T00:00:00-04:00Christalee Biebertag:None,2023-10-07:/posts/deploying-with-github-actions.html<p>Last week I updated my blog for the first time in a long time - so long that I had forgotten exactly how to run and build it. (<code>pelican -rl content</code> is the right answer for my current directory structure.) Once I figured that out, I wrote my post and figured …</p><p>Last week I updated my blog for the first time in a long time - so long that I had forgotten exactly how to run and build it. (<code>pelican -rl content</code> is the right answer for my current directory structure.) Once I figured that out, I wrote my post and figured it was smooth sailing from there. Alas, recently GitHub Pages has changed from its "classic" workflow of deploying from a specified branch, to some GitHub Actions-based workflow. I can't exactly figure out what's going on, but I know it uses Jekyll, which my site doesn't use. So I had to look into a custom Github Actions workflow to make my site go.</p>
<p>Initially I thought I could just use a <a href="https://github.com/actions/starter-workflows/blob/main/pages/static.yml">static workflow</a> since I already had the site build artifacts in <code>/output</code>. But for some reason this wouldn't work. I eventually realized I had to switch my site settings to use Source: GitHub Actions. I also wanted to upload only the <code>/output</code> directory, not my entire repo, so I changed around my directory structure; previously I had my pelican conf and content in a <code>/pelican</code> folder and routed build output to the top-level directory. Now I have pelican conf and <code>/content</code> and <code>/output</code> all at the top level. After that, I simply needed to specify the <code>/output</code> directory in the <code>static.yml</code> script, for the step where it packages up the build artifacts.</p>
<p>I also looked into using one of the <a href="https://github.com/marketplace?category=&type=actions&verification=&query=pelican">several Pelican build Actions</a> in the Marketplace. But reading through what they actually do, I noticed that they built the site in a container and ultimately pushed the artifacts to a branch, relying on the classic GH pages deployment behavior - no improvement over my current status. Looking around a bit more, I see now that when writing a workflow, I can insert shell commands directly with <code>runs:</code> , I'm not only restricted to using actions (<code>uses:</code>), so that is a path I might explore in the future. But for now, my blog works and I'm not inclined to mess with it. 🥳</p>the joy of react2023-10-02T00:00:00-04:002023-10-02T00:00:00-04:00Christalee Biebertag:None,2023-10-02:/posts/the-joy-of-react.html<p>I've recently started some PD at work with <a href="https://www.joyofreact.com/">The Joy of React</a>, a course by React maven Josh Comeau. It promises to teach me not just the basics but also some "happy practices" (hedging on "best practices") that I'm expected to bring back to my daily practice. Several of my …</p><p>I've recently started some PD at work with <a href="https://www.joyofreact.com/">The Joy of React</a>, a course by React maven Josh Comeau. It promises to teach me not just the basics but also some "happy practices" (hedging on "best practices") that I'm expected to bring back to my daily practice. Several of my coworkers have joined, mostly backend devs who want to expand their skills (being on a full-stack team).</p>
<p>Since I haven't written in this blog since starting work, basically, I should probably describe what I do. I work at a health tech startup, building reasonable interfaces for a complex, data-rich system. After focusing on our page that summarizes all the available information for a specific patient (in digital and print!), I've shifted into rebuilding that view, optimized now for being rendered responsively in an iframe inside a medical records program. We're targeting Epic first, but hoping to extend our work to other EMRs without much additional work. This work relies on open protocols like OAuth and SMART on FHIR, but I haven't had to grapple much with that. Primarily I've been doing the React side, pulling together action items and presenting them to the provider to be filled out. (We hope to minimize dual documentation in a future project.)</p>
<p>Taking this Joy of React course, so far I am reminded not to take anything for granted - just because I use React every day, doesn't mean I have nothing to learn! Some of it is down to differences in our codebase - for example, we use <a href="https://styled-components.com/">styled-components</a> while the course uses <a href="https://github.com/css-modules/css-modules">CSS Modules</a>. A recent lesson on forms was frustrating because we use a library / base components for forms instead of the raw HTML elements, so I don't remember the syntax of regular forms particularly well. But I'm moving along with it, in my downtime. My goals look something like:</p>
<ul>
<li>get a model of how to design complex state without drowning (we have some complex components in our codebase, primarily because everyone was focused on adding one more feature and never stepped back to say, is it time to refactor now?)</li>
<li>gain confidence in my ability to design my own hooks (this is more about error handling and possibly working with Promises)</li>
<li>understand better how to organize functions and components for readability and ease-of-use</li>
</ul>
<p>Hopefully I'll learn these lessons and find opportunities to apply them straightforwardly.</p>rc-niceties2021-06-25T00:00:00-04:002021-06-25T00:00:00-04:00Christalee Biebertag:None,2021-06-25:/posts/rc-niceties.html<p>A frequent comment about the Recurse Center is "everyone here is so nice!" Perhaps due to careful admissions, or the <a href="https://www.recurse.com/manual#sub-sec-social-rules">social rules</a>, RC participants strive to keep it a supportive community where people are open to others: working together, communicating carefully, and respecting each other. One mechanism for building the …</p><p>A frequent comment about the Recurse Center is "everyone here is so nice!" Perhaps due to careful admissions, or the <a href="https://www.recurse.com/manual#sub-sec-social-rules">social rules</a>, RC participants strive to keep it a supportive community where people are open to others: working together, communicating carefully, and respecting each other. One mechanism for building the community is Niceties, a periodic opportunity to give compliments about your fellow Recursers. Typically calls go out for Niceties in the last week of a batch, and each participant has one Nicety read aloud at their Never Graduate ceremony on Friday.</p>
<p>Currently Niceties are administered through a Google Form, but once upon a time, some Recursers wrote an app for them. It lives at niceties.recurse.com and when I first encountered it, it was closed. I thought this was a sorry state of affairs and responded to a "good-first-issue" with a pull request, adding a note to the front page that the site was down. I'd been looking for an open source project to contribute to, and this seemed like a good candidate, so I tackled a few more issues. Luckily one of the maintainers, <a href="https://github.com/jasonaowen">@jasonaowen</a>, welcomed me to the project with helpful suggestions and an agreement to review my PRs. We set up a weekly meeting where we could prioritize issues, brainstorm together, and pair on tricky bits of code. This has been invaluable for me in learning to collaborate with other programmers, and helped me make slow but steady progress that really contrasts with the faster pace of a project where I'm the sole designer and programmer. I've figured out a reasonable git workflow and even juggled some tricky <code>git rebase -i</code> situations.</p>
<p>You would think that an app for saying nice things about people would be straightforward, but it's surprisingly complex in the edge cases. Some of the complexity comes from the fact that the app automatically calculates which users should be shown on the screen at a time, but users can change their batch membership at any time, by extending from 6 to 12 weeks or signing up for another 6 or 12 week stint at RC. Should a user who extends their batch be shown twice? Niceties are stored in the database with a unique constraint of author-target-batch, so if we only show the user once, which batch should their data be listed under? The app has a view for the faculty to compile all the niceties for each recipient and print them out, but currently they are emailing them instead of handing out paper. And, of course, the codebase uses Flask on the backend and 2016-era React on the frontend, and bringing that code in line with modern practices is a task all on its own. The app relies on queries to the RC API, which has been revised since the app was written, so those requests needed updating as well.</p>
<p>Most of the work I've done on rc-niceties has been towards fixing bugs, introducing a database migration scheme so we can make changes to the DB, and refactoring the frontend so we can upgrade React. Recently we had a lovely feedback session with some RC faculty to clarify use-cases and prioritize next steps. rc-niceties has one more round of DB schema changes and bug squashing before it's ready for re-opening, and I'm happy to say that @jasonaowen and I have recruited another Recurser, <a href="https://github.com/tas09009">@tas09009</a>, to work on it. I look forward to having the app working again and bringing joy to my community. (cf.<a href="https://joy.recurse.com/">Joy of Computing</a>)</p>Outreachy2021-04-25T00:00:00-04:002021-04-25T00:00:00-04:00Christalee Biebertag:None,2021-04-25:/posts/outreachy.html<p>Last month I applied to <a href="https://www.outreachy.org/">Outreachy</a>, a paid internship for non-students from underrepresented groups in technology. Instead of interviewing based on your resume, part of the application involves making a contribution to the open source project you're hoping to work for. Since the internship employers tend to be big names …</p><p>Last month I applied to <a href="https://www.outreachy.org/">Outreachy</a>, a paid internship for non-students from underrepresented groups in technology. Instead of interviewing based on your resume, part of the application involves making a contribution to the open source project you're hoping to work for. Since the internship employers tend to be big names in open source (Apache, Red Hat, the Linux Foundation, Mozilla, Wikimedia) this can be a bit intimidating. The process is very well documented, however, and volunteer mentors are available to help you as you work.</p>
<p>I chose to submit two contributions to the Wikimedia Foundation, for two different projects of theirs. I appreciated that they carefully scaffolded the contribution process, asking every applicant to complete the same task, instead of just setting us free in the bug tracker. For large projects with many current and aspiring contributors, it can be tough to find a bug that's appropriate for a new programmer and claim it before someone else does, much less complete the work in a reasonable amount of time while following local conventions for contributors. I looked for such a thing with other projects and ultimately didn't find anything within the application timeframe. Luckily the Wikimedia application tasks were well-specified, the mentors were quite responsive, and the tasks themselves were right up my alley: writing Python to analyze data and teach others.</p>
<p>One contribution I made was part of a larger project to write tutorials and tools for users to explore Wikipedia datasets. The task required both writing Python to analyze and visualize the data, and strong technical writing to explain the problem and potential solutions. We started with a <a href="https://public.paws.wmcloud.org/User:Isaac_(WMF)/Outreachy%20Summer%202021/Wikipedia_Edit_Tags.ipynb">partial outline</a> and filled in the gaps, resulting in <a href="https://public.paws.wmcloud.org/User:Christalee_b/[Outreachy]%20Wikipedia%20Edit%20Tags.ipynb">a tutorial</a> aimed at users who want to investigate trends in Wikipedia edits.</p>
<p>Another contribution was for a project to build a tool to analyze how users navigate through Wikipedia, based on clickstream data. This task only required writing Python, although I ran into some challenges: the clickstream dataset is quite large, and using the idiomatic <code>if x in y</code> was prohibitively slow, so I wrote a little implementation of binary search to improve performance; and I initially couldn't figure out how to create a nice diagram showing clicks to and from an article. I started using <a href="https://networkx.org/documentation/stable/auto_examples/index.html"><code>networkx</code></a> but was dissatisfied with the results. Then a comment from another contributor turned me on to Sankey diagrams, and suggested <a href="https://plotly.com/python/">Plotly</a> as a way to graph them. I couldn't get Plotly to show up so I tried <a href="http://holoviews.org/gallery/index.html"><code>holoviews</code></a> and that worked great! I also used <code>pandas</code> a bit in this project, collecting Top 10 sources and destinations in English and German for a specific page, <code>Alan_Turing</code>. Check out the <a href="https://public.paws.wmcloud.org/User:Christalee_b/[Outreachy]%20Wikipedia%20Clickstream.ipynb">results</a>.</p>
<p>Working on these notebooks was pretty fun, although I spent more time than I should've. I don't anticipate budgeting that much time for other job app take-homes, for example. But I wanted to do a good job and give it my best shot, which turns out to be pretty decent. Hopefully the mentors will agree with me and I'll get an internship!</p>Cost of Drinking2021-02-25T00:00:00-05:002021-02-25T00:00:00-05:00Christalee Biebertag:None,2021-02-25:/posts/cost-of-drinking.html<p>When I started at the Recurse Center, I had several vague ideas of projects I wanted to work on. A throwaway comment on the price of beer in Budapest inspired me to see if beer could be used as a cost of living metric. The first maps I found polled …</p><p>When I started at the Recurse Center, I had several vague ideas of projects I wanted to work on. A throwaway comment on the price of beer in Budapest inspired me to see if beer could be used as a cost of living metric. The first maps I found polled a single city per country, typically the capital or largest city, which seemed unrepresentative: everyone knows the cost of living is high in New York, Tokyo, or London. So I wanted to gather data by city, average it across various sources, and map it. Since beer is not globally popular, though (in Saudi Arabia, it's illegal), I decided to expand my analysis to coffee, which is widely available even in non-coffee cultures, and bread, since everyone needs something to nibble on with their beer. (In my household, we make some of our beer and bake some of our bread; we do not roast our own coffee.)</p>
<p>I collaborated with <a href="https://github.com/apettenati">apettenati</a> on the data scraping (<a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/">Beautiful Soup</a>) and cleaning (<a href="https://pandas.pydata.org/">pandas</a>) phase. We split up our data sources: DeutscheBank's <a href="https://www.dbresearch.com/PROD/RPS_EN-PROD/Mapping_the_world_prices_2019/RPS_EN_DOC_VIEW.calias?rwnode=PROD0000000000436748&ProdCollection=PROD0000000000505140">survey of world prices</a>, <a href="https://www.expatistan.com/cost-of-living">Expatistan</a>, <a href="https://www.numbeo.com/cost-of-living/">Numbeo</a>, and <a href="http://www.pintprice.com/">PintPrice</a>. Initially I made a proof-of-concept map in <a href="https://python-visualization.github.io/folium/">folium</a>, but quickly realized I needed to switch to JavaScript, for a feature that restricted the number of markers based on the zoom level, to avoid overcrowding the map. So I tried <a href="https://leafletjs.com/">Leaflet.JS</a> and found it reasonably easy to work with. Folium had given me the idea for charts in popups, though, so I turned to <a href="https://www.chartjs.org/">Chart.JS</a> to create those. I'm still not entirely comfortable in JavaScript but this project was a major step forward in my understanding. The payoff of having a snazzy visualization was surprisingly motivational (in direct contrast to the data cleaning phase, which was tedious beyond belief but also essential.)</p>
<p>Check out the code on <a href="https://github.com/christalee/cost-of-drinking">Github</a> and the map itself <a href="/pages/cost-of-drinking.html">here</a>.</p>syntax highlighting & feeds2021-02-16T00:00:00-05:002021-02-16T00:00:00-05:00Christalee Biebertag:None,2021-02-16:/posts/syntax-highlighting-feeds.html<p>I haven't written much about the process of putting this blog together because I want it to speak for itself, but I wanted to write a short note about two features I added today. One was syntax highlighting, using pygment's 'friendly' theme. (Thanks to <a href="https://help.farbox.com/pygments.html">this gallery</a> for showing off the …</p><p>I haven't written much about the process of putting this blog together because I want it to speak for itself, but I wanted to write a short note about two features I added today. One was syntax highlighting, using pygment's 'friendly' theme. (Thanks to <a href="https://help.farbox.com/pygments.html">this gallery</a> for showing off the default themes!) It was not as straightforward as the docs suggested, in that I needed to generate or acquire a CSS file for my preferred theme. The results are visible in my previous post on PageRank. The first snippet specifies that python highlighting is needed, but the second snippet uses generic <code>```code```</code> syntax and seems to work just fine. (Python may be the default, come to think of it.)</p>
<p>The other update is that if you would like to subscribe to my blog, feeds are now available! There is an <a href="https://christalee.teallabs.org/feeds/rss.xml">RSS feed</a>, an <a href="https://christalee.teallabs.org/feeds/atom.xml">Atom feed</a>, plus <code>all.rss.xml</code> and <code>all.atom.xml</code> which are probably identical.</p>
<p>Bonus feature: previous and next links at the bottom of each post, as there are now enough that someone might want to browse through them!</p>PageRanking RC Zulip2021-02-15T00:00:00-05:002021-02-15T00:00:00-05:00Christalee Biebertag:None,2021-02-15:/posts/pageranking-rc-zulip.html<p>Over the past couple of weeks, I and some colleagues in the <em><a href="https://www.manning.com/books/mastering-large-datasets-with-python#toc">Mastering Large Datasets with Python</a></em> group have been practicing our new ability to scrape and process large amount of data with Spark, by harvesting public messages from the RC Zulip and analyzing them. (For those unfamiliar with <a href="https://zulip.com/">Zulip …</a></p><p>Over the past couple of weeks, I and some colleagues in the <em><a href="https://www.manning.com/books/mastering-large-datasets-with-python#toc">Mastering Large Datasets with Python</a></em> group have been practicing our new ability to scrape and process large amount of data with Spark, by harvesting public messages from the RC Zulip and analyzing them. (For those unfamiliar with <a href="https://zulip.com/">Zulip</a>, it's similar to Slack, with channels and mentions.) Although it doesn't quite qualify as "Big Data", the dataset contains ~800,000 messages, which is fodder for all sorts of questions about who posts, when, on what topics, etc. I've been focusing on implementing PageRank based on @mentions, following the book's example, and found it pretty straightforward once I performed some basic text cleanup.</p>
<figure class="figure-img">
<img src="/images/pr_top10_graph.png" />
<figcaption class="small">User ratings over 10 cycles of PageRanking</figcaption>
</figure>
<p>I gave a <a href="https://docs.google.com/presentation/d/1E4sh81x317Qfqi5LneRF4iFPndK_cO01H8_fatm3DvQ/edit?usp=sharing">short presentation</a> on Friday about the work done so far. Today I worked a bit on one of the next steps: a function to automatically stop the algorithm once it's run "long enough". Originally I was running it for 10 cycles, which I suspected was overkill. I started by generating a list of lists, containing the top 10 users and their ratings, for each cycle. After some massaging, I generated this graph, which shows the scores per user over time. Visual inspection suggests the ratings settle down after 4 cycles, but I'd like to calculate that directly, if possible.</p>
<p>I ended up writing a helper function that, given two sets of top 10 users and their ratings, first compares the users to ensure both sets are the same. If not, it returns one set of names. If so, it calculates the element-wise difference of the ratings and returns them.</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">compare10</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="n">names_a</span> <span class="o">=</span> <span class="p">[</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">a</span><span class="p">]</span>
<span class="n">names_b</span> <span class="o">=</span> <span class="p">[</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">b</span><span class="p">]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">names_a</span> <span class="o">==</span> <span class="n">names_b</span><span class="p">:</span>
<span class="k">return</span> <span class="n">names_a</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">diffs</span> <span class="o">=</span> <span class="p">[(</span><span class="n">x</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">-</span> <span class="n">y</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span><span class="o">*</span><span class="mi">2</span><span class="o">/</span><span class="p">(</span><span class="n">x</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">y</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="k">for</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">)]</span>
<span class="k">return</span> <span class="p">[</span><span class="nb">round</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">diffs</span><span class="p">]</span>
</code></pre></div>
<p>I called this function after a couple of rounds, to compare the current round with the previous two rounds. If the differences between subsequent rounds aren't changing, I'm comfortable declaring the loop finished. Depending on how many places I <code>round</code> to, this turns out to be 7, 10, or 23 cycles! I guess appearances are deceiving. (Machine learning hyperparameter tuning relies heavily on picking values off graphs, which I'm suddenly much more skeptical of...)</p>
<div class="highlight"><pre><span></span><code><span class="n">trace</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[]</span>
<span class="n">finished</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">False</span>
<span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mh">0</span>
<span class="k">while</span><span class="w"> </span><span class="k">not</span><span class="w"> </span><span class="nl">finished:</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mh">0</span><span class="o">:</span>
<span class="w"> </span><span class="n">xs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sc</span><span class="p">.</span><span class="n">parallelize</span><span class="p">(</span><span class="n">zs</span><span class="p">.</span><span class="n">items</span><span class="p">())</span>
<span class="w"> </span><span class="n">acc0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">dict</span><span class="p">(</span><span class="n">xs</span><span class="p">.</span><span class="n">mapValues</span><span class="p">(</span><span class="n">pr_empty</span><span class="p">).</span><span class="n">collect</span><span class="p">())</span>
<span class="w"> </span><span class="n">zs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">xs</span><span class="p">.</span><span class="n">aggregate</span><span class="p">(</span><span class="n">acc0</span><span class="p">,</span><span class="w"> </span><span class="n">pr_acc</span><span class="p">,</span><span class="w"> </span><span class="n">pr_comb</span><span class="p">)</span>
<span class="w"> </span><span class="n">top10</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sorted</span><span class="p">([(</span><span class="n">k</span><span class="p">,</span><span class="w"> </span><span class="n">v</span><span class="p">['</span><span class="n">rating</span><span class="p">'])</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">k</span><span class="p">,</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="n">in</span><span class="w"> </span><span class="n">zs</span><span class="p">.</span><span class="n">items</span><span class="p">()],</span><span class="w"> </span><span class="n">key</span><span class="o">=</span><span class="n">lambda</span><span class="w"> </span><span class="nl">x:</span><span class="w"> </span><span class="n">x</span><span class="p">[</span><span class="mh">1</span><span class="p">],</span><span class="w"> </span><span class="n">reverse</span><span class="o">=</span><span class="n">True</span><span class="p">)[</span><span class="o">:</span><span class="mh">10</span><span class="p">]</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mh">1</span><span class="o">:</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">compare10</span><span class="p">(</span><span class="n">top10</span><span class="p">,</span><span class="w"> </span><span class="n">trace</span><span class="p">[</span><span class="o">-</span><span class="mh">1</span><span class="p">])</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">compare10</span><span class="p">(</span><span class="n">trace</span><span class="p">[</span><span class="o">-</span><span class="mh">1</span><span class="p">],</span><span class="w"> </span><span class="n">trace</span><span class="p">[</span><span class="o">-</span><span class="mh">2</span><span class="p">])</span><span class="o">:</span>
<span class="w"> </span><span class="n">finished</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">True</span>
<span class="w"> </span><span class="n">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mh">1</span>
<span class="w"> </span><span class="n">trace</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">top10</span><span class="p">)</span>
</code></pre></div>Puzzling Goings-On2021-02-11T00:00:00-05:002021-02-11T00:00:00-05:00Christalee Biebertag:None,2021-02-11:/posts/puzzling-goings-on.html<p>Today, an RC colleague organized a group to tackle <a href="https://github.com/nivbend/gitstery">a git mystery</a>, in which murder has been done and the clues are hidden in commit messages. My group did not solve the crime within the hour, nor did we limit ourselves to git commands. But we appreciated the spirit of …</p><p>Today, an RC colleague organized a group to tackle <a href="https://github.com/nivbend/gitstery">a git mystery</a>, in which murder has been done and the clues are hidden in commit messages. My group did not solve the crime within the hour, nor did we limit ourselves to git commands. But we appreciated the spirit of the exercise and became familiar with git concepts such as tags, <code>log</code> vs. <code>show</code>, the <code>--author</code>, <code>--after</code>, and <code>--until</code> flags, the <code>HEAD~n</code> syntax for referencing the nth commit, and how to read diffs. Many objected to the flimsy evidence used to finger the suspect, and I do wish there had been more clues - the story resolved abruptly. I enjoyed myself, though, and look forward to next week's <a href="https://github.com/veltman/clmystery">command line murders</a>.</p>
<p>To get into the proper mood, I spend some time earlier solving <a href="https://mystery.knightlab.com/">an SQL mystery</a>, with a similar premise: investigation reports and clues are scattered through a database, and you need to query them properly to narrow down the suspects. I liked that this mystery did not stop after you found the culprit, but asked for more complex queries to identify the mastermind behind the crime. I managed to solve it nearly entirely with <code>SELECT * FROM example WHERE field1 = x AND field2 = y</code>, by taking copious notes and replaying queries periodically, but I'd like to re-do it with more sophisticated <code>JOIN</code>s now that I've reviewed the walkthrough. My lackluster showing suggests I should go ahead and dive into <a href="https://bigmachine.io/products/a-curious-moon/">A Curious Moon</a>, a science mystery using data from the Cassini mission, which several RCers have recommended / gone through.</p>
<p>I also participated this week in a birthday puzzle party in which we learned how to solve <a href="https://www.gmpuzzles.com/blog/category/loop/yajilin/">yajilin puzzles</a>, a particular favorite of the birthday girl. In fact, she's been learning to write them, although she didn't include her own puzzles in the festivities. I had fun collaborating with some RCers I haven't spent much time with previously, and of course solving puzzles is always a blast. Some people got predictably hung up on whether each step was provable with how much information on the board, but I'd rather intuit my next steps and backtrack if they turn out to be wrong.</p>
<p>This lack of rigor has also lead me to solving some Leetcode problems in non-standard ways, or at least, without using whatever data structure I'm supposed to be learning about. Usually their solutions seem extra convoluted to me, but maybe they make sense in other languages. I'm slowly getting over my resentment about the interview hazing that Leetcode and its friends represent. I'm trying to be grateful that someone has identified a relatively finite amount of content that can be mastered, and organized resources for learning it. Treating them like Advent of Code puzzles also helps, except I keep running into the pesky runtime limit.</p>
<p>Four things more than make a post, and I need to throw together some slides for a PageRank talk this afternoon.</p>Three Things Learned2021-02-04T00:00:00-05:002021-02-04T00:00:00-05:00Christalee Biebertag:None,2021-02-04:/posts/three-things-learned.html<p>I haven't been keeping up with this blog, but I have been keeping busy. A few things I've learned recently:</p>
<ul>
<li>
<p>Although JavaScript has a <code>typeof</code> command, it doesn't produce very useful output. In particular, it yields <code>object</code> no matter whether the structure in question is a Map, an Array, a …</p></li></ul><p>I haven't been keeping up with this blog, but I have been keeping busy. A few things I've learned recently:</p>
<ul>
<li>
<p>Although JavaScript has a <code>typeof</code> command, it doesn't produce very useful output. In particular, it yields <code>object</code> no matter whether the structure in question is a Map, an Array, a Set, or an Object. Apparently, <code>x.constructor</code> is how to find out what type something actually is.</p>
</li>
<li>
<p>On bash, <code>which</code> is a program, not a builtin. So it's not aware of aliases, like <code>python='python3'</code>. Neither is <code>sudo</code>. So you can check <code>python --version >= 3</code> but that's no guarantee that <code>sudo pip install</code> or <code>sudo python -m pip install</code> will be python3. It makes me rethink the utility of aliases, and possibly virtualenvs.</p>
</li>
<li>
<p>Python lists are not implemented with pointers like Lisp lists! Per <a href="https://norvig.com/python-lisp.html">Peter Norvig</a>, Python list access is O(1); per the <a href="https://docs.python.org/3/faq/design.html#how-are-lists-implemented-in-cpython">Python Design and History FAQ</a>, they are contiguous memory chunks with a head pointer and length value stored up front.</p>
</li>
</ul>
<p>Three things make a post, plus it's dinnertime: fried tofu w/ bbq sauce, risotto, and Sichuan dry-fried mushrooms & peppers.</p>refactoring checklist; ML project ideas2021-01-19T00:00:00-05:002021-01-19T00:00:00-05:00Christalee Biebertag:None,2021-01-19:/posts/refactoring-checklist-ml-project-ideas.html<p>In a recent conversation I mentioned that when I meet a new Python feature, I add it to my refactoring checklist. Someone asked me to share that checklist, and here it is, slightly expanded:</p>
<ul>
<li>write all comments/docstrings</li>
<li>resolve all TODOs</li>
<li>add types to all fn declarations and key local …</li></ul><p>In a recent conversation I mentioned that when I meet a new Python feature, I add it to my refactoring checklist. Someone asked me to share that checklist, and here it is, slightly expanded:</p>
<ul>
<li>write all comments/docstrings</li>
<li>resolve all TODOs</li>
<li>add types to all fn declarations and key local vars</li>
<li>expand short names to something explanatory</li>
<li>for loops -> list comprehensions</li>
<li>use dict comprehensions</li>
<li>use generator or lazy iterator?</li>
<li>use collections.Counter to count things</li>
<li>use map, filter, reduce?</li>
</ul>
<p>Obviously this doesn't address the "main" work of refactoring, like moving chunks of code around. But it's a list of stuff to look out for before pushing for public consumption, to encourage my code to be elegant, concise, and useable.</p>
<hr />
<p>In other news, I'm looking for excuses to use the Heap computing cluster, which means a machine learning problem with significant HD or processor requirements. So far I'm considering:</p>
<ul>
<li>restarting my Bengali.AI OCR project</li>
<li>doing something involving text prediction/generation, like Byronic poetry or Shakespearean sonnets or murder ballads<ul>
<li>definitely want a PD corpus</li>
<li>pairing with a colleague taught me about beam search, which generates several high-scoring text strings rather than simply the best token-by-token one</li>
<li>inspiration: <a href="https://www.tensorflow.org/tutorials/text/text_generation">text generation with an RNN</a>, Coursera NLP with Tensorflow Week 4</li>
</ul>
</li>
<li>helping experiment with a colleague's image captioning AI</li>
<li>some Kaggle competition TBD?</li>
</ul>RC Week 12021-01-09T00:00:00-05:002021-01-09T00:00:00-05:00Christalee Biebertag:None,2021-01-09:/posts/rc-week-1.html<p>My first week at the <a href="https://www.recurse.com/">Recurse Center</a> has been a bit of a firehose, mostly socially. It wasn't until Friday that I found myself with more than an hour of unbroken coding time, between orientation activities, chats/pairing with fellow RCers, presentations and craft evening and feelings check-in and more …</p><p>My first week at the <a href="https://www.recurse.com/">Recurse Center</a> has been a bit of a firehose, mostly socially. It wasn't until Friday that I found myself with more than an hour of unbroken coding time, between orientation activities, chats/pairing with fellow RCers, presentations and craft evening and feelings check-in and more. I feel quite well oriented, and I've fleshed out some ideas from <a href="/posts/rc-day-1.html">my previous post</a>:</p>
<ul>
<li>
<p>visualizing the global cost of living through the cost of a beer, a cappuccino, and a loaf of bread. (I would prefer either coffee/tea/beer or wine/bread/cheese, for theming, but this is where we're starting.) I'd like to use <a href="https://python-visualization.github.io/folium/">Folium</a> to build a map with data by city, using data from several sources: <a href="https://www.numbeo.com/cost-of-living/">Numbeo</a>, <a href="https://www.expatistan.com/cost-of-living">Expatistan</a>, Deutsche Bank's <a href="https://www.dbresearch.com/PROD/RPS_EN-PROD/Mapping_the_world_prices_2019/RPS_EN_DOC_VIEW.calias?rwnode=PROD0000000000436748&ProdCollection=PROD0000000000505140">annual prices index</a>, and <a href="http://www.pintprice.com/">PintPrice</a>. Features we'd like to build include:</p>
<ul>
<li>changing how many markers show up as you zoom / pan so the view isn't too crowded</li>
<li>popup bar charts showing the price data on click</li>
<li>layer selectors (?) so you can turn each indicator on/off</li>
<li>some clever interpolation or fill between cities?</li>
</ul>
<p>Luckily I have a colleague working on this with me, she's somewhat new to Python but has jumped right into <a href="https://pandas.pydata.org/">pandas</a> and data cleaning/scraping. I'm a little concerned we won't be able to write all features with Folium but will have to manipulate the underlying Leaflet map directly with JS? Or maybe <a href="https://ipyleaflet.readthedocs.io/en/latest/">ipyleaflet</a> will be the ticket. I also need to give more thought to whether it's feasible to perform all the data transformation on the server or client side, or pre-calculate every subset vs. calculations on request. Another colleague has a project mapping NYPD misconduct complaints, he'd be a good person to talk to.</p>
</li>
<li>
<p>building a font that varies its letterforms over time. I thought this would be extremely difficult and require messing around with FontForge / similar, but someone pointed me to this <a href="https://web.dev/variable-fonts/">primer on variable fonts</a> and now I wonder if it might be as straightforward as writing some JS to manipulate the font axes and re-render the text. The features I'm considering have different time constants:</p>
<ul>
<li>O/o show the phase of the moon</li>
<li>T and Y show seasonal trees</li>
<li>i and j might be flowers?</li>
<li>stroke thickness varies over the course of an hour, or (for testing) as you scroll down</li>
</ul>
</li>
</ul>
<p>Mostly I've been making (slow) progress on the cost of living visualization, Coursera NLP, and <a href="https://www.manning.com/books/mastering-large-datasets-with-python">MLDP</a>. I look forward to next week, when I can get some momentum going those fronts, and maybe do some productive pairing. (Social) networking is one of my goals, not just studying and producing portfolio work, so I'll also schedule a few chats. I may be more accustomed to guiding my own time/priorities than most of my colleagues, but that doesn't make me magically good at it, and I don't usually do it in the presence of so many skilled peers, so I'm hitting a learning curve like everyone else. Participating in feelings check-in was a bit of revelation, it's been a while since I've been in that sort of group therapy space, but I pulled out my empathizing skills and did my best. In the next couple of weeks, I'd like to make some tangible progress I can be proud of, whether it's helping others with their cool project or presenting on my own.</p>
<p>Bits and pieces I learned this week:</p>
<ul>
<li>this is valid Python syntax that evaluates the type of x and uses it to cast x+1 back to that type: <code>type(x)(x+1)</code></li>
<li>good review of threading vs. multiprocessing in Python and the vagaries of the GIL</li>
<li>successfully wrote some code using <code>try...except</code>, a pattern I never use</li>
<li>playtested a CLI puzzle and learned about <code>getfacl</code>/<code>setfacl</code>/extra permissions on files</li>
</ul>RC Day 1!2021-01-04T00:00:00-05:002021-01-04T00:00:00-05:00Christalee Biebertag:None,2021-01-04:/posts/rc-day-1.html<p>I've set a goal to reflect on each day at the Recurse Center; not all those reflections will be public, but those related to what I'm working on will be. The day started a bit earlier than I've been used to, and I enjoyed the orientation activities for the most …</p><p>I've set a goal to reflect on each day at the Recurse Center; not all those reflections will be public, but those related to what I'm working on will be. The day started a bit earlier than I've been used to, and I enjoyed the orientation activities for the most part, although I wasn't entirely sure the format served the content well, particularly the social rules skit. It's quite hard to get real engagement and buy-in over Zoom. I met several new and returning RCers who are interested in Python and/or data science, including one R aficionado, and got encouragement to do a visualization of global cost of living, using the cost of a pint of beer as a metric. Of course it's been done before and finding/scraping the data won't be easy, but it does sound like a tractable project.</p>
<p>I also put out an enquiry about web fonts, to get a san check on one of my more esoteric project ideas: a font with glyphs that vary based on the date/time. For example, O could reflect the phase of the moon, T could be a seasonal tree (bonus points for N/S Hemisphere seasonality), line thickness could vary through the hour, etc. Obviously this would be more in the vein of an art project than a useable font but I think it would be interesting (and have some niche uses - mostly witchy ones.) So far, no typography nerds have revealed themselves.</p>
<p>Another idea I had was based on this <a href="https://www.asimovinstitute.org/neural-network-zoo/">Neural Network Zoo</a> chart, implementing or at least rounding up examples / applications for each one. Perhaps this is more of a study guide than a project. And some of these networks look quite complex or specialized.</p>
<p>I have made good progress through the Coursera DL with TensorFlow specialization, though: 2 courses down, started the 3rd today. So far we've covered basic neural nets and image processing with convolutions, and next is text processing. I've also finished the 7 extant chapters of <a href="https://www.manning.com/books/deep-learning-with-python-second-edition">DL with Python</a>, 2nd ed. I should probably review the 1st ed. for material that hasn't been updated yet. I tackled the 1st chapter of <a href="https://www.manning.com/books/mastering-large-datasets-with-python">MLDP</a>, which promises to cover quite a bit: map/reduce, parallel computinng, distributed computing, Spark, Hadoop, and AWS.</p>
<p>What I didn't do today was write any code, except a few lines for Coursera. I've also been stalled for a week on the first case study of <a href="https://www.manning.com/books/data-science-bookcamp">DS BookCamp</a> - although I gave a go at implementing my own solutions, I didn't expect my code to take several hours to run and assumed I was doing something wrong. Perhaps reader feedback will encourage the author to drop more breadcrumbs in the final edition. Nor did I get a chance to pair or connect with anyone outside of orientation, probably because I spent half the day with no visible avatar in the space. Turns out it's hard to get to know ghosts!</p>
<p>Tomorrow I plan to continue with Coursera and show up for MLDP group; try scheduling some time with a faculty member to narrow down my ideas into a workable project or 3; and attend the pairing workshop before trying it out.</p>Denim Duvet2020-12-25T00:00:00-05:002020-12-25T00:00:00-05:00Christalee Biebertag:None,2020-12-25:/posts/denim-duvet.html<p>Over the years, I've gone through a lot of jeans. Usually I retire them for excessive rips and holes, although my standards have risen steadily. During the 2020 winter holiday, my partner and I decided to make significant progress on turning this pile of jeans into a duvet cover. This …</p><p>Over the years, I've gone through a lot of jeans. Usually I retire them for excessive rips and holes, although my standards have risen steadily. During the 2020 winter holiday, my partner and I decided to make significant progress on turning this pile of jeans into a duvet cover. This required prepping the jeans by cutting off each leg and trimming them into panels 7" wide, roughly sorting them by color, then sewing them into a spiral with 1/4" seam allowances. The last seams were > 6' long!</p>
<p>Next steps on this project are to learn to use our buttonholing foot, make buttonholes in the denim, attach the bottom layer, and add buttons to finish it off. We look forward to having a second duvet cover to alternate with our current one, which is mostly white and shows cat hair entirely too well.</p>
<p><br /></p>
<figure class="figure-img">
<img src="/images/denim-duvet-2.jpg" />
<figcaption class="small">The beginnings of the spiral</figcaption>
</figure>sorting and planning2020-12-23T00:00:00-05:002020-12-23T00:00:00-05:00Christalee Biebertag:None,2020-12-23:/posts/sorting-and-planning.html<p>This week, I've been gearing up for my batch at the Recurse Center, prompted by a flurry of facilitator emails. I've joined Zulip and indicated my interest in a reading/project group for <a href="https://www.manning.com/books/mastering-large-datasets-with-python">Mastering Large Datasets with Python</a>; posted my introduction to the Welcome thread and read about who else …</p><p>This week, I've been gearing up for my batch at the Recurse Center, prompted by a flurry of facilitator emails. I've joined Zulip and indicated my interest in a reading/project group for <a href="https://www.manning.com/books/mastering-large-datasets-with-python">Mastering Large Datasets with Python</a>; posted my introduction to the Welcome thread and read about who else will be joining me; and connected with my onboarding buddy, a current RC attendee who can help me out during my first week. I'm a bit uncertain about strategies for scheduling my time - how many books can I read / study groups can I join, anyway?</p>
<p>I'm also clearing the decks by closing / bookmarking tabs that have accumulated, sorting them into browser windows and desktops, etc. It's always an interesting look at what's caught my eye in the last several months. I definitely have too many resources I'm trying to work with. For example, I've been reading François Chollet's <a href="https://www.manning.com/books/deep-learning-with-python-second-edition">Deep Learning with Python</a>, on a rec from a friend, and it's slowly occurring to me that DL might be overly advanced for where I am in my data science journey. This sentiment is reinforced by having signed up for the NY Dept. of Labor's <a href="https://dol.ny.gov/online-learning-coursera">free Coursera program</a>, which means I can now pursue a DeepLearning.AI TensorFlow Developer Certificate at no cost except my time (and the exam fee). I'm going to give it a go, again, picking up where I left off in the spring. I also have Allan Downey's <a href="https://greenteapress.com/wp/think-stats-2e/">Think Stats</a> and <a href="https://greenteapress.com/wp/think-bayes/">Think Bayes</a>, Skiena's <a href="https://www.springer.com/us/book/9783319554433">Data Science Design Manual</a>, and a pile of other, even more academic, tomes. (I'm a bit of a packrat when it comes to digital resources, I'm afraid!) Obviously I'm not planning to go through every one of them in depth, but hopefully I can find something that hits the right tone and level of assumed expertise for me.</p>Advent of Code 2020, in JavaScript2020-12-09T00:00:00-05:002020-12-09T00:00:00-05:00Christalee Biebertag:None,2020-12-09:/posts/advent-of-code-2020-in-javascript.html<p>I’m doing Advent of Code this year using JavaScript, with the goal of forcing myself to learn the ins and outs of the language. And boy, does it have a lot of those. Here are some reflections on traps and quirks I’ve discovered.</p>
<p>Initially I wrote JS literally …</p><p>I’m doing Advent of Code this year using JavaScript, with the goal of forcing myself to learn the ins and outs of the language. And boy, does it have a lot of those. Here are some reflections on traps and quirks I’ve discovered.</p>
<p>Initially I wrote JS literally as I would Python, but with JS syntax: parens around conditions, curly braces instead of colons, semicolons at the end of statements. I quickly realized that the equivalent of Python’s <code>for x in y</code> statement is not JS’s <code>for (x in y)</code>, but <code>for (x of y)</code>. The first produces indices of the array, sort of like Python’s <code>enumerate</code>, while the second produces elements of the array, which is usually what I want. When I did eventually want <code>for (x in y)</code>, I found a second quirk: those indices may be integers that I can use as <code>Array[i]</code>, but that doesn’t mean I can add them to other numbers! Adding 1 to the indices produced <code>01, 11, 21, 31</code> instead of <code>1, 2, 3, 4</code>, suggesting that the indices are some Number/String hybrid.</p>
<p>Explicit casting to <code>Number</code> or <code>String</code> isn’t so bad, but declaring variables is very strange. Part of the issue is that (again, like I would in Python) I want to use Jupyter Notebooks as my development environment. They’re an easy way to re-run code against different inputs and zero in on sections as I debug, instead of running the whole file every time. I am keeping finished solutions in a <a href="https://github.com/christalee/AoC/blob/master/aoc_2020_code.js">regular JS file</a> and I have opened it up in the Node REPL (<code>node -i</code>) to check that they give the right answer, but it’s such a pain to load in code and run it, I wouldn’t want to do that all the time. Luckily, I found <a href="https://github.com/n-riesco/ijavascript">IJavaScript</a> and it works fine.</p>
<p>However, I quickly found that declaring variables with <code>let</code> and <code>const</code> prevents me from re-running a cell, because you can’t re-declare a variable. To avoid having to restart the kernel every time I want to re-run things, I started leaving off <code>let</code> and <code>const</code>. That’s how I discovered that variables declared without keywords are global. I managed to define a variable in one branch of an <code>if</code> statement, but use it in both, which worked sporadically, depending on whether I had previously followed the branch where it was defined or not. Otherwise, it silently failed, returning an empty list. I don’t have a good sense yet of when to expect errors, return values, etc. in JS, but I was not expecting that level of dysfunction. JS frequently tells me when something is undefined, why not in an <code>else</code> branch?</p>
<p>So now I put in as many <code>let</code> and <code>const</code> statements as I can, and put up with restarting the kernel perpetually. It takes away from some of the convenience, for sure. I also noticed that <code>let</code> and <code>const</code> variables are block-scoped, which means I have to declare them outside a block if I want them to be available later on. I’m pretty sure variables in Python blocks are function-scoped… as are JavaScript <code>var</code> declarations. Apparently this is one reason not to use <code>var</code> anymore. Regardless, it was a surprise, but I’ve accepted it as part of the general fashion for declaring variables upfront. Thank goodness for iterable unpacking, which works for assignments in Python and JavaScript (<code>[a, b] = [1, 2]</code>).</p>
<p>My favorite JavaScript shocker, and the one I find least defensible, came when I wanted to sort an array. I’m trying not to get too bent out of shape at the lack of built-in functions for common operations: <code>range</code>, <code>sum</code>, etc. But <code>[40, 50, 100, 200].sort()</code> should not yield <code>[ 100, 200, 40, 50 ]</code>. Why would you sort non-Strings as if they’re Strings? :head_explodes: It turns out you can specify a sort algorithm, which I’ve done sometimes in Python but for more advanced stuff, like “sort on the value of key x”. While I’m griping, I’ll also say that I don’t entirely understand why empty lists sneak in at the end of data I’m loading from file, or why a random <code>undefined</code> showed up as the first element of the first list in a list of 300+ lists. Not the rest, just that one.</p>
<p>So I’ve learned to be extra careful in checking my inputs manually but given the inconsistent warning about undefined variables, this is probably going to keep tripping me up and I’m just going to have to roll with it. Or abandon the effort - a couple of days ago I was not entirely sure it was worth learning JS to this degree. But I’d like to feel more comfortable with JS, or at least, some language other than Python. My partner suggested that I’m feeling all the pain of JS without the benefit of the nice graphical stuff it typically enables, and I get that, but adding in more complexity / figuring out a development environment that includes the browser is beyond me right now.</p>
<p>If you’re doing Advent of Code, good luck and have fun! I’m trying to keep up with every day, working in JavaScript; for the first 5 days I allowed myself to switch to Python if I was stuck as long as I ultimately implemented a solution in JS, and also I was doing that day’s puzzles from 2017 in Python as a bonus challenge. But now that I’m working all in JS I don’t really have the energy to do more. Whatever language you’re using, whatever challenge you’ve set for yourself, I hope you find something surprising and wonderful!</p>
<p>Cheatsheet (JavaScript analogues to Python structures I use frequently):</p>
<ul>
<li><code>Map() -> dict()</code></li>
<li><code>Map.get(x) -> dict[x]</code></li>
<li><code>Map.set(x, y) -> dict[x] = y</code></li>
<li><code>Map.entries() -> dict.items()</code></li>
<li><code>Array() -> list()</code></li>
<li><code>Array.slice(start, stop) -> list[start:stop]</code></li>
<li><code>Array.push(x) -> list.append(x)</code> (which is different from <code>list.extend(x)</code> or <code>list += x</code>!)</li>
<li><code>Array.sort((a, b) => a - b) -> sorted(list)</code> (or <code>list.sort()</code> for in-place)</li>
<li><code>String.replace(/old/g, new) -> str.replace(old, new)</code> (is that <code>sed</code> regex syntax?)</li>
<li><code>for (x of y) -> for x in y:</code></li>
<li><code>for (x in y) -> for i, x in enumerate(y):</code></li>
<li><code>if (f.includes(x)) -> if x in f:</code></li>
<li><code>&&, ||, ! -> and, or, not</code></li>
</ul>Recurse Center, incoming!2020-11-13T00:00:00-05:002020-11-13T00:00:00-05:00Christalee Biebertag:None,2020-11-13:/posts/recurse-center-incoming.html<p>I'm honored and excited to join the January 2021 batch of the <a href="https://www.recurse.com/">Recurse Center</a>, a unique community of programmers focused on self-directed learning. Although their Brooklyn space is closed for the foreseeable future, they've put an impressive amount of effort into facilitating productivity and communication with <a href="https://www.recurse.com/virtual-rc">Virtual RC</a>, leaning heavily …</p><p>I'm honored and excited to join the January 2021 batch of the <a href="https://www.recurse.com/">Recurse Center</a>, a unique community of programmers focused on self-directed learning. Although their Brooklyn space is closed for the foreseeable future, they've put an impressive amount of effort into facilitating productivity and communication with <a href="https://www.recurse.com/virtual-rc">Virtual RC</a>, leaning heavily on Zoom and <a href="https://zulip.com/">Zulip</a>, a Slack analogue. So far I've taken a look at their calendar, which is hopping with cool activities; set up a chat with an alum who studied the same topics I'm considering; signed up for some mailing lists and joined the Github team; and started writing up some learning goals and gathering resources. I also anticipate wanting to blog and show off whatever I accomplish, so I spent the last couple of weeks building and populating this website. It already contains quite a bit more content than my previous site, based on Hakyll; for more details on how I did it, check out the <a href="/pages/colophon.html">colophon</a>.</p>
<p>But what will I do at the Recurse Center? Ideally, become a better programmer. Specifically, one who can get hired to do data science/engineering. RC is funded primarily by companies who recruit their alumni, essentially paying a referral bonus. I'll be spending my time filling in gaps in my statistics and SQL knowledge, gaining fluency in the standard techniques for language processing, machine learning, and deep learning, making visualizations of my results, and perhaps contributing to an open source project. At least, that's part of the plan. I'm also keeping some mental spacetime open for serendipitous encounters with other Recursers, who are typically a fascinating bunch, and my own experiments. I hope I can find some knowledge to share; unfortunately most of my non-programming hobbies don't translate so well to virtual space. I'll be blogging about my learning here and adding projects as they're ready for review.</p>
<p>Taking a step into the unknown is a bit scary, but I'm putting effort into planning the structure and support I'll need to be successful at Recurse. Tune in in the new year to see how it goes!</p>my first pull request2020-11-01T00:00:00-04:002020-11-01T00:00:00-04:00Christalee Biebertag:None,2020-11-01:/posts/my-first-pull-request.html<p>Someone linked me to <a href="https://computecuter.com/">Compute Cuter</a>, a set of suggestions for cuter text editor themes, fonts, even keyboards and keycaps. The site is by <a href="https://twitter.com/sailorhg">sailorhg</a>, who makes the <a href="https://sailorhg.github.io/fairyfloss/">fairyfloss</a> theme I sometimes use. Looking through the suggestions, I was rather taken with the <a href="https://witchhazel.thea.codes/">Witch Hazel</a> theme, but it didn't have …</p><p>Someone linked me to <a href="https://computecuter.com/">Compute Cuter</a>, a set of suggestions for cuter text editor themes, fonts, even keyboards and keycaps. The site is by <a href="https://twitter.com/sailorhg">sailorhg</a>, who makes the <a href="https://sailorhg.github.io/fairyfloss/">fairyfloss</a> theme I sometimes use. Looking through the suggestions, I was rather taken with the <a href="https://witchhazel.thea.codes/">Witch Hazel</a> theme, but it didn't have an install option for Atom, my text editor of choice. Digging through <a href="https://flight-manual.atom.io/hacking-atom/sections/converting-from-textmate/#convert-the-theme">the documentation</a>, though, I found out that Atom ships with a way to convert Sublime/TextMate theme bundles to Atom themes.</p>
<p>I contacted <a href="https://thea.codes/">Thea Flowers</a>, the designer of Witch Hazel, about adding the Atom instructions to the landing page, and she invited me to make a pull request. I figured out that I had to fork her repo, make my changes, and then make a pull request between the correct branches. I also needed to turn off linting in my editor to avoid a bunch of unwanted whitespace diffs - I was really only adding about 10 lines of text. I made my request and the next day, it was accepted, easy as pie. Thanks, Thea!</p>
<p>I also want to shoutout Jany Belluz, maker of <a href="https://github.com/belluzj/fantasque-sans">Fantasque Sans Mono</a>, my new favorite Terminal font.</p>Embroidery2020-09-25T00:00:00-04:002020-09-25T00:00:00-04:00Christalee Biebertag:None,2020-09-25:/posts/embroidery.html<figure class="figure-img">
<img src="/images/stitch-flw-1.jpg" />
<figcaption class="small">Part of a Wright stained glass windows</figcaption>
</figure>
<p>As a child, I learned to cross-stitch. As an adult, I've returned to it as a relatively quiet, clean, soothing hobby I can pick up at idle moments that nevertheless produces something lasting and beautiful. Projects I've been working on include:</p>
<ul>
<li>
<p>A rendering …</p></li></ul><figure class="figure-img">
<img src="/images/stitch-flw-1.jpg" />
<figcaption class="small">Part of a Wright stained glass windows</figcaption>
</figure>
<p>As a child, I learned to cross-stitch. As an adult, I've returned to it as a relatively quiet, clean, soothing hobby I can pick up at idle moments that nevertheless produces something lasting and beautiful. Projects I've been working on include:</p>
<ul>
<li>
<p>A rendering of one of Frank Lloyd Wright's windows, now in the <a href="https://www.metmuseum.org/art/collection/search/9823">Metropolitan Museum of Art</a>. I've <a href="https://docs.google.com/spreadsheets/d/1DW2hBkbjTFB2UOoZqyk4ieI-YpwfAcXPPxVUCJY0F2U/edit?usp=sharing">charted them out</a> myself, since I didn't realize the patterns were available commercially when I started this project. When I've completed the triptych, I plan to mount them in a float frame or similar so they can be placed in the window, giving an effect similar to the originals.</p>
</li>
<li>
<p>Inspired by <a href="https://www.metmuseum.org/art/collection/search/14986">another FLW design</a> in the Met's collection, I've charted but not yet started a project using conductive thread to highlight the PCB-esque design of the print. I haven't finished designing the circuit but I anticipate the visible components will include a battery, switch, and several LEDs.</p>
</li>
</ul>
<figure class="figure-img">
<img src="/images/stitch-sampler.jpg" />
<figcaption class="small">A bouquet of embroidery stitches</figcaption>
</figure>
<ul>
<li>
<p>In an effort to learn non-cross-stitch embroidery, I stitched this floral sampler, which uses different stitches for each component of the design. I chose the colors from the cache of thread I inherited from my mother, and cut some linen from an old shirt to practice on. It was fun and the result is quite pretty, but working on linen is somewhat tricky.</p>
</li>
<li>
<p>My current project is based on a large design of the 4 seasons, using only the border elements: <a href="/images/stitch-spring.jpg">tulips</a> and apple blossoms for spring, <a href="/images/stitch-summer.jpg">seashells and hollyhocks</a> for summer, red leaves for autumn, and snowflakes and evergreens for winter. The center will hold "A love for all seasons" and the names of the recipients. I'm starting with a draft stitching to check that my colors are close enough to what's specified, otherwise I will need to buy some thread. It's an ambitious project but when I spend an hour a day, it progresses satisfactorily.</p>
</li>
</ul>Family Cookbook2019-12-25T00:00:00-05:002019-12-25T00:00:00-05:00Christalee Biebertag:None,2019-12-25:/posts/family-cookbook.html<p>My extended family likes to cook, especially at the holidays, and frequently I hear, “What’s the recipe for X? Ask Y, they’ll know.” And then the recipe will be dredged up from memory, or a dusty cookbook, or someone’s text history, or photos of a dusty cookbook …</p><p>My extended family likes to cook, especially at the holidays, and frequently I hear, “What’s the recipe for X? Ask Y, they’ll know.” And then the recipe will be dredged up from memory, or a dusty cookbook, or someone’s text history, or photos of a dusty cookbook from someone’s text history. Fed up with this precarious system, I decided to create a family cookbook, collecting recipes and menus from holiday feasts, ragged binders of handwritten recipes, and even punchcards tucked into my parents’ first Joy of Cooking (now mine). I made some tweaks to the LaTeX <a href="https://ctan.org/pkg/cuisine?lang=en">cuisine</a> package, primarily to move the recipe step numbers next to the steps, and used it for a first draft of the <a href="https://github.com/christalee/recipes/blob/master/tex/cookbook.pdf">cookbook</a>. I anticipate adding more content in the future; if you would like to make your own cookbook with this template, check out my <a href="https://github.com/christalee/recipes/blob/master/tex/cb_recipe.sty">style file</a> and/or modified <a href="https://github.com/christalee/recipes/blob/master/tex/cb_cuisine.sty">cuisine.sty</a>.</p>High Holy Days Music2019-09-25T00:00:00-04:002019-09-25T00:00:00-04:00Christalee Biebertag:None,2019-09-25:/posts/high-holy-days-music.html<p>I sing with the <a href="https://brooklyncommunitychorus.org/">Brooklyn Community Chorus</a> and we sometimes hold our concerts at <a href="https://cbebk.org/">Congregation Beth Elohim</a> in Park Slope. In return, CBE invites us to provide backup vocals during their High Holy Days services. I participated in 2019 and was pleased to receive a binder full of music, some …</p><p>I sing with the <a href="https://brooklyncommunitychorus.org/">Brooklyn Community Chorus</a> and we sometimes hold our concerts at <a href="https://cbebk.org/">Congregation Beth Elohim</a> in Park Slope. In return, CBE invites us to provide backup vocals during their High Holy Days services. I participated in 2019 and was pleased to receive a binder full of music, some of which was handwritten, heavily annotated, or used a different melody in rehearsal. To produce sheet music from these pages, I turned to <a href="http://lilypond.org/">Lilypond</a>, a text-based music editor. In a few weeks I’d taught myself enough to transcribe 15 pages of music. The source files and PDF output are available <a href="https://github.com/christalee/hhd-music">on Github</a>.</p>Buffer the Slayer2019-04-25T00:00:00-04:002019-04-25T00:00:00-04:00Christalee Biebertag:None,2019-04-25:/posts/buffer-the-slayer.html<p>When I was teaching programming at the <a href="https://www.workshopschool.org/">Workshop School</a>, I eventually expected my students to learn about object-oriented programming (OOP). As it’s not a paradigm I use frequently, I wanted to refresh my memory, both about OOP and about how to teach it. So I dug up a project …</p><p>When I was teaching programming at the <a href="https://www.workshopschool.org/">Workshop School</a>, I eventually expected my students to learn about object-oriented programming (OOP). As it’s not a paradigm I use frequently, I wanted to refresh my memory, both about OOP and about how to teach it. So I dug up a project from my own student days: a text adventure game featuring Buffer the Vampire Slayer. We were given a basic object system for locations and NPCs, and asked to implement magic objects, secret locations, and our own creative game ideas. The project was re-themed shortly afterward to feature Hairy Cdr and the Chamber of Stata, but otherwise is well described on <a href="https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/projects/st05project4.pdf">MIT OpenCourseWare</a></p>
<p>Unfortunately this project was written in <a href="https://groups.csail.mit.edu/mac/projects/scheme/">Scheme</a>, a LISP variant, not a language I was teaching at the time. So I decided to rewrite it in Python, and re-teach myself about objects at the same time. After the initial, fairly literal, translation, I added a test suite to prevent regression while refactoring. Currently, the game is playable but perhaps not very fun; it lacks a win condition, for one thing. I imagine I'll add that next. In the meantime, you can check it out <a href="https://github.com/christalee/buffer-adventure">on Github</a>.</p>Cat Assistant2017-10-30T00:00:00-04:002017-10-30T00:00:00-04:00Christalee Biebertag:None,2017-10-30:/posts/cat-assistant.html<p>Inspired by the hilarious interview question, "What words would your family use to describe you?"</p><p>Inspired by the hilarious interview question, "What words would your family use to describe you?"</p>
<p>My cats would describe me as warm and dedicated to their welfare, although they have concerns about my emergency response times.</p>
<p>My senior cat reports high levels of satisfaction with his automatic food delivery service, which boasts 24/7 uptime and limits access to authorized users. Prior to this, feeding the cat involved manual operation of the food container, requiring round-the-clock staffing. I researched and implemented this solution after consulting with major stakeholders, including my partner and my sleep schedule.</p>
<p>My junior cat has ongoing concerns about my commitment to user satisfaction, given my frequent attempts to rub her tummy and shoo her off the counter, but concedes that I fulfill my role of Second-Best Human adequately.</p>A Tale of 2 PDs2017-10-20T00:00:00-04:002017-10-20T00:00:00-04:00Christalee Biebertag:None,2017-10-20:/posts/a-tale-of-2-pds.html<p>Recently I attended two professional development events nominally aimed at "maker educators." They ended up being pretty different experiences, though!</p><p>Recently I attended two professional development events nominally aimed at "maker educators." They ended up being pretty different experiences, though!</p>
<!--more-->
<p>One event was held at a university, lead by a faculty member who (with colleagues) has developed well-known tools and pedagogy for the pursuit of creative technology. Like most PD for teachers, it was structured as a lecture with projected visuals and some live-demos. Since only half a dozen were in attendance, we did have some chances to bring our own experiences and questions to the group, but this was insufficient critical mass to really get a discussion going.</p>
<p>The other event was held online, organized by researchers at another respected university program focused on learning with technology. I had signed up only a few hours before, so I didn't realize the team was using an unconference format. I tossed an idea into the nomination pool on a whim, hoping to spark some conversation at a more abstract level than swapping standards-aligned lesson plans. (Nothing against lesson plans, but it's not why I came!)</p>
<p>Surprisingly, my session proposal quickly got traction, mostly due to a catchy title. When the voting was over, I found myself chatting with half a dozen educators about challenges they've faced getting maker programs off the ground in their schools. Several others popped into the chat over the next 45 minutes, although technology issues made it tough to promptly invite them to speak. We used an Etherpad to summarize the discussion and collect resource recommendations.</p>
<p>I did my best to facilitate the discussion, which did not go in the direction I had in mind when I proposed it. But that's the double-edged nature of unconferences - you never know which perspectives are coming to the table. I enjoyed it, although I wasn't expecting to talk so much - that was a bit stressful. Next time I'll come prepared! And I would've liked to pop into other sessions that sounded interesting; luckily the organizers sent out all the session notes afterwards. The event attracted ~50 attendees, many of whom seemed to already know each other, but we all introduced ourselves in chat and had a channel to swap contact info.</p>
<p>I love observing educators in the student/audience role - do they react the way their students would? What are the goals of the organizers? attendees? How are those goals served by the format of the event? Was the event as-advertised, or did it go another way?</p>
<p>Teacher PD is often organized in a fairly traditional lecture/slides format - odd, when so many educators have moved away from that model in their own classrooms. The outcome is relatively predictable, though, compared to an event that depends on everyone's participation. Do you have thoughts on what makes a PD session more or less effective? Have you attended an unconference, or presented at a conference session? Would you rather do all your PD online, or is the networking/facetime important to you?</p>Introduction to Programming2017-07-17T00:00:00-04:002017-07-17T00:00:00-04:00Christalee Biebertag:None,2017-07-17:/posts/introduction-to-programming.html<p>Colleagues often consult me for advice on teaching programming as fledgling or non-programmers. Here are capsule reviews of various tools and approaches for beginners.</p><p>Colleagues often consult me for advice on teaching programming as fledgling or non-programmers. Here are capsule reviews of various tools and approaches for beginners.</p>
<h3>Philosophy</h3>
<p>When picking a platform/curriculum for programming, I focus on these criteria:</p>
<ul>
<li>how familiar or easy to learn it is for the instructor</li>
<li>how aligned it is to pre-existing student interests (games, fan/professional/personal webpage, mobile app, robots - all popular)</li>
<li>whether you want to teach programming in a job context ('learn to make a webpage'), or as a medium for student work on other topics ('use Twine/Scratch to tell a story about...')</li>
</ul>
<p>My colleagues teach with 1:1 Chromebooks, so they need tools that keep student work in the browser (look out for older tools that use Flash). You know your students best - how well do they type? proofread? read directions (vs. video or interactive hints)? If they are aiming at careers in programming (or other STEM), definitely plan opportunities for "real coding"; but if not, it may be more frustrating than rewarding.</p>
<p>If you want a crash course in CS pedagogy, "computational thinking" is the keyword, but it isn't necessary unless you're looking for some organizing principles/vocabulary.</p>
<!-- (I wrote more about computational thinking here.) -->
<h3>Stuff I've Done</h3>
<p>To give you a concrete idea of where I'm coming from, here are CS activities I taught or facilitated with colleagues:</p>
<ul>
<li>basic programming in <a href="https://scratch.mit.edu/">Scratch</a>, up through loops and variables (8 weeks)</li>
<li>basic HTML/CSS -> build a webpage in <a href="https://www.weebly.com/">Weebly</a></li>
<li>students building Android apps in <a href="http://appinventor.mit.edu/explore/">App Inventor</a></li>
<li>students exploring game dev with <a href="https://unity3d.com/">Unity 3D</a></li>
<li>student writing a Python app to display assignment due dates in the classroom, based on the teacher's updated Google Calendar (using OAuth & RasPi)</li>
<li>students exploring basic programming with <a href="https://www.codecademy.com/">Codecademy</a>, <a href="https://code.org/">Code.org</a>, and <a href="https://codecombat.com/">CodeCombat</a></li>
<li>"dissecting" a broken iMac & other electronics</li>
</ul>
<h3>Making a Webpage</h3>
<p><a href="https://thimble.mozilla.org/en-US/">Mozilla Thimble</a> is the most friendly <a href="https://github.com/mozilla/thimble.mozilla.org/wiki/Using-Thimble-FAQ">webpage editor/remixer</a> I know of. You can write your template "from scratch" and include directions as a tutorial, then publish and send the link to students to remix. Downsides: students might have to make an account; everything will be licensed attribution-only, so this isn't a good platform if students want to use lots of other people's copyrighted photos, etc. (If it's all their own writing and images, or they get permission & give credit, great!)</p>
<p><a href="https://www.weebly.com/">Weebly</a> is also popular. Its main mode is drag-and-drop, though you might be able to dig into themes and options to work with the raw HTML.</p>
<p>I haven't used <a href="https://codepen.io/">codepen.io</a> specifically, but it looks like a decent online web dev editor. You would have to find or write lessons.</p>
<p>The easiest and cheapest option for hosting might be to keep webpages and assets in a public Google Drive folder. If you create in Thimble, you can download instead of publishing; if you'd rather use a different editor, Caret is good, and can save directly to Drive on Chromebooks. If this is meant to be a homepage students can use and update in the future, having it in their Google Drive sounds better than on another site/account they will forget about once the project is over.</p>
<h3>Graphics, Animations</h3>
<p>For students new to coding who might not be sure what aspects of programming appeal to them most, I tend to go with Scratch; the floor is low, the community/knowledge base is very robust, and since you can define variables and functions, the ceiling is pretty high. It's the simplest way to get interactive/animated graphics and music, which many students consider important to making games. And students familiar with the block environment can move on to Android apps with App Inventor.</p>
<p>For reference, here is a set of Scratch activities I used in a <a href="https://drive.google.com/drive/folders/0BxkPVQhGc8zXREhxYVJfbTh5aEk?usp=sharing">freshmen programming elective</a>.</p>
<p>I've been interested in Twine but haven't used it with students. My plan was always to focus on storytelling, with the HTML/CSS being enrichment. If you decide to go with Twine, I am super curious to hear how it goes!</p>
<h3>Other Popular Tools</h3>
<p>I've only used Code.org's classic <a href="https://studio.code.org/hoc/1">Hour of Code</a> as a Day 1/Week 1 intro to block programming. I see tutorials there from other familiar resources:</p>
<p><a href="https://www.codecademy.com/">Codecademy</a> - scaffolded tutorials on many subjects for a general adult audience; not good for students who don't read or process directions well</p>
<p><a href="https://www.khanacademy.org/computing/computer-programming">Khan Academy</a> - not as polished as CodeCademy or Code.org, but if you use Khan for other topics, maybe stick with it!</p>
<p><a href="https://codecombat.com/">CodeCombat</a> - Python or Javascript, framed as a hero quest RPG; silly, but ok for self-study</p>
<p><a href="https://blockly.games/">Blockly Games</a> - a self-contained online curriculum with a ramp from blocks to text editor, maybe short on guidance for self-study but should be fine in the classroom</p>CTE Programming in 20172017-06-23T00:00:00-04:002017-06-23T00:00:00-04:00Christalee Biebertag:None,2017-06-23:/posts/cte-programming-in-2017.html<p>Anyone teaching computer-related topics in 2017 knows that: the range of skills, compensation levels, and working conditions in "tech" is huge and unpredictable; and, trying to future-proof your students is impossible.</p><p>Recently I spoke with someone newly hired to teach programming/web development at a career & technical education (CTE, aka vocational) high school. CTE programs vary in length and duration, but the ones I'm familiar with typically require 1080 hours of technical instruction over 3 years (alongside classes to fulfill non-CTE graduation requirements.) This response is based on what I've observed about friends working in software engineer, sysadmin, and web developer roles, with and without CS bachelor's degrees; close friends participating in or leading hiring for programming jobs; and my own observations of what job ads ask for and what those jobs actually entail. (New to teaching CS? Try my <a href="/posts/introduction-to-programming.html">Introduction to Programming</a> for a broader look at creative & constructivist teaching resources.)</p>
<h3>The Problem</h3>
<p>Anyone teaching computer-related topics in 2017 knows that:</p>
<ol>
<li>The range of skills, compensation levels, and working conditions in "tech" is huge and unpredictable.</li>
<li>Trying to future-proof your students is impossible.</li>
</ol>
<!--more-->
<p>Depending on their college/career goals, you need to strike a balance between exposing them to transferable but abstract concepts vs. fostering mastery of specific tools. Students should leave your program showing mastery in at least one cluster of skills, to build their confidence and ensure that they know how to learn beyond the beginner level.</p>
<p>One challenge is to contextualize and connect different computer-related roles and careers. Ideally students get a taste of multiple fields but end up clear that different job titles/paths go with different daily activities, salaries, business sectors, and educational requirements. An Oracle DBA leads a different life than an iOS designer or an embedded systems engineer. Keeping an eye on the job market is essential input for your curriculum. Internships, field trips, and career talks from working professionals may not be enough to get students to distinguish between career paths. Other career exploration ideas: ask students to review an anonymized resume and suggest what jobs it would and would not be suitable for, with tips for improvement; browse real job ads on Craigslist, Indeed, and LinkedIn, and talk about what differences and similarities they see. The details of this <a href="https://github.com/kamranahmedse/developer-roadmap">web developer roadmap</a> are overkill, but if you can find or create a simplified version, it could be a good visual aid.</p>
<p>A common complaint about CS education is that students are taught too much math and abstract CS which isn't applicable to their future jobs. This is pretty funny to me: in this era of widely distributed systems, big data, and high-performance analytics and availability, you have to design systems for big N. Sampling and distributions are essential to understanding what an SLA (service-level agreement) means for your system's uptime and monitoring needs. Working programmers frequently communicate with QA, sysadmins, UI designers, and DBAs. Knowing how to ask the right questions outside your area of expertise is essential.</p>
<p>A unifying framework supports students making connections as they learn. The <a href="https://apstudent.collegeboard.org/apcourse/ap-computer-science-principles">AP Computer Science Principles curriculum</a>, <a href="https://www.csteachers.org/page/standards">CSTA K-12 Computer Science standards</a>, and anything drawing on computational thinking has good vocabulary on concepts and practices of computing.</p>
<!-- (Curious about computational thinking? Here's my take on it.) -->
<h3>My Suggestions</h3>
<p>My suggestion is to build your curriculum around websites (HTML/CSS/JavaScript/SQL/APIs) and mobile apps (App Inventor -> Java). They are popular with students and potential employers, especially if they lead to a digital portfolio & resume, and touch on:</p>
<p><strong>Topics</strong></p>
<ul>
<li>variables/functions/loops</li>
<li>how the internet works</li>
<li>how graphics/processors/caching work</li>
<li>data structures & algorithms</li>
<li>databases</li>
</ul>
<p><strong>Practices</strong></p>
<ul>
<li>UI/wireframing</li>
<li>prototyping/design workflow</li>
<li>debugging & QA</li>
<li>documentation</li>
<li>version control</li>
<li>testing</li>
<li>forking/remixing</li>
</ul>
<p>Design the year around two or three big projects, with smaller hardware or special topics units interspersed. Ideas:</p>
<p><strong>Hardware</strong></p>
<ul>
<li>ethernet & server installation</li>
<li>(dis)assembling a PC</li>
<li>installing Linux on old hardware</li>
<li>playing with RasPi/Arduinos</li>
</ul>
<p><strong>Special Topics</strong></p>
<ul>
<li>how do you know when your problem is Big Data or AI or machine learning or buzzword of the month?</li>
<li>basics of network security, threat modelling, password hygiene, & hacking ethics</li>
<li>build an educational Twitterbot (historical events, procedurally generated text/images, ASCII art)!</li>
</ul>
<p>At some point students will specialize, but have them team up for at least one project, like they would in the workplace. Front end can work with back end to design a schema & API, or with a DBA for a data visualization project; two backend devs can design modules to work together; tech writers & QA can interpret requirements, etc. Talk to your math faculty to find out when students learn stats & probability (monitoring/availability/SLAs), geometry/trigonometry & linear algebra (graphics), and limits & induction (algorithmic analysis). If you have to cover Office, definitely include a deep look at programming with Excel (if you use Google Docs, you can add <a href="https://developers.google.com/apps-script/">Apps Script</a>!)</p>
<p>Resources for teaching programming abound, but here are a few tools I've used or heard good things about, in addition to those listed above. <a href="https://c9.io/">Cloud9</a> is an editor/dev environment; <a href="https://glitch.com/">Glitch</a> is another, directly aimed at web/API scripting and remixing. I've always wanted to use <a href="https://twinery.org/">Twine</a> to do a ELA/programming interactive storytelling unit. Have you used any of these tools in your classroom?</p>Teaching Materials Selection in High School2017-06-13T00:00:00-04:002017-06-13T00:00:00-04:00Christalee Biebertag:None,2017-06-13:/posts/teaching-materials-selection-in-high-school.html<p>Materials selection and Ashby charts are rarely covered in depth for most STEM students or teachers, so I wanted to give them strong guidance. Here's my advice.</p><p>A few months ago, a former colleague lead a project where students designed, prototyped, and pitched a model of an urban watershed for use as a teaching tool. They had already interviewed local water department staff and watershed educators. Now the instructors contacted me for ideas about supplies and activities for prototyping. Materials selection and Ashby charts are rarely covered in depth for most STEM students or teachers, so I wanted to give them strong guidance. Here's my advice:</p>
<!--more-->
<ol>
<li>
<p>Find a maker or engineer to visit or consult. I put a call out to my network and got a response from an exhibit designer at the city’s science museum.</p>
</li>
<li>
<p>Drawings are the quickest way to explore design ideas, so don’t jump immediately to the laser cutter! In addition to 2D paper sketches, consider Sketchup or another modeling program to build 3D visualization skills, especially for younger students.</p>
</li>
<li>
<p>Essential questions: What is the timeline? budget? What concepts or lessons is this model trying to teach? What goals does it serve? What functions or properties does it need to accomplish that?</p>
<p>Ideally students would come up with these questions, and some of their answers, during the project introduction. One way to get started is to ask students to think about the 5 Ws: Who will use this? When? Where? To do What? Why?</p>
<p>Or, have them fill in the blank: This model needs to be <strong><em>_</em></strong>_</p>
<p>(cheap, durable, easy to build, easy to fix, fixable without special tools, expandable/upgradable, waterproof, easy to clean, not too heavy, collapsible, creative)</p>
<p>Write down these answers and post them on the wall for easy reference.</p>
</li>
<li>
<p>Grab some boxes and take an hour after school gathering up prototyping materials: plywood, lumber, acrylic sheet, felt/fabric, plastic bottles/containers, metal bars, tile, XPS foam, glass pebbles, PVC pipes, polycarbonate sheet, landscaping/craft foam, aluminum foil, plastic wrap... Also gather scissors, glue guns, box cutters, Gorilla glue, tape, glue sticks, and other tabletop cutting and fastening supplies. Maybe also markers, graph paper, and rulers. Use the boxes to organize everything per classroom and per group. Anything you can’t find or don’t have enough of, put in an order now!</p>
</li>
<li>
<p>For pointers on how to break down the materials selection process, I recommend MIT D-Lab’s excellent <a href="https://d-lab.mit.edu/sites/default/files/D-Lab_Learn-It_Material-selection.pdf">Materials Selection poster</a>. (They also have resources on <a href="https://d-lab.mit.edu/sites/default/files/D-Lab_Learn-It_Adhesives.pdf">Adhesives</a> and <a href="https://d-lab.mit.edu/sites/default/files/D-Lab_Learn-It_Fasteners_0.pdf">Fasteners</a>.)</p>
<p>Ask students to look at the table at the top to get acquainted with the key questions and comparisons between wood, metal, and plastic. Which parts of this chart are relevant to this project? What would you add? Is color or paintability important, or not? Having samples of materials on hand can help demonstrate differences in weight, strength, absorption, etc. and get ideas flowing.</p>
</li>
<li>
<p>Next, to ground it in the logistics of the fabrication shop, ask students to split up and make a list of machines and the materials each one can cut or join. Add notes on how much time/effort is involved in each method; for example, the entire 10th grade probably can’t design and laser cut multiple iterations in a week. Students may realize they need to improve their CAD skills or get trained on a machine - now is the time to schedule some tutorials!</p>
</li>
<li>
<p>Step back and check your list of which properties are most important for the prototype and the final product (remember, they may not be the same!) A model you hope to manufacture in bulk as a teaching aid might need to be light, strong, cheap, and waterproof. What combination of materials and manufacturing techniques can accomplish that? You may need to try something out, like comparing the behavior of plywood vs. lumber in water, or do more research, like finding out exactly which plastics can be cut safely on the laser cutter.</p>
<p>By the time their prototypes are built, students should be able to explain why they chose the materials and manufacturing methods they did. Their analysis can also inform recommendations on how the final product should be produced, although design for manufacturing is a whole topic on its own.</p>
</li>
</ol>
<p>Often, teachers design activities to use what's on hand, or what can be acquired cheaply and in bulk. But students need to learn how different materials behave, just like they need to learn how different tools work. Materials selection is part of the engineering design process, so I hope I've given you some ideas on how to include it in your next maker project!</p>Advent of Code2017-01-25T00:00:00-05:002017-01-25T00:00:00-05:00Christalee Biebertag:None,2017-01-25:/posts/advent-of-code.html<p><a href="https://adventofcode.com/">Advent of Code</a> is an annual challenge during the month of December, posing short puzzles that generally require code to solve. Although I've never seriously competed, I have completed for my own enjoyment every puzzle from 2016, and nearly every one from 2015. The solutions from 2016 are annotated for …</p><p><a href="https://adventofcode.com/">Advent of Code</a> is an annual challenge during the month of December, posing short puzzles that generally require code to solve. Although I've never seriously competed, I have completed for my own enjoyment every puzzle from 2016, and nearly every one from 2015. The solutions from 2016 are annotated for potential teaching use, as well as showing off my problem-solving skills. Some 2015 solutions include type hinting via <a href="https://mypy.readthedocs.io/en/latest/index.html">mypy</a>, an approach I later abandoned. The solutions and corresponding test suites are <a href="https://github.com/christalee/AoC">available on Github</a>.</p>Berrybasket2013-06-25T00:00:00-04:002013-06-25T00:00:00-04:00Christalee Biebertag:None,2013-06-25:/posts/berrybasket.html<p>In 2013 my partner Daniel and I were teaching at The Hacktory, a Philadelphia makerspace, mostly about circuits. A friend approached us about teaming up with an elementary science teacher for a unit on datalogging in (cardboard) houses, since Daniel's former job involved datalogging in (real) houses. The students were …</p><p>In 2013 my partner Daniel and I were teaching at The Hacktory, a Philadelphia makerspace, mostly about circuits. A friend approached us about teaming up with an elementary science teacher for a unit on datalogging in (cardboard) houses, since Daniel's former job involved datalogging in (real) houses. The students were learning about solar gain and heat transfer, and each group made modifications to their house to improve its comfort: sealing the window, adding black paper or aluminum foil to the exterior, increasing the thermal mass with a cup of water, etc. Then the houses went out on the roof for a week, each wired up with a temperature sensor running back to a Raspberry Pi located in the classroom, sending data every 10 minutes to an online feed. We used that data to teach a lesson on interpreting graphs, making connections to their house modifications, the weather, and other experiments they'd done with lamps and handheld thermometers. You can find the <a href="https://bergey.github.io/berrybasket/">full technical details</a> at Daniel's site.</p>
<p>My contribution to this project was primarily soldering and assembling the circuitry, as my Python skills were rudimentary back then. Working with the students was very interesting, they noticed more about the graphs than I expected and were really enthusiastic about the lesson. Preparing and presenting our poster at OHS 2013 was also a wonderful experience, I hadn't engaged much with the open hardware community before that.</p>The Hacktory2013-06-25T00:00:00-04:002013-06-25T00:00:00-04:00Christalee Biebertag:None,2013-06-25:/posts/the-hacktory.html<p>When I moved to Philadelphia, I got involved in a local makerspace, The Hacktory. They provided a great platform for teaching others and tinkering on my own projects. Here are a few of the activities I worked on there.</p><p>When I moved to Philadelphia, I got involved in a local makerspace, The Hacktory. They provided a great platform for teaching others and tinkering on my own projects. Here are a few of the activities I worked on there.</p>
<p>Introduction to Sensors, July 2012 (with Daniel Bergey): <a href="/files/sensors_overview.html">Overview</a></p>
<ul>
<li>Class 1 <a href="/files/sensors_class1_outline.pdf">Outline</a>, <a href="/files/sensors_class1_handout.pdf">Handout</a></li>
<li>Class 2 <a href="/files/sensors_class2_outline.pdf">Outline</a>, <a href="/files/sensors_class2_handout.pdf">Handout</a></li>
</ul>
<p>Recycled Electronics Jewelry, December 2012: <a href="https://www.flickr.com/photos/thehacktory/albums/72157632148528018">Photos</a></p>
<p>Starry Night T-Shirt, April 2013: <a href="/files/tshirt_workshop.pdf">Slides</a></p>
<figure class="figure-img">
<img src="/images/led_patch.jpg" />
<figcaption class="small">Girl Scout Patches</figcaption>
</figure>
<p>Girl Scout Patches, May 2013: <a href="https://www.flickr.com/photos/thehacktory/albums/72157633628918935">Photos</a></p>
<p>Meet the Multimeter, July 2013 (with Steph Alarcón): <a href="/files/multimeter_slides.pdf">Slides</a>, <a href="/files/multimeter_handout.pdf">Handout</a></p>
<p>LED Lightbox, August 2013: <a href="https://www.flickr.com/photos/thehacktory/albums/72157635093569045">Photos</a></p>
<p>Introduction to Circuits, September 2013 (with Abby Seligsohn): <a href="/files/circuits_slides.pdf">Slides</a>, <a href="/files/circuits_handout.pdf">Handout</a></p>
<p>Sew an LED Mask, October 2013 (with Abby Seligsohn): <a href="/files/led_masks_handout.pdf">Handout</a></p>
<p>Costuming with EL Wire, October 2013: <a href="https://www.flickr.com/photos/thehacktory/albums/72157633628918935">Photos</a></p>
<p>Sew an LED Monster, June 2014 (with Allison Frick): <a href="/files/monsters_slides.pdf">Slides</a>, <a href="/files/monsters.pdf">Handout</a>, <a href="/files/led_monsters_supplies.txt">Supplies</a></p>
<figure class="figure-img">
<img src="/images/led_mask.jpg" />
<figcaption class="small">Sew an LED Mask</figcaption>
</figure>
<p>Robot Jam, April 2016: <a href="https://www.flickr.com/photos/thehacktory/albums/72157667918411435">Photos</a></p>MIT OCW Highlights2011-09-25T00:00:00-04:002011-09-25T00:00:00-04:00Christalee Biebertag:None,2011-09-25:/posts/mit-ocw-highlights.html<p>You never forget your first, and for me, it's true for my first job: working with faculty to publish open educational content at <a href="https://ocw.mit.edu/">MIT OpenCourseWare</a>. A massive undertaking, OCW's original remit was to publish the entirety of MIT's curriculum online under an open license, for reuse and remixing. I was …</p><p>You never forget your first, and for me, it's true for my first job: working with faculty to publish open educational content at <a href="https://ocw.mit.edu/">MIT OpenCourseWare</a>. A massive undertaking, OCW's original remit was to publish the entirety of MIT's curriculum online under an open license, for reuse and remixing. I was lucky enough to be present when they hit the milestone of 2000 courses published, and they've come quite a ways since then.</p>
<p>But beyond the world-changing nature of the project itself, my time at OCW was unforgettable because of my colleagues, who taught me so much about how to negotiate the working world and laid the foundation for my intellectual and career pursuits. I also learned to get oriented to a new topic quickly, since we worked on new courses every 2 weeks. I needed to assess the content and handle any IP issues with an understanding of the student viewpoint, whether the course was an introductory survey course or a graduate elective.</p>
<p>I published many courses during my tenure there, but these are some of my favorites, either technically challenging or just plain fascinating content.</p>
<h3>Supplemental Resources</h3>
<p>These were published not as part of any specific MIT course, but as general teaching resources.</p>
<ul>
<li><a href="https://ocw.mit.edu/resources/res-18-004-the-torch-or-the-firehose-a-guide-to-section-teaching-spring-2009/online-publication/">The Torch or the Firehose</a></li>
<li><a href="https://ocw.mit.edu/resources/res-2-002-finite-element-procedures-for-solids-and-structures-spring-2010/">Finite Element Procedures for Solids and Structures</a></li>
<li><a href="https://ocw.mit.edu/resources/res-21g-01-kana-spring-2010/">Kana</a></li>
<li><a href="https://ocw.mit.edu/resources/res-21g-003-learning-chinese-a-foundation-course-in-mandarin-spring-2011/">Learning Chinese: A Foundation Course in Mandarin</a></li>
</ul>
<h3>Custom Layouts</h3>
<p>Typically courses were published with a tab for each resource type (lecture notes, exams, assignments, etc.) but occasionally we would publish material that demanded a different layout. Coming up with a custom page design that organized material by topic, while still being easy to navigate for users, was always a good fun challenge.</p>
<p>I'd like to shout-out the first link here, which was a course I worked on with 2 colleagues, but they graciously allowed me to organize a topic map and page template for the entire course. Any day I got to bring content-specific knowledge to work was a good one.</p>
<ul>
<li><a href="https://ocw.mit.edu/courses/materials-science-and-engineering/3-091sc-introduction-to-solid-state-chemistry-fall-2010/">Introduction to Solid State Chemistry</a></li>
<li><a href="https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-050j-information-and-entropy-spring-2008/">Information & Entropy</a></li>
<li><a href="https://ocw.mit.edu/courses/materials-science-and-engineering/3-a27-case-studies-in-forensic-metallurgy-fall-2007/">Case Studies in Forensic Metallurgy</a></li>
</ul>
<h3>Transcription</h3>
<p>For these courses, I supervised a student transcriptionist to produce typed versions of the professor's handwritten notes.</p>
<ul>
<li>Finite Element Analysis of Solids and Fluids <a href="https://ocw.mit.edu/courses/mechanical-engineering/2-092-finite-element-analysis-of-solids-and-fluids-i-fall-2009/">I</a> and <a href="https://ocw.mit.edu/courses/mechanical-engineering/2-094-finite-element-analysis-of-solids-and-fluids-ii-spring-2011/">II</a></li>
<li><a href="https://ocw.mit.edu/courses/mechanical-engineering/2-081j-plates-and-shells-spring-2007/">Plates and Shells</a></li>
</ul>
<h3>Multimedia</h3>
<p>These courses include image galleries, audio lectures, or video lectures.</p>
<ul>
<li><a href="https://ocw.mit.edu/courses/mechanical-engineering/2-830j-control-of-manufacturing-processes-sma-6303-spring-2008/">Control of Manufacturing Processes</a></li>
<li><a href="https://ocw.mit.edu/courses/mechanical-engineering/2-71-optics-spring-2009/">Optics</a></li>
<li><a href="https://ocw.mit.edu/courses/mechanical-engineering/2-997-direct-solar-thermal-to-electrical-energy-conversion-technologies-fall-2009/">Direct Solar/Thermal to Electrical Energy Conversion Technologies</a></li>
<li><a href="https://ocw.mit.edu/courses/comparative-media-studies-writing/cms-608-game-design-fall-2010/">Game Design</a></li>
<li><a href="https://ocw.mit.edu/courses/materials-science-and-engineering/3-a04-modern-blacksmithing-and-physical-metallurgy-fall-2008/">Modern Blacksmithing and Physical Metallurgy</a></li>
<li><a href="https://ocw.mit.edu/courses/music-and-theater-arts/21m-715-the-craft-of-costume-design-fall-2009/index.htm">The Craft of Costume Design</a></li>
</ul>Cider Press2009-10-25T00:00:00-04:002009-10-25T00:00:00-04:00Christalee Biebertag:None,2009-10-25:/posts/cider-press.html<p>Once upon a time, my friends and I went apple-picking, and decided we wanted to make some hard cider. So we got in touch with a friend of a friend who had a working cider press, drove out to the coast, and pressed some apples. This was great fun, but …</p><p>Once upon a time, my friends and I went apple-picking, and decided we wanted to make some hard cider. So we got in touch with a friend of a friend who had a working cider press, drove out to the coast, and pressed some apples. This was great fun, but the next year we wanted to use our own cider press, instead of taking a road trip to someone else's. My partner Daniel and I had a few design constraints: that the footprint fit in our apartment kitchen, and that the press should disassemble for easy storage.</p>
<p>So we came up with a design that used a hydraulic bottle jack, pressing an inch thick follower into a pressing barrel (with gaps between the slats) full of shredded apples. The apple juice flowed out and down and onto a tray lined with food-grade PET, into a bucket. We constructed the barrel, catch-tray, a wooden mesh to keep the apples from damming the flow, and a frame to hold the whole assembly.</p>
<figure class="figure-img">
<img src="/images/cider-press-2.jpg" />
<figcaption class="small">The entire press, disassembled (bottom to top): old catch-tray, plastic for new catch-tray, wooden mesh, follower, jack, barrel, metal/wood frame.</figcaption>
</figure>
<p>Building the system to properly direct and withstand the force of the jack was the hardest part of this project. We knew that we could cause serious damage if a component failed under load. The jack bears onto a metal box-beam, attached with threaded rods to another box-beam under the catch tray. The wooden frame runs through the box-beams, so it hold the weight of the assembly, but the threaded rod bears the force of the compressed apples, and is rated accordingly. We also calculated the forces on the barrel slats, so we could cut them to an adequate thickness and fasten the hoops with strong enough bolts. We used white oak for the barrel, follower, and mesh; its closed-cell structure makes it naturally resistant to absorbing liquid.</p>
<p>We've used our press to make several batches of hard cider and hosted multiple community apple-pressing events, where everyone brings some apples and goes home with some cider. Currently the press is in need of some repairs, including a new catch-tray that will be easier to sterilize. I look forward to bringing the fun of home engineering to more audiences next year!</p>