<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ryan Frazier&#39;s Blog</title><link>https://pianomanfrazier.com/</link><description>Recent content on Ryan Frazier&#39;s Blog</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Wed, 22 Dec 2021 15:29:06 -0700</lastBuildDate><atom:link href="https://pianomanfrazier.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Some COVID Numbers</title><link>https://pianomanfrazier.com/post/some-covid-numbers/</link><pubDate>Wed, 22 Dec 2021 15:29:06 -0700</pubDate><guid>https://pianomanfrazier.com/post/some-covid-numbers/</guid><description>&lt;p&gt;The following is an email I wrote to the COVID response team at my workplace. I have since had many conversations with people and wanted to show them the research I have done and the numbers I could and, more importantly, could not find.&lt;/p&gt;
&lt;p&gt;I have yet to hear a decent refutation of these numbers. The usual response is something like, &amp;quot;I trust the CDC and 3 years of data is good enough.&amp;quot;&lt;/p&gt;
&lt;p&gt;This email was written sometime around April/June of 2021 so some of the numbers are incomplete. Updated numbers as of today (Dec. 22, 2021) has not really changed my assessment.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;[ EMAIL START ]&lt;/p&gt;
&lt;p&gt;Hi COVID response team,&lt;/p&gt;
&lt;p&gt;Thanks for your work. As engineers and scientists we are taught to be skeptical. I have therefore tried to dig around in the numbers I could find.&lt;/p&gt;
&lt;p&gt;I found this paper written by 3 economists very interesting comparing mortality rates between Denmark, Finland, Norway, and Sweden &lt;a href=&#34;https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3674138&#34;&gt;https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3674138&lt;/a&gt; (and a summary here &lt;a href=&#34;https://www.aier.org/article/swedens-high-covid-death-rates-among-the-nordics-dry-tinder-and-other-important-factors/&#34;&gt;https://www.aier.org/article/swedens-high-covid-death-rates-among-the-nordics-dry-tinder-and-other-important-factors/&lt;/a&gt;). They propose the dry tinder theory. The reason I find that interesting is that Sweden’s charts over the last several years look very similar to our own. We had a very mild flue season the last 2 years and then we were hit fairly hard by COVID.&lt;/p&gt;
&lt;p&gt;Research that I would like to do but can’t find the numbers is to look at the last 150 years of mortality deaths and compare them. Most news bites and the CDC (&lt;a href=&#34;https://www.cdc.gov/nchs/nvss/vsrr/covid19/excess_deaths.htm&#34;&gt;https://www.cdc.gov/nchs/nvss/vsrr/covid19/excess_deaths.htm&lt;/a&gt; see chart below) seem to only show the public what has happened in the last 4 years which feels very misleading to me because I’m not sure how you can draw an accurate trendline based on 4 years of data. You should be looking at 100+ years. If you are going to make the claim that this is worse or comparable to the Spanish Flu then I need some numbers to back those claims.&lt;/p&gt;
&lt;figure&gt;
&lt;img
src=&#34;https://pianomanfrazier.com/img/covid_numbers/image001.png&#34;
alt=&#34;&#34;
title=&#34;COVID19 Excess Deaths&#34;
&gt;
&lt;figcaption class=&#34;&#34;&gt;COVID19 Excess Deaths. &lt;em&gt;source &lt;a href=&#34;https://www.cdc.gov/nchs/nvss/vsrr/covid19/excess_deaths.htm&#34;&gt;https://www.cdc.gov/nchs/nvss/vsrr/covid19/excess_deaths.htm&lt;/a&gt; accessed Sept. 2021&lt;/em&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I did my best by going to data.gov and plotting all mortality numbers by week. The best I could do was go back to 2014. Sources:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://catalog.data.gov/dataset/weekly-counts-of-deaths-by-state-and-select-causes-2014-2018&#34;&gt;https://catalog.data.gov/dataset/weekly-counts-of-deaths-by-state-and-select-causes-2014-2018&lt;/a&gt;
&lt;a href=&#34;https://catalog.data.gov/dataset/weekly-counts-of-deaths-by-state-and-select-causes-2019-2020&#34;&gt;https://catalog.data.gov/dataset/weekly-counts-of-deaths-by-state-and-select-causes-2019-2020&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I combined the data into one spreadsheet which I have attached.&lt;/p&gt;
&lt;figure&gt;
&lt;img
src=&#34;https://pianomanfrazier.com/img/covid_numbers/image002.png&#34;
alt=&#34;&#34;
title=&#34;&#34;
&gt;
&lt;figcaption class=&#34;&#34;&gt;US deaths from all causes generated from data.gov data&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;If we slice each year by the mortality valley, which appears to be around August I made the following table.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aug-July&lt;/th&gt;
&lt;th&gt;Total&lt;/th&gt;
&lt;th&gt;% Change&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2014-2015&lt;/td&gt;
&lt;td&gt;2,699,118&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2015-2016&lt;/td&gt;
&lt;td&gt;2,692,140&lt;/td&gt;
&lt;td&gt;-0.00259&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2016-2017&lt;/td&gt;
&lt;td&gt;2,783,134&lt;/td&gt;
&lt;td&gt;0.0338&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.018689018&lt;/td&gt;
&lt;td&gt;2,835,147&lt;/td&gt;
&lt;td&gt;0.018689&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2018-2019&lt;/td&gt;
&lt;td&gt;2,823,934&lt;/td&gt;
&lt;td&gt;0.108804&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2019-2020*&lt;/td&gt;
&lt;td&gt;1,571,180&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;average&lt;/td&gt;
&lt;td&gt;2,827,443&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;em&gt;*Short 7+ months due to insufficient data&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The US life expectancy curve has flattened in the last 5 years, so it would stand to reason that total mortality rates would also increase. It seems that if the life expectancy has gone down and death rates haven’t increased then we were ripe for a disease to come through and bring the numbers back up to the trend line. Source: &lt;a href=&#34;https://www.macrotrends.net/countries/USA/united-states/life-expectancy&#34;&gt;https://www.macrotrends.net/countries/USA/united-states/life-expectancy&lt;/a&gt; (filter the years between 1950 and 2019)&lt;/p&gt;
&lt;figure&gt;
&lt;img
src=&#34;https://pianomanfrazier.com/img/covid_numbers/image003.png&#34;
alt=&#34;&#34;
title=&#34;&#34;
&gt;
&lt;figcaption class=&#34;&#34;&gt;US life expectancy &lt;em&gt;source &lt;a href=&#34;https://www.macrotrends.net/countries/USA/united-states/life-expectancy&#34;&gt;https://www.macrotrends.net/countries/USA/united-states/life-expectancy&lt;/a&gt;&lt;/em&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;So the most I can say about this data is that there is definitely a spike, but it is only the worst since 2014 because I don’t have the data. I would really like a comparison to the swine flu, SARS, Spanish flu, all in one graph. Is this a 1 in 10 year disease, 1 in 25, 1 in 100?&lt;/p&gt;
&lt;p&gt;What I would like to see is a chart like the one I was able to gather about Sweden. Source: &lt;a href=&#34;https://www.scb.se/en/finding-statistics/statistics-by-subject-area/population/population-composition/population-statistics/pong/tables-and-graphs/yearly-statistics--the-whole-country/population-and-population-changes/&#34;&gt;https://www.scb.se/en/finding-statistics/statistics-by-subject-area/population/population-composition/population-statistics/pong/tables-and-graphs/yearly-statistics--the-whole-country/population-and-population-changes/&lt;/a&gt; I have also attached the spreadsheet with my chart in it.&lt;/p&gt;
&lt;figure&gt;
&lt;img
src=&#34;https://pianomanfrazier.com/img/covid_numbers/image004.png&#34;
alt=&#34;&#34;
title=&#34;&#34;
&gt;
&lt;figcaption class=&#34;&#34;&gt;Sweden Total Deaths 1850-2019 generated from scb.se data&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;You can indeed find the catastrophic spike from the 1918 Spanish Flu. I replicated this based on a graphic I saw on a podcast. It has more annotations and a bit more detail but I was able to reproduce it pretty close so I trust it. Source: &lt;a href=&#34;https://youtu.be/3BEfkKCXSOQ&#34;&gt;https://youtu.be/3BEfkKCXSOQ&lt;/a&gt; around 39:19&lt;/p&gt;
&lt;figure&gt;
&lt;img
src=&#34;https://pianomanfrazier.com/img/covid_numbers/image005.jpg&#34;
alt=&#34;&#34;
title=&#34;&#34;
&gt;
&lt;figcaption class=&#34;&#34;&gt;Labeled Sweden deaths from podcast&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I don’t have the week by week data but Sweden has a precipitous drop off in 2019 which probably account for the bad COVID spike.&lt;/p&gt;
&lt;figure&gt;
&lt;img
src=&#34;https://pianomanfrazier.com/img/covid_numbers/image006.png&#34;
alt=&#34;&#34;
title=&#34;&#34;
&gt;
&lt;figcaption class=&#34;&#34;&gt;Sweden Deaths/Population 2014-2019 from scb.se data&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Here is a comparison with the US for those same years. I didn’t have the total population, but this chart would slope downward if it did. It looks very similar. We had less deaths in 2018 than 2014 with more people to draw from. There is a huge cliff in deaths in the years 2018 to 2019.&lt;/p&gt;
&lt;figure&gt;
&lt;img
src=&#34;https://pianomanfrazier.com/img/covid_numbers/image007.png&#34;
alt=&#34;&#34;
title=&#34;&#34;
&gt;
&lt;figcaption class=&#34;&#34;&gt;US Deaths/Population 2014-2019 from data.gov data&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I’m trying to go to the original source because if you play with the numbers long enough you can tell any story you want. I suppose the purpose of this email is to question if the hysteria is actually warranted. I am having difficulty coming up with the data to support the hysteria (e.g. lockdowns, mandatory masks, …). It seems we have forgotten all we know about virus transmission from the last hundred years in favor of a myopic view of the last 4 years.&lt;/p&gt;
&lt;p&gt;Help finding the US total mortality numbers for the last 100+ years would be much appreciated.&lt;/p&gt;
&lt;p&gt;[ EMAIL END ]&lt;/p&gt;</description></item><item><title>Microbit Asteroids</title><link>https://pianomanfrazier.com/post/microbit-asteroids/</link><pubDate>Tue, 21 Dec 2021 14:24:22 -0700</pubDate><guid>https://pianomanfrazier.com/post/microbit-asteroids/</guid><description>&lt;p&gt;We will be using the &lt;a href=&#34;https://codewith.mu/&#34;&gt;Mu Editor&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here is the final version of this simple game.&lt;/p&gt;
&lt;video controls loop autoplay &gt;
&lt;source src=&#34;https://pianomanfrazier.com/img/microbit_asteroids/final_demo.mp4&#34; type=&#34;video/mp4&#34;/&gt;
Your browser does not support this video.
&lt;/video&gt;
&lt;p&gt;Here is our plan of attack.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;create controllable rocket&lt;/li&gt;
&lt;li&gt;make asteroid fall from the sky&lt;/li&gt;
&lt;li&gt;check if game over (asteroid collides with our rocket)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;tldr&#34;&gt;TLDR;&lt;/h2&gt;
&lt;p&gt;Go to the bottom and copy and paste my code into your microbit.&lt;/p&gt;
&lt;h2 id=&#34;light-up-an-led&#34;&gt;Light up an LED&lt;/h2&gt;
&lt;p&gt;First we need to know how to light up individual lights on the 5x5 grid. We can use the function &lt;code&gt;display.set_pixel(x,y,b)&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#0cf;font-weight:bold&#34;&gt;microbit&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;*&lt;/span&gt;
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;set_pixel(&lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#f60&#34;&gt;9&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img
src=&#34;https://pianomanfrazier.com/img/microbit_asteroids/light_led.png&#34;
alt=&#34;Microbit LED 0,0&#34;
title=&#34;Microbit LED 0,0&#34;
&gt;
&lt;figcaption class=&#34;&#34;&gt;Lighting LED 0,0 on the grid&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;the-led-grid&#34;&gt;The LED grid&lt;/h2&gt;
&lt;p&gt;The 5x5 grid can be addressed with the cartesian coordinates with the origin starting at the top left.&lt;/p&gt;
&lt;figure&gt;
&lt;img
src=&#34;https://pianomanfrazier.com/img/microbit_asteroids/led_grid.png&#34;
alt=&#34;&#34;
title=&#34;Microbit LED grid&#34;
&gt;
&lt;figcaption class=&#34;&#34;&gt;The LED cartesian grid start at the top right&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;As an exercise try to light up each of the four corners of the grid.&lt;/p&gt;
&lt;p&gt;What happens if you try to light up an LED that isn&#39;t on the grid like (0,5)?&lt;/p&gt;
&lt;h2 id=&#34;button-input&#34;&gt;Button Input&lt;/h2&gt;
&lt;p&gt;We are going to need to control our rocket with the A and B buttons. So let&#39;s make a simple program where a pixel lights up if we just push a button.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#0cf;font-weight:bold&#34;&gt;microbit&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;*&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; button_a&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;is_pressed():
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;set_pixel(&lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#f60&#34;&gt;9&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img
src=&#34;https://pianomanfrazier.com/img/microbit_asteroids/led_button.png&#34;
alt=&#34;&#34;
title=&#34;Microbit LED grid&#34;
&gt;
&lt;figcaption class=&#34;&#34;&gt;The LED cartesian grid start at the top right&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Now if you run this you likely won&#39;t see anything happen. This is because the code is only run once. What we actually want to happen is for the microbit to keep checking if we have pushed a button and then respond to it. So we really need the code to always be running our code. The way we do that is with an &lt;strong&gt;event loop&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;We also need to tell the microbit to turn the light off if we are not pushing the button. We&#39;ll use &lt;code&gt;display.clear()&lt;/code&gt;. Otherwise once the light is turned on it will stay on whether we press the button again or not.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#0cf;font-weight:bold&#34;&gt;microbit&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;*&lt;/span&gt;
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# event loop hack&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;while&lt;/span&gt; True:
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; button_a&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;is_pressed():
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;set_pixel(&lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#f60&#34;&gt;9&lt;/span&gt;)
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;else&lt;/span&gt;:
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;clear()&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;making-our-rocket&#34;&gt;Making our rocket&lt;/h2&gt;
&lt;p&gt;Now we need to be able to control our rocket (the pixel) with the buttons. We want our rocket to be on the bottom so the available positions of our rocket will be (0,4), (1,4), (2,4), (3,4), and (4,4).&lt;/p&gt;
&lt;p&gt;If you&#39;ll notice the Y position stays the same and the X position moves. So we should make a variable in our code for the part that changes. We&#39;ll combine what we know about checking for buttons and drawing pixels to the grid.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#0cf;font-weight:bold&#34;&gt;microbit&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;*&lt;/span&gt;
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# this part changes based on button pushes&lt;/span&gt;
rocketX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# this doesn&amp;#39;t change&lt;/span&gt;
rocketY &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;while&lt;/span&gt; True:
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; button_a&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;is_pressed():
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# move the rocket to the left by 1&lt;/span&gt;
rocketX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; button_b&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;is_pressed():
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# move the rocket to the right by 1&lt;/span&gt;
rocketX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# draw the rocket&lt;/span&gt;
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;clear()
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;set_pixel(rocketX,rocketY,&lt;span style=&#34;color:#f60&#34;&gt;9&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The program kind of works but it has some problems. Can you find them? There are 2.&lt;/p&gt;
&lt;h2 id=&#34;problem-1&#34;&gt;Problem 1&lt;/h2&gt;
&lt;p&gt;The program runs really fast so when we push a button our rocket shoots of the screen and then there is an error. We can fix this by slowing down our event loop with the &lt;code&gt;sleep&lt;/code&gt; function. Since we are only checking the buttons every so often now we should switch to checking if there have been any button presses with &lt;code&gt;button_a.get_presses()&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#0cf;font-weight:bold&#34;&gt;microbit&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;*&lt;/span&gt;
rocketX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;
rocketY &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;while&lt;/span&gt; True:
sleep(&lt;span style=&#34;color:#f60&#34;&gt;200&lt;/span&gt;)
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; button_a&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;get_presses():
rocketX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; button_b&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;get_presses():
rocketX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;clear()
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;set_pixel(rocketX,rocketY,&lt;span style=&#34;color:#f60&#34;&gt;9&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;problem-2&#34;&gt;Problem 2&lt;/h2&gt;
&lt;p&gt;Ok. So we&#39;ve fixed that but we can still run our rocket off the screen.&lt;/p&gt;
&lt;video controls loop autoplay &gt;
&lt;source src=&#34;https://pianomanfrazier.com/img/microbit_asteroids/overflow_error.mp4&#34; type=&#34;video/mp4&#34;/&gt;
Your browser does not support this video.
&lt;/video&gt;
&lt;p&gt;We need a way to make sure that you can&#39;t move your rocket off the screen and crash our program. In order to do that we need to guarantee that &lt;code&gt;rocketX&lt;/code&gt; is never greater than 4 or less than 0.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#0cf;font-weight:bold&#34;&gt;microbit&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;*&lt;/span&gt;
rocketX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;
rocketY &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;while&lt;/span&gt; True:
sleep(&lt;span style=&#34;color:#f60&#34;&gt;200&lt;/span&gt;)
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; button_a&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;get_presses() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;and&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;:
rocketX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; button_b&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;get_presses() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;and&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;:
rocketX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;clear()
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;set_pixel(rocketX,rocketY,&lt;span style=&#34;color:#f60&#34;&gt;9&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;video controls loop autoplay &gt;
&lt;source src=&#34;https://pianomanfrazier.com/img/microbit_asteroids/overflow_fix.mp4&#34; type=&#34;video/mp4&#34;/&gt;
Your browser does not support this video.
&lt;/video&gt;
&lt;h2 id=&#34;asteroids&#34;&gt;Asteroids&lt;/h2&gt;
&lt;p&gt;Now that we have a controllable rocket we need some asteroids to dodge.&lt;/p&gt;
&lt;p&gt;The idea is that an asteroid will start at a random place on the top and fall towards the bottom.&lt;/p&gt;
&lt;p&gt;Try to draw a random pixel to the screen.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#0cf;font-weight:bold&#34;&gt;microbit&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;*&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#0cf;font-weight:bold&#34;&gt;random&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; randint
rocketX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;
rocketY &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;
asteroidX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; randint(&lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;)
asteroidY &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;while&lt;/span&gt; True:
sleep(&lt;span style=&#34;color:#f60&#34;&gt;200&lt;/span&gt;)
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; button_a&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;get_presses() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;and&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;:
rocketX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; button_b&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;get_presses() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;and&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;:
rocketX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;clear()
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;set_pixel(rocketX, rocketY, &lt;span style=&#34;color:#f60&#34;&gt;9&lt;/span&gt;)
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# draw the asteroid&lt;/span&gt;
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;set_pixel(asteroidX, asteroidY, &lt;span style=&#34;color:#f60&#34;&gt;9&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Try reseting the microbit several times with the button on the back and notice how the asteroid starts at different positions.&lt;/p&gt;
&lt;p&gt;Now we need the asteroid to fall down and then when it goes off the screen start over at the top again. We also need to make sure that the asteroid doesn&#39;t try to draw off screen or our program will crash just like our rocket crashed our program before.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#0cf;font-weight:bold&#34;&gt;microbit&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;*&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#0cf;font-weight:bold&#34;&gt;random&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; randint
rocketX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;
rocketY &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;
asteroidX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; randint(&lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;)
asteroidY &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;while&lt;/span&gt; True:
sleep(&lt;span style=&#34;color:#f60&#34;&gt;200&lt;/span&gt;)
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; button_a&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;get_presses() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;and&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;:
rocketX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; button_b&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;get_presses() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;and&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;:
rocketX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; asteroidY &lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;:
asteroidY &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; asteroidY &lt;span style=&#34;color:#555&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;else&lt;/span&gt;:
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# reset the asteroid&lt;/span&gt;
asteroidY &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;
asteroidX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; randint(&lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;)
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;clear()
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;set_pixel(rocketX, rocketY, &lt;span style=&#34;color:#f60&#34;&gt;9&lt;/span&gt;)
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;set_pixel(asteroidX, asteroidY, &lt;span style=&#34;color:#f60&#34;&gt;9&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You&#39;ll notice now that we almost have a working game. We now need to detect if the asteroid crashed into your rocket.&lt;/p&gt;
&lt;h2 id=&#34;game-over&#34;&gt;Game Over&lt;/h2&gt;
&lt;p&gt;To do that we need to check if the asteroid is occupying the same space as our rocket.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#0cf;font-weight:bold&#34;&gt;microbit&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;*&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#0cf;font-weight:bold&#34;&gt;random&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; randint
rocketX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;
rocketY &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;
asteroidX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; randint(&lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;)
asteroidY &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;while&lt;/span&gt; True:
sleep(&lt;span style=&#34;color:#f60&#34;&gt;200&lt;/span&gt;)
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; button_a&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;get_presses() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;and&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;:
rocketX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; button_b&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;get_presses() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;and&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;:
rocketX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; rocketX &lt;span style=&#34;color:#555&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; asteroidY &lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;:
asteroidY &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; asteroidY &lt;span style=&#34;color:#555&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;else&lt;/span&gt;:
asteroidY &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;
asteroidX &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; randint(&lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;,&lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;)
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# check the game over condition&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; asteroidX &lt;span style=&#34;color:#555&#34;&gt;==&lt;/span&gt; rocketX &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;and&lt;/span&gt; asteroidY &lt;span style=&#34;color:#555&#34;&gt;==&lt;/span&gt; rocketY:
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;scroll(&lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;GAME OVER&amp;#39;&lt;/span&gt;)
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;else&lt;/span&gt;:
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;clear()
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;set_pixel(rocketX, rocketY, &lt;span style=&#34;color:#f60&#34;&gt;9&lt;/span&gt;)
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;set_pixel(asteroidX, asteroidY, &lt;span style=&#34;color:#f60&#34;&gt;9&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;bonus&#34;&gt;Bonus&lt;/h2&gt;
&lt;p&gt;There are a bunch of other features you could add to this game. Here are some ideas.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;connect up a speaker and make music/sound on asteroid collision&lt;/li&gt;
&lt;li&gt;keep score (either a timer or number of asteroids missed)&lt;/li&gt;
&lt;li&gt;add multiple asteroids&lt;/li&gt;
&lt;li&gt;allow the rocket to shoot with A+B button presses&lt;/li&gt;
&lt;li&gt;use the microbit internal tilt sensor to control the rocket&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;add-sound&#34;&gt;Add sound&lt;/h2&gt;
&lt;p&gt;Microbit verion 2 has better support for sounds, I only have version 1 so I&#39;ll make due with playing some music on game over.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#0cf;font-weight:bold&#34;&gt;music&lt;/span&gt;
&lt;span style=&#34;color:#555&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# check the game over condition&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; asteroidX &lt;span style=&#34;color:#555&#34;&gt;==&lt;/span&gt; rocketX &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;and&lt;/span&gt; asteroidY &lt;span style=&#34;color:#555&#34;&gt;==&lt;/span&gt; rocketY:
music&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;play(music&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;BADDY)
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;scroll(&lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;GAME OVER&amp;#39;&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;keep-score&#34;&gt;Keep Score&lt;/h2&gt;
&lt;p&gt;To keep score we&#39;ll count the asteroids that go by. For this we need another variable to count the asteroids.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;score &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;while&lt;/span&gt; True:
&lt;span style=&#34;color:#555&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; asteroidX &lt;span style=&#34;color:#555&#34;&gt;==&lt;/span&gt; rocketX &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;and&lt;/span&gt; asteroidY &lt;span style=&#34;color:#555&#34;&gt;==&lt;/span&gt; rocketY:
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# report the score to the player&lt;/span&gt;
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;scroll(&lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;GAME OVER! SCORE: &amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;+&lt;/span&gt; score)
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# reset the score on game over&lt;/span&gt;
score &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;else&lt;/span&gt;:
score &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; score &lt;span style=&#34;color:#555&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;clear()
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;set_pixel(rocketX, rocketY, &lt;span style=&#34;color:#f60&#34;&gt;9&lt;/span&gt;)
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;set_pixel(asteroidX, asteroidY, &lt;span style=&#34;color:#f60&#34;&gt;9&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;multiple-asteroids&#34;&gt;Multiple Asteroids&lt;/h2&gt;
&lt;p&gt;Multiple asteroids becomes trickier because we don&#39;t just want to copy and paste the asteroid code and keep track of all those variables. We need a way to abstract out the idea of an asteroid. We&#39;ll use a class. This is a more advanced topic so beware.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#0cf;font-weight:bold&#34;&gt;microbit&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;*&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#0cf;font-weight:bold&#34;&gt;music&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#0cf;font-weight:bold&#34;&gt;random&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; randint
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# base class&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#0a8;font-weight:bold&#34;&gt;Point&lt;/span&gt;:
x &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;
y &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;
brightness &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;9&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;update&lt;/span&gt;(self):
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;pass&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;draw&lt;/span&gt;(self):
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;set_pixel(self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;x, self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;y, self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;brightness)
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;def&lt;/span&gt; __eq__(self, other):
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;return&lt;/span&gt; self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;x &lt;span style=&#34;color:#555&#34;&gt;==&lt;/span&gt; other&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;x &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;and&lt;/span&gt; self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;y &lt;span style=&#34;color:#555&#34;&gt;==&lt;/span&gt; other&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;y
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#0a8;font-weight:bold&#34;&gt;Rocket&lt;/span&gt;(Point):
brightness &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;9&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;def&lt;/span&gt; __init__(self):
self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;x &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;2&lt;/span&gt;
self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;y &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;update&lt;/span&gt;(self):
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; button_a&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;get_presses() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;and&lt;/span&gt; self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;x &lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;:
self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;x &lt;span style=&#34;color:#555&#34;&gt;-=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; button_b&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;get_presses() &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;and&lt;/span&gt; self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;x &lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;:
self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;x &lt;span style=&#34;color:#555&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#0a8;font-weight:bold&#34;&gt;Asteroid&lt;/span&gt;(Point):
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;def&lt;/span&gt; __init__(self):
self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;brightness &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; randint(&lt;span style=&#34;color:#f60&#34;&gt;3&lt;/span&gt;, &lt;span style=&#34;color:#f60&#34;&gt;7&lt;/span&gt;)
self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;x &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; randint(&lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;)
self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;y &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;update&lt;/span&gt;(self):
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;y &lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;:
self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;brightness &lt;span style=&#34;color:#555&#34;&gt;+=&lt;/span&gt; randint(&lt;span style=&#34;color:#555&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#f60&#34;&gt;2&lt;/span&gt;, &lt;span style=&#34;color:#f60&#34;&gt;2&lt;/span&gt;)
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;brightness &lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;9&lt;/span&gt;:
self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;brightness &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;9&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;brightness &lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;2&lt;/span&gt;:
self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;brightness &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;2&lt;/span&gt;
self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;y &lt;span style=&#34;color:#555&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;else&lt;/span&gt;:
self&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;__init__()
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;init&lt;/span&gt;():
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;global&lt;/span&gt; rocket
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;global&lt;/span&gt; asteroids
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;global&lt;/span&gt; counter
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;global&lt;/span&gt; num_asteroids
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;global&lt;/span&gt; speed
rocket &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; Rocket()
asteroids &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; []
counter &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;
num_asteroids &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
speed &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;200&lt;/span&gt;
init()
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;while&lt;/span&gt; True:
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# throttle the event loop&lt;/span&gt;
sleep(speed)
counter &lt;span style=&#34;color:#555&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# gradually add more asteroids&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; counter &lt;span style=&#34;color:#555&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;and&lt;/span&gt; &lt;span style=&#34;color:#366&#34;&gt;len&lt;/span&gt;(asteroids) &lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt; num_asteroids:
asteroids&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;append(Asteroid())
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; counter &lt;span style=&#34;color:#555&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;3&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;and&lt;/span&gt; &lt;span style=&#34;color:#366&#34;&gt;len&lt;/span&gt;(asteroids) &lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt; num_asteroids:
asteroids&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;append(Asteroid())
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# difficulty adjustment&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; counter &lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;13&lt;/span&gt;:
num_asteroids &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;2&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; counter &lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;37&lt;/span&gt;:
num_asteroids &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;3&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; counter &lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;53&lt;/span&gt;:
speed &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;170&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; counter &lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;71&lt;/span&gt;:
speed &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;150&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; counter &lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;93&lt;/span&gt;:
speed &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;120&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; counter &lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;111&lt;/span&gt;:
num_asteroids &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;
rocket&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;update()
[x&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;update() &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;for&lt;/span&gt; x &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;in&lt;/span&gt; asteroids]
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# check the game over condition&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; True &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;in&lt;/span&gt; [rocket &lt;span style=&#34;color:#555&#34;&gt;==&lt;/span&gt; x &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;for&lt;/span&gt; x &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;in&lt;/span&gt; asteroids]:
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;show(Image&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;ANGRY)
music&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;play(music&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;BADDY)
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;scroll(&lt;span style=&#34;color:#366&#34;&gt;str&lt;/span&gt;(counter))
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# reset the game variables&lt;/span&gt;
init()
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;else&lt;/span&gt;:
display&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;clear()
rocket&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;draw()
[x&lt;span style=&#34;color:#555&#34;&gt;.&lt;/span&gt;draw() &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;for&lt;/span&gt; x &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;in&lt;/span&gt; asteroids]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>What Is Functional Programming</title><link>https://pianomanfrazier.com/post/what-is-functional-programming/</link><pubDate>Tue, 20 Oct 2020 09:55:15 -0600</pubDate><guid>https://pianomanfrazier.com/post/what-is-functional-programming/</guid><description>&lt;p&gt;In my day to day work as a software engineer I do not have the luxury of using a functional language like Haskell or Elm, however I have learned a lot from Elm that has changed how I program in JavaScript or Python. Here is a run-down of some of the concepts I have learned from writing 3000+ lines of Elm code.&lt;/p&gt;
&lt;p&gt;Here are some of my projects written entirely in Elm.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://knowyourtheory.com/&#34;&gt;Know Your Theory&lt;/a&gt; - a music theory drill app&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://elm-piano-teacher.netlify.app/&#34;&gt;Elm Piano Teacher&lt;/a&gt; - a midi keyboard interactive tool&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://frazierpianostudio.com/resources/scale-explorer/&#34;&gt;Music Scale Explorer&lt;/a&gt; - interactive graph of musical scales&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://frazierpianostudio.com/resources/circle-of-fifths-explorer/&#34;&gt;Circle of 5ths Explorer&lt;/a&gt; - interactive circle of 5ths with key signatures and keyboard&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://frazierpianostudio.com/resources/ukulele-chord-finder/&#34;&gt;Uke Chord Finder&lt;/a&gt; - interactive Ukulele chord finder&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;fp-vocabulary&#34;&gt;FP Vocabulary&lt;/h2&gt;
&lt;p&gt;Here is a list of common terms that come up when learning functional programming (FP). I will discuss many of them in this article.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pure Function&lt;/li&gt;
&lt;li&gt;Side Effect&lt;/li&gt;
&lt;li&gt;Referential Transparency&lt;/li&gt;
&lt;li&gt;Mutable/Immutable&lt;/li&gt;
&lt;li&gt;Currying&lt;/li&gt;
&lt;li&gt;Monad&lt;/li&gt;
&lt;li&gt;Algebraic Data Types&lt;/li&gt;
&lt;li&gt;Variant&lt;/li&gt;
&lt;li&gt;Lambda Calculus&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;pure-functions&#34;&gt;Pure Functions&lt;/h2&gt;
&lt;p&gt;What is a pure function?&lt;/p&gt;
&lt;p&gt;A function is said to be pure if 1) given the same arguments it always returns the same result and 2) the function has no side effects.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;function&lt;/span&gt; add(a,b) {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;return&lt;/span&gt; a &lt;span style=&#34;color:#555&#34;&gt;+&lt;/span&gt; b;
}
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;function&lt;/span&gt; impureAdd(a,b) {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;return&lt;/span&gt; a &lt;span style=&#34;color:#555&#34;&gt;+&lt;/span&gt; b &lt;span style=&#34;color:#555&#34;&gt;+&lt;/span&gt; c;
}
console.log(add(&lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;,&lt;span style=&#34;color:#f60&#34;&gt;2&lt;/span&gt;)) &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// 3
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// console.log(impureAdd(1,2)) // EXPLOSION!!!
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt;c &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;
console.log(impureAdd(&lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;,&lt;span style=&#34;color:#f60&#34;&gt;2&lt;/span&gt;)) &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// 4
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt;c &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;2&lt;/span&gt;
console.log(impureAdd(&lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;,&lt;span style=&#34;color:#f60&#34;&gt;2&lt;/span&gt;)) &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// 5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;what-is-a-side-effect&#34;&gt;What is a side effect?&lt;/h2&gt;
&lt;p&gt;A side effect is something that occurs as a result of a function call that does not get returned from the function.&lt;/p&gt;
&lt;h2 id=&#34;referential-transparency&#34;&gt;Referential Transparency&lt;/h2&gt;
&lt;p&gt;An expression is said to be &lt;strong&gt;referentially transparent&lt;/strong&gt; if the evaluation of the function can be replaced with its return value and not effect the program&#39;s behavior.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;result &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; add(&lt;span style=&#34;color:#f60&#34;&gt;2&lt;/span&gt;,&lt;span style=&#34;color:#f60&#34;&gt;3&lt;/span&gt;) &lt;span style=&#34;color:#555&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;5&lt;/span&gt; &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// result == 10
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt;result &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;5&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;5&lt;/span&gt; &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// result == 10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By contrast, if the function call cannot be replaced by the output then the function is said to be &lt;strong&gt;referentially opaque&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&#34;no-for-loops&#34;&gt;No For Loops?&lt;/h2&gt;
&lt;p&gt;In a pure functional language like Haskell or Elm, you will notice there are no for loops. You must process all lists with &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;reduce&lt;/code&gt;, and &lt;code&gt;filter&lt;/code&gt; (among others).&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;list &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;,&lt;span style=&#34;color:#f60&#34;&gt;2&lt;/span&gt;,&lt;span style=&#34;color:#f60&#34;&gt;3&lt;/span&gt;,&lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;]
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// Imperative
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt;listTimesThree &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; []
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;for&lt;/span&gt;(i &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;0&lt;/span&gt;; i &lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt; list.length; i&lt;span style=&#34;color:#555&#34;&gt;++&lt;/span&gt;) {
listTimesThree.push(list[i] &lt;span style=&#34;color:#555&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;3&lt;/span&gt;)
}
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// Declarative
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt;listTimesThree &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; list.map(x =&amp;gt; x &lt;span style=&#34;color:#555&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;3&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What are all the things that could go wrong in a for loop?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mental burden of parsing a for loop (What does it do? Is it correct?)&lt;/li&gt;
&lt;li&gt;thread mutate the processing list&lt;/li&gt;
&lt;li&gt;mutate the iterator variable &lt;code&gt;i&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;out of range list access&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;currying&#34;&gt;Currying&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;currying is the technique of converting a function that takes multiple arguments into a sequence of functions that each take a single argument.&lt;/p&gt;
&lt;footer&gt;&lt;span class=&#34;quote-who&#34;&gt; Wikipedia &lt;a href=&#34;https://en.wikipedia.org/wiki/Currying&#34;&gt;Currying&lt;/a&gt;
&lt;/span&gt;&lt;/footer&gt;&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;add &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; a =&amp;gt; b =&amp;gt; a &lt;span style=&#34;color:#555&#34;&gt;+&lt;/span&gt; b
addOne &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; add(&lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// What does this return?
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt;
add(&lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;)(&lt;span style=&#34;color:#f60&#34;&gt;2&lt;/span&gt;) &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// 3
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt;
list.map(x =&amp;gt; addOne(x)) &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// [2,3,4,5]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;How is currying useful?&lt;/p&gt;
&lt;p&gt;How about providing different ways to render a list? Currying makes it easy to make functions from other functions.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;list &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;Fries&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;Hamburger&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;Shake&amp;#39;&lt;/span&gt;]
latexListHead &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; x =&amp;gt; &lt;span style=&#34;color:#c30&#34;&gt;`\\begin&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;{itemize&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;n&lt;/span&gt;&lt;span style=&#34;color:#a00&#34;&gt;${&lt;/span&gt;x&lt;span style=&#34;color:#a00&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;n\\end&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;{itemize&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;}`&lt;/span&gt;
latexItem &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; x =&amp;gt; &lt;span style=&#34;color:#c30&#34;&gt;`\\item &lt;/span&gt;&lt;span style=&#34;color:#a00&#34;&gt;${&lt;/span&gt;x&lt;span style=&#34;color:#a00&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;`&lt;/span&gt;
htmlListHead &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; x =&amp;gt; &lt;span style=&#34;color:#c30&#34;&gt;`&amp;lt;ul&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;n&lt;/span&gt;&lt;span style=&#34;color:#a00&#34;&gt;${&lt;/span&gt;x&lt;span style=&#34;color:#a00&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;n&amp;lt;/ul&amp;gt;`&lt;/span&gt;
htmlItem &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; x =&amp;gt; &lt;span style=&#34;color:#c30&#34;&gt;`&amp;lt;li&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#a00&#34;&gt;${&lt;/span&gt;x&lt;span style=&#34;color:#a00&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;&amp;lt;/li&amp;gt;`&lt;/span&gt;
mdListHead &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; x =&amp;gt; x &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// The identity function
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt;mdItem &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; x =&amp;gt; &lt;span style=&#34;color:#c30&#34;&gt;`- &lt;/span&gt;&lt;span style=&#34;color:#a00&#34;&gt;${&lt;/span&gt;x&lt;span style=&#34;color:#a00&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;`&lt;/span&gt;
renderList &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; headFn =&amp;gt; itemFn =&amp;gt; list =&amp;gt; headFn(list.map(x =&amp;gt; itemFn(x)).join(&lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;))
latexList &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; renderList(latexListHead)(latexItem) &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// LaTeX render function
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt;webList &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; renderList(htmlListHead)(htmlItem) &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// HTML render function
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt;mdList &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; renderList(mdListHead)(mdItem) &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// Markdown render function
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt;
console.log(webList(list))
console.log(latexList(list))
console.log(mdList(list))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now what if you wanted several styles of lists, like a fancy web list.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;htmlListHead &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; classes =&amp;gt; x =&amp;gt; &lt;span style=&#34;color:#c30&#34;&gt;`&amp;lt;ul class=&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#a00&#34;&gt;${&lt;/span&gt;classes.join(&lt;span style=&#34;color:#c30&#34;&gt;&amp;#39; &amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#a00&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;n&lt;/span&gt;&lt;span style=&#34;color:#a00&#34;&gt;${&lt;/span&gt;x&lt;span style=&#34;color:#a00&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;\&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;n&amp;lt;/ul&amp;gt;`&lt;/span&gt;
bigBlueListHead &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; htmlListHead([&lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;big&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;blue&amp;#39;&lt;/span&gt;])
smallRedListHead &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; htmlListHead([&lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;small&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;red&amp;#39;&lt;/span&gt;])
webList &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; renderList(bigBlueListHead)(htmlItem)
console.log(webList(list))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are other uses for currying like generating a range of math plots. See my post on &lt;a href=&#34;https://pianomanfrazier.com/post/create-beautiful-math-homework/&#34;&gt;creating beautiful math homework&lt;/a&gt;. And here is the &lt;a href=&#34;https://pianomanfrazier.com/files/plots/lognorm.py&#34;&gt;python file&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;exception-throwing-is-a-side-effect&#34;&gt;Exception Throwing is a Side Effect&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;The reasoning is that I consider exceptions to be no better than “goto’s”, considered harmful since the 1960s, in that they create an abrupt jump from one point of code to another. In fact they are significantly worse than goto’s&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;They are invisible in the source code.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;They create too many possible exit points&lt;/strong&gt; for a function.&lt;/li&gt;
&lt;/ol&gt;
&lt;footer&gt;&lt;span class=&#34;quote-who&#34;&gt; Joel Spolsky at &lt;a href=&#34;https://www.joelonsoftware.com/2003/10/13/13/&#34;&gt;Joel on Software&lt;/a&gt;
&lt;/span&gt;&lt;/footer&gt;&lt;/blockquote&gt;
&lt;p&gt;I wrote about this topic in a previous blog post &lt;a href=&#34;https://pianomanfrazier.com/post/exceptions-considered-harmful/&#34;&gt;Exceptions Considered Harmful&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;javascript-helper-libraries&#34;&gt;JavaScript helper libraries&lt;/h2&gt;
&lt;p&gt;JavaScript is notorious for an inconstant API. What functions are immutable? For example, &lt;code&gt;map()&lt;/code&gt; creates a new array whereas &lt;code&gt;sort()&lt;/code&gt; and &lt;code&gt;reverse()&lt;/code&gt; &lt;em&gt;mutate&lt;/em&gt; the array &lt;em&gt;in place&lt;/em&gt; and returns the mutated array. This inconsistency is a mental burden. Therefore there is a need for libraries like &lt;a href=&#34;https://ramdajs.com/docs/&#34;&gt;Ramda&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;list &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#f60&#34;&gt;4&lt;/span&gt;,&lt;span style=&#34;color:#f60&#34;&gt;2&lt;/span&gt;,&lt;span style=&#34;color:#f60&#34;&gt;3&lt;/span&gt;,&lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;]
sortedList &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; list.sort()
console.log(list) &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// [4,2,3,1] or [1,2,3,4]?
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Compare with &lt;a href=&#34;https://ramdajs.com/docs/#sort&#34;&gt;Ramda&#39;s sort&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;js-libraries&#34;&gt;JS Libraries&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://ramdajs.com/docs/&#34;&gt;Ramda&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/supermacro/neverthrow&#34;&gt;neverthrow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://immutable-js.github.io/immutable-js/docs/#/&#34;&gt;immutableJS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;typescript-libraries&#34;&gt;TypeScript Libraries&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gigobyte.github.io/purify/&#34;&gt;purify-ts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gcanti.github.io/fp-ts/&#34;&gt;fp-ts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://true-myth.js.org/&#34;&gt;true-myth&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;other-resources&#34;&gt;Other Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://codewords.recurse.com/issues/one/an-introduction-to-functional-programming&#34;&gt;[Blog Post] A practical guide to functional programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/QyJZzq0v7Z4&#34;&gt;[YouTube] Why Isn&#39;t Functional Programming the Norm? – Richard Feldman&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://dev.to/bobbypriambodo/comment/j27&#34;&gt;[Forum Post] Explain Monads Like I&#39;m Five&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/3VQ382QG-y4&#34;&gt;[YouTube] Lambda Calculus - Fundamentals of Lambda Calculus &amp;amp; Functional Programming in JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://elmbits.com/issue-40-functional-programming/&#34;&gt;[Blog Post] Some good discussion and some resources&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>My Side Projects</title><link>https://pianomanfrazier.com/projects/</link><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate><guid>https://pianomanfrazier.com/projects/</guid><description>&lt;h2 id=&#34;table-of-contents&#34;&gt;Table of Contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#knowyourtheory&#34;&gt;KnowYourTheory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#frazier-piano-studio&#34;&gt;Frazier Piano Studio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#elm-piano-teacher&#34;&gt;Elm Piano Teacher&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#lilypond-in-markdown&#34;&gt;Lilypond in Markdown&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#popcorn-cove-subscriptions&#34;&gt;Popcorn Cove Subscriptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#lemmings-clone&#34;&gt;Lemmings Clone&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#dr-dougs-pediatrics&#34;&gt;Dr Doug&#39;s Pediatrics&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;knowyourtheory&#34;&gt;KnowYourTheory&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://app.knowyourtheory.com&#34;&gt;&lt;figure&gt;&lt;img src=&#34;https://pianomanfrazier.com/img/projects/know-your-theory-thumbnail.png&#34; alt=&#34;Know Your Theory app thumbnail&#34;&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The app: &lt;a href=&#34;https://knowyourtheory.com&#34;&gt;https://knowyourtheory.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is the music learning platform I have been working on since fall of 2018. The front end is all in Elm.&lt;/p&gt;
&lt;p&gt;I gave a talk at &lt;a href=&#34;https://pianomanfrazier.com/speaking#elm-conf-2019&#34;&gt;Elm Conf 2019&lt;/a&gt; about how I built this app.&lt;/p&gt;
&lt;p&gt;I am currently working and planning out the backend. My current plan is the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;netlify identity for authorization and authentication&lt;/li&gt;
&lt;li&gt;PouchDB/CouchDB for storing user data using IBM&#39;s &lt;a href=&#34;https://www.ibm.com/cloud/cloudant&#34;&gt;cloudant&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;netlify functions for glueing everything together&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And &lt;a href=&#34;https://www.knowyourtheory.com/posts/planned-features/&#34;&gt;here&lt;/a&gt; are some of my ideas for my next features.&lt;/p&gt;
&lt;h2 id=&#34;frazier-piano-studio&#34;&gt;Frazier Piano Studio&lt;/h2&gt;
&lt;p&gt;This is my piano teaching website &lt;a href=&#34;https://frazierpianostudio.com&#34;&gt;https://frazierpianostudio.com&lt;/a&gt;. I post my teaching resources and blog a little bit.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://frazierpianostudio.com&#34;&gt;&lt;figure&gt;&lt;img src=&#34;https://pianomanfrazier.com/img/projects/frazier-piano-studio-thumbnail.png&#34; alt=&#34;Frazier Piano Studio&#34;&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I also put up my coding music experiments and visualizations on this site. Here are some of them.&lt;/p&gt;
&lt;h3 id=&#34;music-scale-explorer&#34;&gt;Music Scale Explorer&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://frazierpianostudio.com/resources/scale-explorer/&#34;&gt;&lt;figure&gt;&lt;img src=&#34;https://pianomanfrazier.com/img/projects/music-scale-explorer-thumbnail.png&#34; alt=&#34;Music Scale Explorer&#34;&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;circle-of-fifths-explorer&#34;&gt;Circle of Fifths Explorer&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://frazierpianostudio.com/resources/circle-of-fifths-explorer/&#34;&gt;&lt;figure&gt;&lt;img src=&#34;https://pianomanfrazier.com/img/projects/circle-of-fifths-explorer-thumbnail.png&#34; alt=&#34;Circle of Fifths Explorer&#34;&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;elm-piano-teacher&#34;&gt;Elm Piano Teacher&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://elm-piano-teacher.netlify.app&#34;&gt;&lt;figure&gt;&lt;img src=&#34;https://pianomanfrazier.com/img/projects/elm-piano-teacher.png&#34; alt=&#34;Elm Piano Teacher&#34;&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This little app is built in Elm to demonstrate music concepts for my &lt;a href=&#34;https://pianomanfrazier.com/speaking#elm-conf-2019&#34;&gt;Elm Conf 2019 talk&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You will need a midi keyboard plugged into your computer and use a browser, like Chrome, that supports the web midi api.&lt;/p&gt;
&lt;p&gt;I needed an audio and visual way to talk about music stuffs with a keyboard. It uses the WebMIDI api available in Chrome. It also uses a lot of the tooling like note and keyboard rendering I have built up for &lt;a href=&#34;https://knowyourtheory.com&#34;&gt;knowyourtheory.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The things I added were&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;sound with &lt;a href=&#34;https://tonejs.github.io/&#34;&gt;Tone.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;midi with &lt;a href=&#34;https://github.com/djipco/webmidi&#34;&gt;WebMidi.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I then added decoders and encoders for all the midi messages so I could handle everything else in Elm.&lt;/p&gt;
&lt;h2 id=&#34;lilypond-in-markdown&#34;&gt;Lilypond in Markdown&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href=&#34;https://github.com/pianomanfrazier/lilypond-in-markdown-v2&#34;&gt;https://github.com/pianomanfrazier/lilypond-in-markdown-v2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/lilypond-in-markdown/&#34;&gt;Blog Post on Version 1&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;https://lilypond-in-markdown.netlify.com&#34;&gt;&lt;figure&gt;&lt;img src=&#34;https://pianomanfrazier.com/img/projects/lilypond-in-markdown.png&#34; alt=&#34;Lilypond in Markdown screenshot&#34;&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This projects generates music SVG from a markdown file using GNU Lilypond. I made a custom Nunjucks tag to process the markup and inject Lilypond&#39;s SVG output into the resulting HTML file.&lt;/p&gt;
&lt;p&gt;More about the process can be found &lt;a href=&#34;https://pianomanfrazier.com/post/lilypond-in-markdown/&#34;&gt;in this blog post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I also extended this to generate music files and play them in the browser using the output MIDI from Lilypond.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://lilypond-in-markdown.surge.sh&#34;&gt;&lt;figure&gt;&lt;img src=&#34;https://pianomanfrazier.com/img/projects/lilypond-audio-in-markdown.png&#34; alt=&#34;Lilypond audio from markdown&#34;&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It uses&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://lilypond.org/index.html&#34;&gt;LilyPond&lt;/a&gt; markup and compiler to generate music SVG&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://timidity.sourceforge.net/&#34;&gt;TiMidity++&lt;/a&gt; to transform the midi files&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://ffmpeg.org/&#34;&gt;FFmpeg&lt;/a&gt; to process the audio for the web&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://howlerjs.com/&#34;&gt;Howler.js&lt;/a&gt; to manage the audio in the browser&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I then stitch all the sound and audio stuff together using vanilla JavaScript.&lt;/p&gt;
&lt;h2 id=&#34;popcorn-cove-subscriptions&#34;&gt;Popcorn Cove Subscriptions&lt;/h2&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
&lt;iframe src=&#34;//www.youtube.com/embed/P_8gmr_Ol-4&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; allowfullscreen title=&#34;YouTube Video&#34;&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;I built an app to help manage subscription boxes for a popcorn candy store my sister and brother-in-law run in Washington.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href=&#34;https://github.com/pianomanfrazier/popcorncove_subscriptions&#34;&gt;https://github.com/pianomanfrazier/popcorncove_subscriptions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The app is built with the following&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;deployed on Heroku&lt;/li&gt;
&lt;li&gt;python flask&lt;/li&gt;
&lt;li&gt;PostgresDB&lt;/li&gt;
&lt;li&gt;VueJS with Vuetify for the UI&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;lemmings-clone&#34;&gt;Lemmings Clone&lt;/h2&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
&lt;iframe src=&#34;//www.youtube.com/embed/knKsHbLo6Yc&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; allowfullscreen title=&#34;YouTube Video&#34;&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href=&#34;https://github.com/pianomanfrazier/lemmings-clone&#34;&gt;https://github.com/pianomanfrazier/lemmings-clone&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I built this for my game development class in &lt;a href=&#34;http://vanilla-js.com/&#34;&gt;vanilla javascript&lt;/a&gt;. It uses no game engine so we had to program the game loop ourselves. I learned a lot about sprite sheets and managing game state.&lt;/p&gt;
&lt;p&gt;The levels that you see in the game were described in CSV. My goal for this was to have users be able to create their own levels and upload them. I never got that far.&lt;/p&gt;
&lt;h2 id=&#34;dr-dougs-pediatrics&#34;&gt;Dr Doug&#39;s Pediatrics&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://drdougspediatrics.com/&#34;&gt;&lt;figure&gt;&lt;img src=&#34;https://pianomanfrazier.com/img/projects/dr-doug.png&#34; alt=&#34;Dr. Doug&#39;s Pediatrics website&#34;&gt;&lt;/figure&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The website: &lt;a href=&#34;https://drdougspediatrics.com/&#34;&gt;https://drdougspediatrics.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This was my first freelance web project. My kid&#39;s dentist&#39;s old website was broken for mobile so I built them a new website.&lt;/p&gt;
&lt;p&gt;The dependecies are really minimal for this project. I didn&#39;t use a framework. I stitched together some things to make it work.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://tachyons.io/&#34;&gt;Tachyons&lt;/a&gt; for the CSS&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://swiperjs.com/&#34;&gt;Swiper.js&lt;/a&gt; for mobile image swipers&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://zeptojs.com/&#34;&gt;Zepto&lt;/a&gt; because I was into JQuery at the time and wanted something lighter&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://vincentgarreau.com/particles.js/&#34;&gt;particles.js&lt;/a&gt; for the bubble effect on the landing splash image&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Introduction to Algebraic Data Types</title><link>https://pianomanfrazier.com/post/introduction-to-algebraic-data-types/</link><pubDate>Tue, 14 Jul 2020 00:00:00 +0000</pubDate><guid>https://pianomanfrazier.com/post/introduction-to-algebraic-data-types/</guid><description>&lt;p&gt;The demo code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Elm on &lt;a href=&#34;https://ellie-app.com/9my7fGjW3Rsa1&#34;&gt;ellie-app&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;TypeScript on &lt;a href=&#34;https://www.typescriptlang.org/play/#code/IYIwzgLgTsDGEAJYBthjAgggOwJYFthkEBvAKAEhRIZ4EwAHAU2AGsAKASgC57pdsAcwDcZAL5kyKNBgDCwREwAeEJtgAmGHASKlKjFhx58oAwXooUoTCAFco2BACJ8TAPYB3J6IoSJU1HQEABE3c2VVDS08QmJyCgM2Ll4aMwsrG3tHJxBgKFZvSj9JMgB6UqRgbAByREJWJgQqpvBoOERtWLKK2DdsSAR8AE9O3QBeBGwmDywYoi5RXv66oflECamZtYXJJbA3ZCYAOmQw9mG1o8SjTlEyADNbbHhcPoR7piZ1UeR2Kp1kLwfsZUkILNY7A5nBAABZVVgYe5uKAIWGNJFudQAQmcCAA1E05sgrswkrdxLs+vtDiczh8vj9zqsFJxyWQBKooPc4I0fgAlJi9KDqCwQIbMAD6QKJPmwwFcKX4QlE-j2iA+yFwSmlAIFQpFE3iYslvE2CG2nAANJQ5QrnAAxJiapROa1iURAA#&#34;&gt;TypeScript playground&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One of the concepts in functional programming that trips up beginners is Algebraic Data Types (ADT). I am going to go through some examples and relate it to some concepts that would be familiar to Object Oriented Programming (OOP).&lt;/p&gt;
&lt;p&gt;For this introduction I will be using TypeScript for the OOP examples and Elm for the functional examples.&lt;/p&gt;
&lt;p&gt;Let&#39;s start with an example.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-elm&#34; data-lang=&#34;elm&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Animal&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Cat&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Dog&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;An &lt;code&gt;Animal&lt;/code&gt; can be either a &lt;code&gt;Cat&lt;/code&gt; or a &lt;code&gt;Dog&lt;/code&gt;, but you can&#39;t just be an animal. You need to be a type of an animal, the classic &amp;quot;is a&amp;quot; relationship. This is a bit similar to abstract classes in OOP languages.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;abstract&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;class&lt;/span&gt; Animal {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;abstract&lt;/span&gt; speak()&lt;span style=&#34;color:#555&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;string&lt;/span&gt;;
}
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;class&lt;/span&gt; Cat &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;extends&lt;/span&gt; Animal {
speak()&lt;span style=&#34;color:#555&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;string&lt;/span&gt; {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;meow&amp;#34;&lt;/span&gt;;
}
}
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;class&lt;/span&gt; Dog &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;extends&lt;/span&gt; Animal {
speak()&lt;span style=&#34;color:#555&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;string&lt;/span&gt; {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;bark&amp;#34;&lt;/span&gt;;
}
}
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// can&amp;#39;t make an abstract Animal
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// const myAnimal = new Animal();
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;const&lt;/span&gt; myCat &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;new&lt;/span&gt; Cat();
console.log(myCat.speak());&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now you could make a function that generically takes any type of &lt;code&gt;Animal&lt;/code&gt; as an argument.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;function&lt;/span&gt; feedAnimal(animal: &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Animal&lt;/span&gt;)&lt;span style=&#34;color:#555&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;string&lt;/span&gt; {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;thanks for the food! &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;+&lt;/span&gt; animal.speak();
}
console.log(feedAnimal(myCat));&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Similarly, let&#39;s translate this to Elm.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-elm&#34; data-lang=&#34;elm&#34;&gt;&lt;span style=&#34;color:#033&#34;&gt;animalSpeak&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Animal&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;string&lt;/span&gt;
&lt;span style=&#34;color:#033&#34;&gt;animalSpeak&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;animal&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;=&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;animal&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;of&lt;/span&gt;
&lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Cat&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;-&amp;gt;&lt;/span&gt;
&lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;meow&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Dog&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;-&amp;gt;&lt;/span&gt;
&lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;bark&amp;#34;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-elm&#34; data-lang=&#34;elm&#34;&gt;&lt;span style=&#34;color:#033&#34;&gt;feedAnimal&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Animal&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;string&lt;/span&gt;
&lt;span style=&#34;color:#033&#34;&gt;feedAnimal&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;animal&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;=&lt;/span&gt;
&lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;thanks for the food! &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;++&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;animalSpeak&lt;/span&gt;(&lt;span style=&#34;color:#033&#34;&gt;animal&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;why-are-they-useful&#34;&gt;Why are they useful?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Easier refactors. You can catch problems at compile time.&lt;/li&gt;
&lt;li&gt;Can constrain the problem domain by the type system. See &lt;a href=&#34;https://www.youtube.com/watch?v=IcgmSRJHu_8&#34;&gt;Making Impossible States Impossible&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When working on a new feature or a refactor with a strongly typed language I will often start by changing the data structures and then let the compiler tell me where my code fails to compile. When my code compiles again my job is mostly done.&lt;/p&gt;
&lt;p&gt;You can do this by leveraging classes and using them as types but it is a lot easier and compact to have a robust type system built into the language. There is usually a lot of boiler code needed to get some better type safety in languages like Java or TypeScript. See &lt;a href=&#34;https://stackoverflow.com/questions/21034017/how-do-you-emulate-adts-and-pattern-matching-in-typescript&#34;&gt;this stackoverflow question&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;animal-names&#34;&gt;Animal Names&lt;/h2&gt;
&lt;p&gt;Since there are no classes or member variables in a language like Elm we use records instead.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-elm&#34; data-lang=&#34;elm&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;alias&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;AnimalRecord&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;=&lt;/span&gt;
{ &lt;span style=&#34;color:#033&#34;&gt;type_&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Animal&lt;/span&gt;
, &lt;span style=&#34;color:#033&#34;&gt;name&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;String&lt;/span&gt;
}
&lt;span style=&#34;color:#033&#34;&gt;felix&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;AnimalRecord&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Cat&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;Felix&amp;#34;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When I write TypeScript I actually prefer using interfaces instead of defining classes. The reason for this preference is that I like to separate the structure of the data from the operations on that data.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I will, in fact, claim that the difference between a bad programmer
and a good one is whether he considers his code or his data structures
more important. Bad programmers worry about the code. Good programmers
worry about data structures and their relationships.&lt;/p&gt;
&lt;footer&gt;&lt;span class=&#34;quote-who&#34;&gt; Linux Torvalds, see &lt;a href=&#34;https://lwn.net/Articles/193245/&#34;&gt;https://lwn.net/Articles/193245/&lt;/a&gt;
&lt;/span&gt;&lt;/footer&gt;&lt;/blockquote&gt;
&lt;p&gt;So it would look like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;interface&lt;/span&gt; AnimalRecord {
type_ : &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Animal&lt;/span&gt;;
name : &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;string&lt;/span&gt;;
}
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;const&lt;/span&gt; felix : &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;AnimalRecord&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; {
type_: &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;new&lt;/span&gt; Cat(),
name &lt;span style=&#34;color:#555&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;Felix&amp;#34;&lt;/span&gt;,
};&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;immutability&#34;&gt;Immutability&lt;/h2&gt;
&lt;p&gt;One core idea of functional programming is immutability. You can get more immutability in TypeScript by declaring class members or interfaces as immutable.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;for classes &lt;a href=&#34;https://www.typescriptlang.org/docs/handbook/classes.html#readonly-modifier&#34;&gt;https://www.typescriptlang.org/docs/handbook/classes.html#readonly-modifier&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;for interfaces &lt;a href=&#34;https://www.typescriptlang.org/docs/handbook/utility-types.html#readonlyt&#34;&gt;https://www.typescriptlang.org/docs/handbook/utility-types.html#readonlyt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;an-example-with-error-handling&#34;&gt;An example with error handling&lt;/h2&gt;
&lt;p&gt;I wrote about this in another post &lt;a href=&#34;https://pianomanfrazier.com/post/exceptions-considered-harmful/&#34;&gt;Exceptions considered harmful&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let&#39;s use the &lt;code&gt;Either&lt;/code&gt; type from &lt;a href=&#34;https://gigobyte.github.io/purify/adts/Either&#34;&gt;purify-ts&lt;/a&gt; to deal with errors in our code. The TypeScript compiler can help us if we give it the right information.&lt;/p&gt;
&lt;p&gt;Below is the type signature for Either (almost). See &lt;a href=&#34;https://github.com/gigobyte/purify/blob/master/src/Either.ts#L3&#34;&gt;https://github.com/gigobyte/purify/blob/master/src/Either.ts#L3&lt;/a&gt; Neverthrow&#39;s &lt;a href=&#34;https://github.com/supermacro/neverthrow/blob/master/src/result.ts#L3&#34;&gt;Result&lt;/a&gt; type signature is a bit easier to read but has less functionality.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;type Either&lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt;E, T&lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; Left&lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt;E, T&lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;|&lt;/span&gt; Right&lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt;T, E&lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;An &lt;code&gt;Either&lt;/code&gt; can be one of &lt;code&gt;Left&lt;/code&gt; which holds the error or it can be &lt;code&gt;Right&lt;/code&gt; which holds the successful return value.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// might be one of an Error or a result string
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;function&lt;/span&gt; getUsernameFromDB(id : &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;number&lt;/span&gt;) &lt;span style=&#34;color:#555&#34;&gt;:&lt;/span&gt; Either&lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#366&#34;&gt;Error&lt;/span&gt;, &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;const&lt;/span&gt; username : &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;string&lt;/span&gt;;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;const&lt;/span&gt; error : &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Error&lt;/span&gt;;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;try&lt;/span&gt; {
username &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; DB.getUserById(id);
} &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;catch&lt;/span&gt;(e) {
error &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; e;
}
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; (error) {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;return&lt;/span&gt; Left(error); &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// error values are always Left
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt; } &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;else&lt;/span&gt; {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;return&lt;/span&gt; Right(username); &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// Right is &amp;#34;right&amp;#34; or the correct value
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt; }
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// could use Either.encase instead
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt; &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// see https://gigobyte.github.io/purify/adts/Either#encase
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt; &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// return Either.encase(() =&amp;gt; DB.getUserByID(id));
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt;}
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;const&lt;/span&gt; result &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; getUsernameFromDB(&lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;);
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// now the compiler forces you to deal with the error
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt;result.caseOf({
Left: &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;error&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&amp;gt;&lt;/span&gt; error.toString(),
Right: &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;value&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&amp;gt;&lt;/span&gt; value,
})&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here are the docs of &lt;code&gt;caseOf&lt;/code&gt; statements for&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Either &lt;a href=&#34;https://gigobyte.github.io/purify/adts/Either#caseOf&#34;&gt;https://gigobyte.github.io/purify/adts/Either#caseOf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Maybe &lt;a href=&#34;https://gigobyte.github.io/purify/adts/Maybe#caseOf&#34;&gt;https://gigobyte.github.io/purify/adts/Maybe#caseOf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When I first encountered ADT in Elm it looked so foreign. Once I got used to them I wished that every language I used had them. The compiler now becomes your best friend.&lt;/p&gt;
&lt;p&gt;You can get fancier with TypeScript that I did in this post to get something closer to Elms ADTs using &lt;em&gt;union types&lt;/em&gt;. See &lt;a href=&#34;https://www.typescriptlang.org/docs/handbook/advanced-types.html#union-types&#34;&gt;https://www.typescriptlang.org/docs/handbook/advanced-types.html#union-types&lt;/a&gt; TypeScript also has &lt;em&gt;type guards&lt;/em&gt; that aid in handling these types.&lt;/p&gt;</description></item><item><title>My First 5 Day Fast</title><link>https://pianomanfrazier.com/post/my-first-5-day-fast/</link><pubDate>Fri, 10 Jul 2020 00:00:00 +0000</pubDate><guid>https://pianomanfrazier.com/post/my-first-5-day-fast/</guid><description>
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
&lt;iframe src=&#34;//www.youtube.com/embed/xqmu2VQl9sk&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; allowfullscreen title=&#34;YouTube Video&#34;&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;h2 id=&#34;my-experience-with-fasting&#34;&gt;My experience with fasting&lt;/h2&gt;
&lt;p&gt;In my faith as a member of The Church of Jesus Christ of Latter-Day Saints we fast once a month. This is a 24 hour fast of no water and no food, commonly known as a black fast or a Jewish fast. I have been doing this monthly fast since I was about 8 years old. We then donate the money we saved on food and contribute to a fund to help the poor and needy. See &lt;a href=&#34;https://www.churchofjesuschrist.org/study/scriptures/gs/fast-fasting?lang=eng&amp;amp;clang=eng&#34;&gt;Gospel Topics - Fast, Fasting&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A couple of years ago I started experimenting with intermittent fasting and extended fasting. My intermittent fasting routine now is either eat one meal a day (OMAD) or eat my first meal around 2-3 and dinner around 6. I will usually do OMAD for 2 or 3 days a week. Sometimes I cheat and eat Sunday breakfast, but that is my usual routine.&lt;/p&gt;
&lt;p&gt;Once a month I usually do a longer 2-3 day fast. Because once a month my faith does a one day fast as a group, I don&#39;t really feel it much of a sacrifice to do a 24 hour fast anymore so I do at least 2 days. I&#39;m not trying to compete with those around me, I just don&#39;t feel it much of a sacrifice. I might have already done 3 or 4 OMAD days earlier that week.&lt;/p&gt;
&lt;h2 id=&#34;the-purpose-of-the-extended-fast&#34;&gt;The purpose of the extended fast&lt;/h2&gt;
&lt;p&gt;I am already pretty lean so my purpose in fasting is not to lose weight.&lt;/p&gt;
&lt;p&gt;There are many benefits to extended fasting such as increased mental clarity, autophagy, cancer prevention, and more. See Dr. Fung&#39;s amazing work &lt;a href=&#34;https://www.amazon.com/Complete-Guide-Fasting-Intermittent-Alternate-Day/dp/1628600012&#34;&gt;The Complete Guide to Fasting&lt;/a&gt;. You can also find him on YouTube.&lt;/p&gt;
&lt;p&gt;Fasting is an ancient practice. You can read about extended fasts in the bible. We have accounts of Jesus, Moses, and Elijah fasting for 40 days.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;And he [Moses] was there with the Lord forty days and forty nights; he did neither eat bread, nor drink water. And he wrote upon the tables the words of the covenant, the ten commandments.&lt;/p&gt;
&lt;footer&gt;&lt;span class=&#34;quote-who&#34;&gt; KJV Bible, Exodus 34:28
&lt;/span&gt;&lt;/footer&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;And he [Elijah] arose, and did eat and drink, and went in the strength of that meat forty days and forty nights unto Horeb the mount of God.&lt;/p&gt;
&lt;footer&gt;&lt;span class=&#34;quote-who&#34;&gt; KJV Bible, 1 Kings 19:8
&lt;/span&gt;&lt;/footer&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Then Jesus was led by the Spirit into the wilderness ... After fasting forty days and forty nights, He was hungry.&lt;/p&gt;
&lt;footer&gt;&lt;span class=&#34;quote-who&#34;&gt; KJV Bible, Mathew 4:2
&lt;/span&gt;&lt;/footer&gt;&lt;/blockquote&gt;
&lt;p&gt;In Judaism the number 40 has some significance, so they probably didn&#39;t actually fast for a full 40 days. But I&#39;m sure it was longer than 1 day. The number 40 occurs a lot in the Bible.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;https://www.churchofjesuschrist.org/search?lang=eng&amp;amp;query=%22forty%20days%22&amp;amp;facet=scriptures&amp;amp;highlight=true&amp;amp;page=1&#34;&gt;scripture search &amp;quot;forty days&amp;quot;&lt;/a&gt;, &lt;a href=&#34;https://en.wikipedia.org/wiki/40_(number)#Judaism&#34;&gt;Wikipedia 40 Number - Judaism&lt;/a&gt;, and also &lt;a href=&#34;https://www.aish.com/atr/The_Number_40.html&#34;&gt;Ask the Rabbi - The Number 40&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;preparation&#34;&gt;Preparation&lt;/h2&gt;
&lt;p&gt;I had been thinking about trying a 5 day fast, so last few weeks I have not been doing my daily fasts like I usually do. I also tried to up some of my portions. I&#39;ve tried in the past to do 5 days but I get to the 3 day mark and feel like I need to end the fast.&lt;/p&gt;
&lt;p&gt;The only thing I had on this fast other than tap water was sea salt and a bit of lemon juice. See my version of &lt;a href=&#34;#ketorade&#34;&gt;ketorade&lt;/a&gt; recipe.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;&lt;h2 id=&#34;ketorade&#34; style=&#34;margin-top: 0&#34;&gt;Ketorade&lt;/h2&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 tsp. lemon juice (a big squirt)&lt;/li&gt;
&lt;li&gt;1/2 tsp. lime juice (a squirt)&lt;/li&gt;
&lt;li&gt;1/4 tsp. of pink Himalayan sea salt (or just plain sea salt works too but I don&#39;t think it tastes as good)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mix in a tall glass of water&lt;/p&gt;
&lt;p&gt;This essentially has no calories and didn&#39;t seem to break my fast.&lt;/p&gt;
&lt;/aside&gt;
&lt;h2 id=&#34;day-1--sunday-july-5-2020&#34;&gt;Day 1 - Sunday July 5, 2020&lt;/h2&gt;
&lt;p&gt;Like I said earlier I am very comfortable doing one meal a day. I have built up to doing OMAD for the last few years.&lt;/p&gt;
&lt;p&gt;Day 1 felt about like a normal day, although I don&#39;t usually go to bed hungry.&lt;/p&gt;
&lt;h2 id=&#34;day-2--monday-july-6-2020&#34;&gt;Day 2 - Monday July 6, 2020&lt;/h2&gt;
&lt;p&gt;Surprisingly, day 2 was the hardest day of the fast. I felt tired and my brain was pretty foggy. It was a bit hard to concentrate at work.&lt;/p&gt;
&lt;p&gt;Another thing I noticed was that occasionally my heart would race. My pulse would increase to around 90 bpm. This is actually pretty common for me for a day 2 or 3 fast. My problem might be dehydration which I talk more about in days 3 and 4 of this post.&lt;/p&gt;
&lt;p&gt;I did take some pink Himalayan salt and a bit of lemon juice mixed with water. That seemed to help a bit.&lt;/p&gt;
&lt;p&gt;By the end of the day I was feeling a lot better and not sluggish and foggy. I went to bed at my normal time around midnight.&lt;/p&gt;
&lt;h2 id=&#34;day-3--tuesday-july-7-2020&#34;&gt;Day 3 - Tuesday July 7, 2020&lt;/h2&gt;
&lt;p&gt;I woke up a bit earlier than usual feeling very refreshed around 6:30 a.m. I went for an hour morning walk. I usually go on a half hour walk every morning. I was feeling great so I went a bit longer than usual.&lt;/p&gt;
&lt;p&gt;At this point in the fast I started feeling really great. I had a lot of mental clarity and was really productive throughout the day.&lt;/p&gt;
&lt;p&gt;I wasn&#39;t even that hungry anymore. I did occasionally have the desire to eat because I saw what the rest of my family was eating, but I didn&#39;t really feel hungry.&lt;/p&gt;
&lt;p&gt;It made me think of my relationship with food. Sometimes I eat because I want to eat as entertainment or eat to be social, which is different than the body saying I need to eat. I feel like I didn&#39;t learn what true hunger was until I had done several 3 day fasts.&lt;/p&gt;
&lt;p&gt;I felt especially more light headed than day 2. From what I&#39;ve read is that the body sheds salt as it burns through your glycogen stores. At this point I was probably well into full ketosis.&lt;/p&gt;
&lt;p&gt;On breaks from work (I work at home due to COVID 19 quarantine) I would go outside and weed my garden. When I would stand up I got really light headed. I figured eventually my body would adjust so I pushed through.&lt;/p&gt;
&lt;p&gt;I had a lot of energy and stayed up a bit later than usual and went to bed around 12:45 a.m.&lt;/p&gt;
&lt;h2 id=&#34;day-4--wednesday-july-8-2020&#34;&gt;Day 4 - Wednesday July 8, 2020&lt;/h2&gt;
&lt;p&gt;I woke up again a bit before my 7 o&#39;clock alarm and felt pretty good. I notice that I sleep really well on a fast and that I need less sleep than usual.&lt;/p&gt;
&lt;p&gt;I felt a bit dehydrated although my pee was pretty clear. I drank a big glass of ketorade (lemon juice, lime juice, pink Himalayan salt) and then went for an hour walk.&lt;/p&gt;
&lt;p&gt;I was not really that hungry although I felt like I was moving a bit slow.&lt;/p&gt;
&lt;p&gt;I did get a metallic taste on the roof of my mouth on and off throughout the day.&lt;/p&gt;
&lt;p&gt;The first couple of times I did a fast longer than 2 days I would get a strong metal mouth taste, especially in the mornings. I have done this enough times now that I rarely get metal mouth anymore.&lt;/p&gt;
&lt;p&gt;I was again experiencing a lot of light headedness so I did some reading online and most people suggested take in more salt to retain more water. I think I was a bit dehydrated and my blood pressure was low. So I mixed up 1 teaspoon of sea salt in about 2 cups of water and drank that.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;T.M.I. alert!&lt;/em&gt;&lt;/strong&gt; Be careful not to overdo the salt because it will flush out your bowels. I didn&#39;t know salt water had this effect. The salt water flush (SFW) is part of The Master Cleanse.&lt;/p&gt;
&lt;p&gt;Anyway I confirmed that my bowels were indeed empty.&lt;/p&gt;
&lt;p&gt;I felt much better after the salt and I could sit and stand without feeling light headed.&lt;/p&gt;
&lt;p&gt;I again went to bed late around 12:45 a.m.&lt;/p&gt;
&lt;h2 id=&#34;day-5--thursday-july-9-2020&#34;&gt;Day 5 - Thursday July 9, 2020&lt;/h2&gt;
&lt;p&gt;Considering I went to bed late I did not expect to be done sleeping around 5:45 a.m. I felt fully refreshed and I didn&#39;t get drowsy throughout the day.&lt;/p&gt;
&lt;p&gt;Again I had a large glass of ketorade.&lt;/p&gt;
&lt;p&gt;I had some extra time in the morning so I went for a hike in the mountains before work. Where I live I have access to two canyons full of trails about a 5 min drive away.&lt;/p&gt;
&lt;p&gt;I went on an hour and a half long hike. I had plenty of energy, although I was a bit winded more than usual going up the first hill of that hike.&lt;/p&gt;
&lt;p&gt;I felt really great the rest of the day. I felt like I could have taken the fast a couple more days. I am already quite lean and I don&#39;t want to waste away so I am only going to day 5. I was surprised how good I felt.&lt;/p&gt;
&lt;h2 id=&#34;breaking-the-fast&#34;&gt;Breaking the fast&lt;/h2&gt;
&lt;p&gt;For me one of the hardest parts of fasting is breaking the fast properly. Choosing not to eat is pretty simple. Not always easy but really simple. When you go back into eating food it&#39;s really tempting to just eat until you can&#39;t eat anymore.&lt;/p&gt;
&lt;p&gt;For a 1 or 2 day fast I haven&#39;t had too many troubles just eating dinner like normal, but for anything longer than that I have had to be more careful. The digestive system shuts down and needs a bit of time to get going again.&lt;/p&gt;
&lt;p&gt;If I do too much too fast I experience lots of intestinal distress like bloating and diarrhea and I often don&#39;t sleep very well that night.&lt;/p&gt;
&lt;p&gt;So it is a good idea to have a plan when breaking your fast. Plan out what you will eat, how much, and when.&lt;/p&gt;
&lt;h3 id=&#34;first-meal&#34;&gt;First meal&lt;/h3&gt;
&lt;p&gt;I broke my fast with a small meal around 4:00 p.m.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a small bowl of fermented asparagus&lt;/li&gt;
&lt;li&gt;small handful of raw almonds and walnuts&lt;/li&gt;
&lt;li&gt;bowl of fresh chicken broth with boiled onions and garlic (I just made some boiled shredded chicken for dinner)&lt;/li&gt;
&lt;li&gt;1 slice of Dubliner cheese (my favorite cheese)&lt;/li&gt;
&lt;li&gt;watermelon (1-2 Cups)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Watermelon is like cheating coming off a fast. It is mostly water but you feel like you have eaten a lot. It is pretty low carb so it will not spike your insulin (as much). I haven&#39;t tried it but you could probably gorge yourself on watermelon without any adverse effects.&lt;/p&gt;
&lt;p&gt;A note about fermented foods. I have found coming off the fast I do especially well when I can eat something fermented. When you fast and the digestive system shuts down and I surmise that a lot of the gut flora also decreases. When you eat fermented foods at the break of the fast you replenish the gut with new bacteria.&lt;/p&gt;
&lt;p&gt;I love fermenting vegetables. I have fermented jalapeños, carrots, onions, garlic, Brussels sprouts, cabbage (Saurekraut) and of course cucumbers. They are all yummy. My kids also like most of it too.&lt;/p&gt;
&lt;h3 id=&#34;second-meal&#34;&gt;Second meal&lt;/h3&gt;
&lt;p&gt;The 4 o&#39;clock meal settled really well so I had a somewhat normal portioned dinner around 7 o&#39;clock. We had a picnic at the park. I tried to keep the carbs really low so I skipped the bread or any tortilla chips. We had fresh made chicken salad sandwiches. My wife even made fresh rolls (she is a master bread maker). So I had the sandwich without the bread 😞.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Chicken Salad -- shredded chicken, mayo, home made yogurt (no sugar added, extra cream added), dill pickles, a few raisins, course ground mustard, walnuts&lt;/li&gt;
&lt;li&gt;cheddar cheese&lt;/li&gt;
&lt;li&gt;tomato&lt;/li&gt;
&lt;li&gt;greens (Spring mix)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This meal might not have been strictly keto, but it was pretty close (I probably had a total of 8 raisins in the chicken salad). I slept really well that night and I felt great the next morning.&lt;/p&gt;
&lt;p&gt;Eating a keto-like diet coming off the fast keeps your insulin low and eases your body back out of the fast. My rule is to avoid breads, chips, cookies and the like. I choose instead a small portion of meat, cheese, any vegetable.&lt;/p&gt;
&lt;h2 id=&#34;the-day-after-breaking-the-fast&#34;&gt;The day after breaking the fast&lt;/h2&gt;
&lt;p&gt;Beware not to overdo it the next day as well. I have experienced some gut problems the next day if I eat too much or a bunch of junk. I had a bunch of kettle corn the second day after a fast one year on July 24&lt;sup&gt;th&lt;/sup&gt; (Pioneer Day in Utah) and my guts were not very happy.&lt;/p&gt;
&lt;p&gt;I try to get back on my normal eating routine the day after I break the fast. I don&#39;t try to make up for the lost weight immediately.&lt;/p&gt;</description></item><item><title>Case Statement in Typescript</title><link>https://pianomanfrazier.com/post/case-statement-in-typescript/</link><pubDate>Wed, 24 Jun 2020 12:33:03 -0600</pubDate><guid>https://pianomanfrazier.com/post/case-statement-in-typescript/</guid><description>&lt;p&gt;One of my favorite features of functional languages like Elm is pattern matching. Here is an example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-elm&#34; data-lang=&#34;elm&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;State&lt;/span&gt;
&lt;span style=&#34;color:#c0f&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Loading&lt;/span&gt;
&lt;span style=&#34;color:#c0f&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Error&lt;/span&gt;
&lt;span style=&#34;color:#c0f&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Ok&lt;/span&gt;
&lt;span style=&#34;color:#033&#34;&gt;stateToString&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;State&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;String&lt;/span&gt;
&lt;span style=&#34;color:#033&#34;&gt;stateToString&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;state&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;=&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;state&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;of&lt;/span&gt;
&lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Loading&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;-&amp;gt;&lt;/span&gt;
&lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;Loading ...&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Error&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;-&amp;gt;&lt;/span&gt;
&lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;Something went wrong.&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Ok&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;-&amp;gt;&lt;/span&gt;
&lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;It&amp;#39;s all good&amp;#34;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I found a simple way to provide an action for every case of a TypeScript enum.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;enum&lt;/span&gt; State {
Loading,
&lt;span style=&#34;color:#366&#34;&gt;Error&lt;/span&gt;,
Ok,
}
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;const&lt;/span&gt; STATE_MAP &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; {
[State.Loading] &lt;span style=&#34;color:#555&#34;&gt;:&lt;/span&gt; () &lt;span style=&#34;color:#555&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;Loading ...&amp;#34;&lt;/span&gt;,
[State.&lt;span style=&#34;color:#366&#34;&gt;Error&lt;/span&gt;] &lt;span style=&#34;color:#555&#34;&gt;:&lt;/span&gt; () &lt;span style=&#34;color:#555&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;Something went wrong.&amp;#34;&lt;/span&gt;,
[State.Ok] &lt;span style=&#34;color:#555&#34;&gt;:&lt;/span&gt; () &lt;span style=&#34;color:#555&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;It&amp;#39;s all good&amp;#34;&lt;/span&gt;,
}
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;function&lt;/span&gt; stateToString(state : &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;State&lt;/span&gt;) &lt;span style=&#34;color:#555&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;string&lt;/span&gt; {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;return&lt;/span&gt; STATE_MAP[state]();
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&#34;https://www.typescriptlang.org/play/#code/KYOwrgtgBAygLgQzsKBvAUASADIHsEAmAliAOYA0WAogE4242WYDyA1pQL7roDGuIAZziwAKgEERVAPoBZMQAUoAXjRYA2vCTAAdHkIlSAXSgAuKAAoAlMoB8UAER7iZKNrf2mGxMm216NYzMrWwcYXAhgOAALAygAd1BhOPoybQ91TR82QItrJTt7AEk4AHIBKAQAG0qoUlxcAnSudAAzMBAeOCJ+KCEtEVx4GgNzPuRTWG9gazMhYZcMTBpIsBoQUQlpOXk1MeBDKwBudGa+QVxKnUrcUlGpgaGRzJ0nA0tLQ6A&#34;&gt;Link to TypeScript playground&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Usually TypeScript won&#39;t allow bracket notation to access properties of an object. In this case the compiler knows that all cases of &lt;code&gt;State&lt;/code&gt; are accounted for and can thus be used to index into the object.&lt;/p&gt;
&lt;p&gt;Try removing one of the states from &lt;code&gt;STATE_MAP&lt;/code&gt; and the TypeScript compiler will yell at you.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;Element implicitly has an &amp;#39;any&amp;#39; type because expression of type &amp;#39;State&amp;#39; can&amp;#39;t be used to index type &amp;#39;{ 0: () =&amp;gt; string; 1: () =&amp;gt; string; }&amp;#39;.
Property &amp;#39;[State.Ok]&amp;#39; does not exist on type &amp;#39;{ 0: () =&amp;gt; string; 1: () =&amp;gt; string; }&amp;#39;.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Exceptions Considered Harmful</title><link>https://pianomanfrazier.com/post/exceptions-considered-harmful/</link><pubDate>Fri, 05 Jun 2020 13:32:21 -0600</pubDate><guid>https://pianomanfrazier.com/post/exceptions-considered-harmful/</guid><description>&lt;blockquote&gt;
&lt;p&gt;The reasoning is that I consider exceptions to be no better than “goto’s”, considered harmful since the 1960s, in that they create an abrupt jump from one point of code to another. In fact they are significantly worse than goto’s&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;They are invisible in the source code.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;They create too many possible exit points&lt;/strong&gt; for a function.&lt;/li&gt;
&lt;/ol&gt;
&lt;footer&gt;&lt;span class=&#34;quote-who&#34;&gt; Joel Spolsky at &lt;a href=&#34;https://www.joelonsoftware.com/2003/10/13/13/&#34;&gt;Joel on Software&lt;/a&gt;
&lt;/span&gt;&lt;/footer&gt;&lt;/blockquote&gt;
&lt;p&gt;How do we deal with uncertainty in our code?&lt;/p&gt;
&lt;p&gt;If something goes wrong in our code we need to know about it, preferably without crashing our program. When I come back to the code months later or I am using someone elses code I want the compiler to help me handle errors gracefully.&lt;/p&gt;
&lt;p&gt;Here are several patterns that I have seen, my own code included.&lt;/p&gt;
&lt;h2 id=&#34;pattern-1--return-true-or-false&#34;&gt;Pattern 1 - return true or false&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;function&lt;/span&gt; doWork() &lt;span style=&#34;color:#555&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;boolean&lt;/span&gt; {
&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// do some SIDE EFFECT
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;let&lt;/span&gt; result &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; doWork();
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;this&lt;/span&gt;.some_member_variable &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; result;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;let&lt;/span&gt; success &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; result &lt;span style=&#34;color:#555&#34;&gt;!==&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;null&lt;/span&gt;;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; (success) {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;true&lt;/span&gt;;
} &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;else&lt;/span&gt; {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;false&lt;/span&gt;;
}
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Side effect&#39;s make it harder to reason about what your code does. Pure functions, side effect free functions, are also easier to test. Also if there was a failure you can&#39;t send a message to the function caller.&lt;/p&gt;
&lt;h2 id=&#34;pattern-2--return-null-if-failed&#34;&gt;Pattern 2 - return null if failed&lt;/h2&gt;
&lt;p&gt;In the next examples, let&#39;s assume that our database stuff are synchronous to make things a bit simpler.&lt;/p&gt;
&lt;p&gt;Instead of returning true or false we could return the value or a null value.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; DB from &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;my-synchronous-database&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;function&lt;/span&gt; getUser(id : &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;UserID&lt;/span&gt;) &lt;span style=&#34;color:#555&#34;&gt;:&lt;/span&gt; User &lt;span style=&#34;color:#555&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;null&lt;/span&gt; {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;const&lt;/span&gt; user &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; DB.getUserById(id);
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; (user) {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;return&lt;/span&gt; user;
} &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;else&lt;/span&gt; {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;null&lt;/span&gt;;
}
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is slightly better, now that we don&#39;t have a side effect. However we still have no error message and we better make sure to handle that returned &lt;code&gt;null&lt;/code&gt; value or our program will explode.&lt;/p&gt;
&lt;p&gt;This eliminates the side effect but now creates a new problem.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn&#39;t resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.&lt;/p&gt;
&lt;footer&gt;&lt;span class=&#34;quote-who&#34;&gt; Tony Hoare at QCon London 2009, see &lt;a href=&#34;https://en.wikipedia.org/wiki/Tony_Hoare#Apologies_and_retractions&#34;&gt;wikipedia&lt;/a&gt;
&lt;/span&gt;&lt;/footer&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;pattern-3--throw-exception&#34;&gt;Pattern 3 - throw exception&lt;/h2&gt;
&lt;p&gt;Our other choice is to throw an exception.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; DB from &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;my-synchronous-database&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;function&lt;/span&gt; getUser(id : &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;UserID&lt;/span&gt;) &lt;span style=&#34;color:#555&#34;&gt;:&lt;/span&gt; User {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;const&lt;/span&gt; user &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; DB.getUserById(id);
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; (user) {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;return&lt;/span&gt; user;
} &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;else&lt;/span&gt; {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;throw&lt;/span&gt; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;new&lt;/span&gt; &lt;span style=&#34;color:#366&#34;&gt;Error&lt;/span&gt;(&lt;span style=&#34;color:#c30&#34;&gt;`Cannot find the user by id &lt;/span&gt;&lt;span style=&#34;color:#a00&#34;&gt;${&lt;/span&gt;id&lt;span style=&#34;color:#a00&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;`&lt;/span&gt;);
}
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we have an error message but now we introduced another side effect: the exception. If you don&#39;t catch the exception, in most cases, your program will crash.&lt;/p&gt;
&lt;p&gt;In JavaScript there is no way I can tell by using a function if it will throw or not. Java helps because the tooling will warn you that you are using a throwable function. Still no one likes seeing a &lt;code&gt;nullExceptionPointer&lt;/code&gt; in Java land. Not fun.&lt;/p&gt;
&lt;h2 id=&#34;pattern-4--return-a-result-type&#34;&gt;Pattern 4 - return a result type&lt;/h2&gt;
&lt;p&gt;What if we wanted to both return an error message if something goes wrong and also not introduce side effects.&lt;/p&gt;
&lt;p&gt;This is the &lt;code&gt;Result&lt;/code&gt; type. This is also called the &lt;code&gt;Maybe&lt;/code&gt; type.&lt;/p&gt;
&lt;p&gt;This thing is baked into the standard library of newer programming languages like Rust and Elm. We have &lt;a href=&#34;https://doc.rust-lang.org/std/result/&#34;&gt;std::result&lt;/a&gt; in Rust and the &lt;a href=&#34;https://package.elm-lang.org/packages/elm/core/latest/Result&#34;&gt;Result Type&lt;/a&gt; in Elm. Some newer languages don&#39;t implement exceptions and treat &lt;strong&gt;errors as data&lt;/strong&gt; like &lt;a href=&#34;https://blog.golang.org/go1.13-errors&#34;&gt;Go&lt;/a&gt;, &lt;a href=&#34;https://doc.rust-lang.org/book/ch09-00-error-handling.html&#34;&gt;Rust&lt;/a&gt;, and &lt;a href=&#34;https://guide.elm-lang.org/error_handling/&#34;&gt;Elm&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Since this article is using TypeScript, I&#39;m going to use the library &lt;a href=&#34;https://github.com/supermacro/neverthrow&#34;&gt;neverthrow&lt;/a&gt; but there are others to choose from. This will also work in plain JavaScript too.&lt;/p&gt;
&lt;p&gt;Let&#39;s look at neverthrow&#39;s &lt;code&gt;Result&lt;/code&gt; type.&lt;/p&gt;
&lt;p&gt;From the neverthrow &lt;a href=&#34;https://github.com/supermacro/neverthrow#synchronous-api&#34;&gt;docs&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;type Result&lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt;T, E&lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; Ok&lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt;T, E&lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;|&lt;/span&gt; Err&lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt;T, E&lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;Ok&amp;lt;T, E&amp;gt;&lt;/code&gt;: contains the success value of type &lt;code&gt;T&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Err&amp;lt;T, E&amp;gt;&lt;/code&gt;: contains the failure value of type &lt;code&gt;E&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And here it is in action.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; { Result, ok, err } from &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;neverthrow&amp;#39;&lt;/span&gt;;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;import&lt;/span&gt; DB from &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;my-synchronous-database&amp;#39;&lt;/span&gt;;
type DBError &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;string&lt;/span&gt;; &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// type alias for error message
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;function&lt;/span&gt; getUser(id : &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;UserID&lt;/span&gt;) &lt;span style=&#34;color:#555&#34;&gt;:&lt;/span&gt; Result&lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt;User, DBError&lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;const&lt;/span&gt; user &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; DB.getUserById(id);
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; (user) {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;return&lt;/span&gt; ok(user); &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// return instance of OK
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt; } &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;else&lt;/span&gt; {
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;return&lt;/span&gt; err(&lt;span style=&#34;color:#c30&#34;&gt;`Cannot find the user by id &lt;/span&gt;&lt;span style=&#34;color:#a00&#34;&gt;${&lt;/span&gt;id&lt;span style=&#34;color:#a00&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;`&lt;/span&gt;); &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;// return instance of Err
&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;&lt;/span&gt; }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is an improvement because there are now &lt;strong&gt;no side effects&lt;/strong&gt; and we can return an &lt;strong&gt;error message&lt;/strong&gt; if something goes wrong. I know that when I use this function I will always get a &lt;code&gt;Result&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;const&lt;/span&gt; userID &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt;;
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;const&lt;/span&gt; userResult : &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Result&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;&amp;lt;&lt;/span&gt;User, DBError&lt;span style=&#34;color:#555&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; getUser(userID);
&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; (userResult.isOK()) {
console.log(userResult.value);
} &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;else&lt;/span&gt; {
console.log(userResult.error);
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you try to retrieve &lt;code&gt;userResult.value&lt;/code&gt; before you have checked &lt;code&gt;isOK()&lt;/code&gt; the TS compiler won&#39;t let you. Pretty awesome.&lt;/p&gt;
&lt;h2 id=&#34;javascript-tooling&#34;&gt;JavaScript tooling&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/jonaskello/tslint-immutable&#34;&gt;tslint-immutable&lt;/a&gt; is a plugin for TSlint that has several options to prevent throwing exceptions. See this set of functional programming rules for TSlint &lt;a href=&#34;https://github.com/jonaskello/tslint-immutable#no-throw&#34;&gt;here&lt;/a&gt;. Enable &lt;code&gt;no-throw&lt;/code&gt; and &lt;code&gt;no-try&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;And &lt;a href=&#34;https://github.com/jonaskello/eslint-plugin-functional&#34;&gt;here&lt;/a&gt; is a similar set of rules for eslint.&lt;/p&gt;
&lt;h2 id=&#34;other-libraries-and-languages&#34;&gt;Other libraries and languages&lt;/h2&gt;
&lt;p&gt;These ideas are also being explored in other languages. Here are some libraries I found.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.cppreference.com/w/cpp/utility/optional&#34;&gt;C++ std::optional&lt;/a&gt;, &lt;code&gt;optional&amp;lt;T&amp;gt;&lt;/code&gt;, is a safer way than just returning &lt;code&gt;null&lt;/code&gt;. The optional can be empty or it can hold a value of type &lt;code&gt;T&lt;/code&gt;. It does not hold an error message. This type is also called &lt;code&gt;Maybe&lt;/code&gt; in &lt;a href=&#34;https://guide.elm-lang.org/error_handling/maybe.html&#34;&gt;elm&lt;/a&gt; and elsewhere.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/oktal/result&#34;&gt;C++ Result&lt;/a&gt; is a header only library that implements Rust&#39;s &lt;code&gt;Result&amp;lt;T, E&amp;gt;&lt;/code&gt; type. This type can hold the value or an error.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/dbrgn/result&#34;&gt;Python result&lt;/a&gt; another Rust inspired result type.&lt;/p&gt;
&lt;p&gt;If you want to explore more typed functional programming in TypeScript, check out &lt;a href=&#34;https://gigobyte.github.io/purify/&#34;&gt;purify&lt;/a&gt;, &lt;a href=&#34;https://true-myth.js.org/&#34;&gt;true myth&lt;/a&gt;, or the full featured &lt;a href=&#34;https://gcanti.github.io/fp-ts/&#34;&gt;fp-ts&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Elm Calculator Part 11 - Netlify Deployment</title><link>https://pianomanfrazier.com/post/elm-calculator-book/11-deployment/</link><pubDate>Fri, 22 May 2020 00:00:00 +0000</pubDate><guid>https://pianomanfrazier.com/post/elm-calculator-book/11-deployment/</guid><description>&lt;p&gt;&lt;em&gt;This post is part of a series. If you wish to support my work you can purchase the PDF book on &lt;a href=&#34;https://gum.co/NwMtt&#34;&gt;gumroad&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This project uses Elm version 0.19&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/01-intro/&#34;&gt;Part 1 - Introduction &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/02-setup/&#34;&gt;Part 2 - Project Setup &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/03-styling/&#34;&gt;Part 3 - Add CSS &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/04-basic-operations/&#34;&gt;Part 4 - Basic Operations &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/05-decimals/&#34;&gt;Part 5 - Adding Decimal Support &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/06-negatives/&#34;&gt;Part 6 - Supporting Negative Numbers &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/07-dirty-state/&#34;&gt;Part 7 - Add Dirty State &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/08-keypad-input/&#34;&gt;Part 8 - Support Keypad Input &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/09-keypad-combos/&#34;&gt;Part 9 - Combination Key Input &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/10-testing/&#34;&gt;Part 10 - Testing &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Part 11 - Netlify Deployment (this post)&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;browse:&lt;/em&gt;&lt;/strong&gt; &lt;a href=&#34;https://gitlab.com/pianomanfrazier/elm-calculator/-/tree/master&#34;&gt;https://gitlab.com/pianomanfrazier/elm-calculator/-/tree/master&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;diff:&lt;/em&gt;&lt;/strong&gt; &lt;a href=&#34;https://gitlab.com/pianomanfrazier/elm-calculator/-/commit/e2b92f39f910329dc7b882be9ac2b82b44a09f00&#34;&gt;https://gitlab.com/pianomanfrazier/elm-calculator/-/commit/e2b92f39f910329dc7b882be9ac2b82b44a09f00&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Netlify makes deploying web apps super easy. You point Netlify to a git repository hosted with GitHub, GitLab, or Bitbucket and netlify will build and deploy your project. We will need to add some things to our project so that Netlify will know how to build and deploy our project.&lt;/p&gt;
&lt;h2 id=&#34;add-deploy-script&#34;&gt;Add deploy script&lt;/h2&gt;
&lt;p&gt;The only change we need to add to our project for Netlify is to add a build script. We will add that to the &lt;code&gt;package.json&lt;/code&gt;. Anything added to the scripts section in a &lt;code&gt;package.json&lt;/code&gt; can be run with &lt;code&gt;npm run &amp;lt;script name&amp;gt;&lt;/code&gt;. So in our case we can run &lt;code&gt;npm run build&lt;/code&gt; and npm will build our project to a &lt;code&gt;dist&lt;/code&gt; folder.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;{
&lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;elm-calculator&amp;#34;&lt;/span&gt;,
&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;&amp;#34;scripts&amp;#34;&lt;/span&gt;: {
&lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;&amp;#34;build&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;&amp;lt;do build stuff here&amp;gt;&amp;#34;&lt;/span&gt;
},
&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;...&lt;/span&gt;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here is what we need to do to make a build.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;mkdir -p dist &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# make a dist folder if not already there&lt;/span&gt;
elm make src/Main.elm --optimize --output&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;dist/elm.js &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# make optimized build and output to dist/elm.js&lt;/span&gt;
cp index.html dist &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# copy index.html to build directory&lt;/span&gt;
cp style.css dist &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# copy style.css to build directory&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And then we add it to our &lt;code&gt;package.json&lt;/code&gt; so we can run it with &lt;code&gt;npm run build&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;{
&lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;elm-calculator&amp;#34;&lt;/span&gt;,
&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;&amp;#34;scripts&amp;#34;&lt;/span&gt;: {
&lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;&amp;#34;build&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;mkdir -p dist &amp;amp;&amp;amp; elm make src/Main.elm --optimize --output=dist/elm.js &amp;amp;&amp;amp; cp index.html dist &amp;amp;&amp;amp; cp style.css dist&amp;#34;&lt;/span&gt;
},
&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;...&lt;/span&gt;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;configure-netlify&#34;&gt;Configure Netlify&lt;/h2&gt;
&lt;p&gt;Now we need to point Netlify to our git repository.&lt;/p&gt;
&lt;p&gt;First you need to register for an account on Netlify. After you can log in to your netlify account you need to go to the dashboard at &lt;code&gt;https//app.netlify.com&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;figure&gt;&lt;img src=&#34;https://pianomanfrazier.com/img/elm-calculator/netlify-dashboard.png&#34; alt=&#34;Netlify dashboard&#34;&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;After you click on &amp;quot;New site from Git&amp;quot; you will need to choose you git hosting service. I am hosting this project on GitLab so I will choose that one.&lt;/p&gt;
&lt;p&gt;&lt;figure id=&#34;fig:netlifydashboard&#34;&gt;&lt;img src=&#34;https://pianomanfrazier.com/img/elm-calculator/netlify-choose-git-provider.png&#34; alt=&#34;Choose git provider for Netlify&#34;&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Netlify will ask you to allow permission to access you repositories on the chosen git provider. After you login and give permission you will choose a repository.&lt;/p&gt;
&lt;p&gt;&lt;figure id=&#34;fig:netlifygitprovider&#34;&gt;&lt;img src=&#34;https://pianomanfrazier.com/img/elm-calculator/netlify-choose-repo.png&#34; alt=&#34;Choose git repository for Netlify&#34;&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Next is the most important step. We tell Netlify what command to run to build our project and with directory to deploy from. The build command needs to be set to &lt;code&gt;npm run build&lt;/code&gt; and the publish directory needs to be set to &lt;code&gt;dist&lt;/code&gt;. See &lt;a class=&#34;cite&#34; href=&#34;#fig:netlifydefinebuild&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure id=&#34;fig:netlifychooserepo&#34;&gt;&lt;img src=&#34;https://pianomanfrazier.com/img/elm-calculator/netlify-define-build.png&#34; alt=&#34;Define Netlify build&#34;&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Click on &amp;quot;deploy site&amp;quot;. If all goes well you should see that your build is in queue waiting to be built.&lt;/p&gt;
&lt;p&gt;When it is ready you can click on the link provided and see you app live on the internet to share with the world.&lt;/p&gt;
&lt;p&gt;&lt;figure id=&#34;fig:netlifydefinebuild&#34;&gt;&lt;img src=&#34;https://pianomanfrazier.com/img/elm-calculator/netlify-deployed.png&#34; alt=&#34;App deployed on Netlify&#34;&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;If you want a custom Netlify sub-domain name click on &amp;quot;Site settings&amp;quot;. Then click on &amp;quot;Change site name&amp;quot;. You can then change the name to something like &amp;quot;elm-calculator&amp;quot;. Your project would then be made available at &lt;a href=&#34;https://elm-calculator.netlify.com&#34;&gt;https://elm-calculator.netlify.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;figure id=&#34;fig:netlifydeployed&#34;&gt;&lt;img src=&#34;https://pianomanfrazier.com/img/elm-calculator/netlify-change-name.png&#34; alt=&#34;Change Netlify sub domain name&#34;&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id=&#34;fig:netlifychangename&#34;&gt;We&#39;re done&lt;/h2&gt;
&lt;p&gt;Congratulations for making it to the end of this project. I learned a lot putting this together and I hope you learned a lot as well.&lt;/p&gt;
&lt;p&gt;Together we build an Elm application from the ground up and deployed it to netlify for all the world to see.&lt;/p&gt;</description></item><item><title>Elm Calculator Part 10 - Testing</title><link>https://pianomanfrazier.com/post/elm-calculator-book/10-testing/</link><pubDate>Fri, 15 May 2020 00:00:00 +0000</pubDate><guid>https://pianomanfrazier.com/post/elm-calculator-book/10-testing/</guid><description>&lt;p&gt;&lt;em&gt;This post is part of a series. If you wish to support my work you can purchase the PDF book on &lt;a href=&#34;https://gum.co/NwMtt&#34;&gt;gumroad&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This project uses Elm version 0.19&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/01-intro/&#34;&gt;Part 1 - Introduction &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/02-setup/&#34;&gt;Part 2 - Project Setup &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/03-styling/&#34;&gt;Part 3 - Add CSS &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/04-basic-operations/&#34;&gt;Part 4 - Basic Operations &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/05-decimals/&#34;&gt;Part 5 - Adding Decimal Support &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/06-negatives/&#34;&gt;Part 6 - Supporting Negative Numbers &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/07-dirty-state/&#34;&gt;Part 7 - Add Dirty State &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/08-keypad-input/&#34;&gt;Part 8 - Support Keypad Input &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/09-keypad-combos/&#34;&gt;Part 9 - Combination Key Input &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Part 10 - Testing (this post)&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pianomanfrazier.com/post/elm-calculator-book/11-deployment/&#34;&gt;Part 11 - Netlify Deployment &lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;browse:&lt;/em&gt;&lt;/strong&gt; &lt;a href=&#34;https://gitlab.com/pianomanfrazier/elm-calculator/-/tree/master&#34;&gt;https://gitlab.com/pianomanfrazier/elm-calculator/-/tree/master&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;diff:&lt;/em&gt;&lt;/strong&gt; &lt;a href=&#34;https://gitlab.com/pianomanfrazier/elm-calculator/-/commit/c5c32b5c0566b8034fc723e8e0f7ffdf2f6db70c&#34;&gt;https://gitlab.com/pianomanfrazier/elm-calculator/-/commit/c5c32b5c0566b8034fc723e8e0f7ffdf2f6db70c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://package.elm-lang.org/packages/elm-explorations/test/latest&#34;&gt;elm-test&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://package.elm-lang.org/packages/avh4/elm-program-test/latest&#34;&gt;elm-program-test&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Note: ellie-app does not support splitting out your code into modules and files. So there is no ellie link for this chapter.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We will be using a newer Elm package called &lt;a href=&#34;https://package.elm-lang.org/packages/avh4/elm-program-test/latest/&#34;&gt;elm-program-test&lt;/a&gt;. It allows us to test our application as a whole. It will stand up the application and allow us to test it as if a user were clicking through the application.&lt;/p&gt;
&lt;h2 id=&#34;some-refactoring&#34;&gt;Some Refactoring&lt;/h2&gt;
&lt;p&gt;In order to test our program we need to expose some of our functions in &lt;code&gt;Main.elm&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-elm&#34; data-lang=&#34;elm&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;module &lt;/span&gt;&lt;span style=&#34;color:#0a8;font-weight:bold&#34;&gt;Main&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;exposing&lt;/span&gt; (&lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Model&lt;/span&gt;, &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Msg&lt;/span&gt;, &lt;span style=&#34;color:#033&#34;&gt;init&lt;/span&gt;, &lt;span style=&#34;color:#033&#34;&gt;main&lt;/span&gt;, &lt;span style=&#34;color:#033&#34;&gt;update&lt;/span&gt;, &lt;span style=&#34;color:#033&#34;&gt;view&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We also need to make our elm program use &lt;code&gt;Browser.document&lt;/code&gt; instead of &lt;code&gt;Browser.element&lt;/code&gt; since we will be using &lt;code&gt;ProgramTest.createDocument&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Elm has different ways to create a program. &lt;code&gt;Browser.element&lt;/code&gt; is good for creating a small elm application that you embed into the page on a specific DOM node. What if you want Elm to take over the whole page? That is what &lt;code&gt;Browser.document&lt;/code&gt; is for. See the &lt;a href=&#34;https://guide.elm-lang.org/webapps/&#34;&gt;elm-guide&lt;/a&gt; for more information about &lt;code&gt;Browser.element&lt;/code&gt; and &lt;code&gt;Browser.document&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: Since creating this book, I have since learned that you can use &lt;code&gt;ProgramTest.createElement&lt;/code&gt; instead and we wouldn&#39;t need to do this refactor.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Refactoring is lovely in Elm. Our first step is to start at the highest level of our refactor and let the compiler tell us what to change. So start by changing the &lt;code&gt;main&lt;/code&gt; function to return a &lt;code&gt;Browser.document&lt;/code&gt; instead of a &lt;code&gt;Browser.element&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The only thing we need to change for this refactor is the &lt;code&gt;view&lt;/code&gt; function to return a &lt;code&gt;Browser.Document&lt;/code&gt; instead of &lt;code&gt;Html&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The difference with &lt;code&gt;Browser.Document&lt;/code&gt; is that the view function now needs a record with a &lt;code&gt;title&lt;/code&gt; and a &lt;code&gt;body&lt;/code&gt; field. We can place our previous view html stuffs inside the body field.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-elm&#34; data-lang=&#34;elm&#34;&gt;&lt;span style=&#34;color:#033&#34;&gt;view&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Model&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Browser&lt;/span&gt;&lt;span style=&#34;color:#c0f&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Document&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Msg&lt;/span&gt;
&lt;span style=&#34;color:#033&#34;&gt;view&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;model&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;=&lt;/span&gt;
{ &lt;span style=&#34;color:#033&#34;&gt;title&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;Elm Calculator&amp;#34;&lt;/span&gt;
, &lt;span style=&#34;color:#033&#34;&gt;body&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;=&lt;/span&gt;
[ &lt;span style=&#34;color:#033&#34;&gt;div&lt;/span&gt; []
[ &lt;span style=&#34;color:#033&#34;&gt;h&lt;/span&gt;&lt;span style=&#34;color:#f60&#34;&gt;1&lt;/span&gt; [ &lt;span style=&#34;color:#033&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;h1&amp;#34;&lt;/span&gt; ] [ &lt;span style=&#34;color:#033&#34;&gt;text&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;RPN Calculator&amp;#34;&lt;/span&gt; ]
, &lt;span style=&#34;color:#c0f&#34;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;write-the-test&#34;&gt;Write the test&lt;/h2&gt;
&lt;p&gt;First we need to install everything we need. We need the &lt;code&gt;elm-test&lt;/code&gt; command line program because we need something to launch and execute our tests. This is our test runner if you have used something like pytest.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;npm install --save-dev elm-test&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We also need to install the corresponding elm packages as well.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;elm install elm-explorations/test
elm install avh4/elm-program-test&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To get a simple example test run &lt;code&gt;elm-test init&lt;/code&gt; in your project folder.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;npx elm-test init&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now run the test you just created.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;npx elm-test&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You should get a test report.&lt;/p&gt;
&lt;p&gt;Create a new file in the tests directory called &lt;code&gt;CalculatorTest.elm&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The test is short (less than 40 lines of code). I&#39;ll walk through the most interesting part.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-elm&#34; data-lang=&#34;elm&#34;&gt;&lt;span style=&#34;color:#033&#34;&gt;all&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#078;font-weight:bold&#34;&gt;Test&lt;/span&gt;
&lt;span style=&#34;color:#033&#34;&gt;all&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;=&lt;/span&gt;
&lt;span style=&#34;color:#033&#34;&gt;describe&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;basic arithmetic&amp;#34;&lt;/span&gt;
[ &lt;span style=&#34;color:#033&#34;&gt;test&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;20 × 3 = 60&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#c0f&#34;&gt;&amp;lt;|&lt;/span&gt;
&lt;span style=&#34;color:#c0f&#34;&gt;\&lt;/span&gt;() &lt;span style=&#34;color:#c0f&#34;&gt;-&amp;gt;&lt;/span&gt;
&lt;span style=&#34;color:#033&#34;&gt;start&lt;/span&gt;
&lt;span style=&#34;color:#c0f&#34;&gt;|&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;clickCalcBtn&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;2&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#c0f&#34;&gt;|&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;clickCalcBtn&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#c0f&#34;&gt;|&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;clickCalcBtn&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;←&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#c0f&#34;&gt;|&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;clickCalcBtn&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;3&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#c0f&#34;&gt;|&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;clickCalcBtn&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;×&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#c0f&#34;&gt;|&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;expectViewHas&lt;/span&gt;
[ &lt;span style=&#34;color:#033&#34;&gt;text&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;60&amp;#34;&lt;/span&gt;
]
]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This simulates a user clicking on the number and operator buttons. It then checks that the number 60 is somewhere on the page. Try playing with this and adding another test.&lt;/p&gt;
&lt;p&gt;The next and last chapter will cover deploying our Elm application to netlify. If you got this far, congratulations! We&#39;re almost finished. I get a lot of satisfaction with web projects because they are so easy to share with the world. I&#39;ll show you how in the next chapter.&lt;/p&gt;</description></item></channel></rss>