<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Stephen Hara</title>
    <description>The latest articles on DEV Community by Stephen Hara (@tarsir).</description>
    <link>https://dev.to/tarsir</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F215907%2Fa04f3cd1-63b4-4925-9f96-e2d677543645.png</url>
      <title>DEV Community: Stephen Hara</title>
      <link>https://dev.to/tarsir</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tarsir"/>
    <language>en</language>
    <item>
      <title>Intro to the Terminal: Public Draft Available!</title>
      <dc:creator>Stephen Hara</dc:creator>
      <pubDate>Tue, 27 Aug 2024 15:29:21 +0000</pubDate>
      <link>https://dev.to/tarsir/intro-to-the-terminal-public-draft-available-2gcc</link>
      <guid>https://dev.to/tarsir/intro-to-the-terminal-public-draft-available-2gcc</guid>
      <description>&lt;p&gt;I'd like to announce that the public draft of my ebook, &lt;a href="https://tarsir.github.io/gentle-intro-terminal/why-read-this-book.html" rel="noopener noreferrer"&gt;A Gentle Introduction to the Terminal&lt;/a&gt;, is now available!&lt;/p&gt;

&lt;p&gt;It has some WIP pages that I still need to mark more clearly, but there's still, I think, quite a bit of good stuff for folks new to the terminal and the command line in general!&lt;/p&gt;

&lt;p&gt;If you have comments or other feedback, please leave a comment here, or drop me a DM/mention on &lt;a href="https://bsky.app/profile/tarsir.bsky.social" rel="noopener noreferrer"&gt;Bluesky&lt;/a&gt; or &lt;a href="https://x.com/StephenHaraDev" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>cli</category>
      <category>terminal</category>
      <category>bash</category>
    </item>
    <item>
      <title>No-Spoiler FF14 Progress Checks</title>
      <dc:creator>Stephen Hara</dc:creator>
      <pubDate>Tue, 16 Jul 2024 08:43:27 +0000</pubDate>
      <link>https://dev.to/tarsir/no-spoiler-ff14-progress-checks-2dhi</link>
      <guid>https://dev.to/tarsir/no-spoiler-ff14-progress-checks-2dhi</guid>
      <description>&lt;p&gt;As I've been playing the new FF14 expansion, I wanted to see if I could check my progress without spoilers. As it turns out, you can do it pretty easily with a bit of Javascript and &lt;a href="https://jquery.com" rel="noopener noreferrer"&gt;JQuery&lt;/a&gt;! &lt;/p&gt;

&lt;p&gt;First, open &lt;a href="https://ffxiv.consolegameswiki.com/wiki/Dawntrail_Main_Scenario_Quests" rel="noopener noreferrer"&gt;this page&lt;/a&gt;, which has a list of all the quests in the new expansion. &lt;/p&gt;

&lt;p&gt;Second, open up the developer tools for your browser. You can right-click and find the option that way, or maybe the shortcut Ctrl+Shift+C works like it does for mine.&lt;/p&gt;

&lt;p&gt;Next, open the console tab of the developer tools. This will open a little prompt you can use as a Javascript REPL!&lt;/p&gt;

&lt;p&gt;We're going to build a JQuery selector to find the elements we want. JQuery is a Javascript library that allows you to filter HTML elements on a web page based on class, ID, element type, and more.&lt;/p&gt;

&lt;p&gt;Ultimately, my approach uses the current quest name as the "search query". We can find the position of the quest name in the list of elements and divide that by the total number of quests in Dawntrail to get a percentage of our progress.&lt;/p&gt;

&lt;p&gt;By inspecting the HTML, we can find a few clues to help us craft a good query. The first is that the quests all appear in HTML tables, so we can probably use &lt;code&gt;tr&lt;/code&gt; and &lt;code&gt;td&lt;/code&gt; as starting points.&lt;/p&gt;

&lt;p&gt;The summary of the page mentions there are 100 quests, so to check how our query is coming along, we can make sure there are 100 elements in our result. Let's try this:&lt;br&gt;
&lt;code&gt;$('tr').size()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Not quite right, as this returns 111, meaning we captured 11 more elements than we expect. But looking at the tables, there's an extra row on each of them that might be causing problems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8obypc2dm59uootqtgwt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8obypc2dm59uootqtgwt.png" alt="Screenshot of the first sub-table of quests" width="800" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To keep the header of each table from being captured, we can use a pseudo-class - 2 of them, in fact!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tr:not(:first-child)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that gives us 100! The pseudo-classes are &lt;code&gt;:not&lt;/code&gt; and &lt;code&gt;:first-child&lt;/code&gt;. &lt;code&gt;:not&lt;/code&gt; takes another selector, including pseudo-classes, as an argument and filters them out of the results. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;:first-child&lt;/code&gt; takes the first matching element of a group from the same parent. It's easier to understand with some examples, so I'd recommend checking the MDN page for more. &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:first-child" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/CSS/:first-child&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Combined, &lt;code&gt;tr:not(:first-child)&lt;/code&gt; means "when a node has multiple &lt;code&gt;tr&lt;/code&gt; children, capture all of them except the first one". In terms of the quest table rows, this means we skip the header and only end up with the quest rows!&lt;/p&gt;

&lt;p&gt;Within each &lt;code&gt;tr&lt;/code&gt; row is a group of &lt;code&gt;td&lt;/code&gt; cells: they include the quest name, the "type", level, quest giver, any unlocks, and any rewards.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdfqy7potgxhlcwq7b0om.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdfqy7potgxhlcwq7b0om.png" alt="Single quest row with boxes indicating the different cells" width="800" height="47"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quite convenient that once again, we only want to pick out the quest name - we can use &lt;code&gt;:first-child&lt;/code&gt; again!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tr:not(:first-child) &amp;gt; td:first-child&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, we get 100, meaning we didn't lose anything with this addition. The last thing we need is to pick out the quest name. We can't do this directly from these &lt;code&gt;td&lt;/code&gt; elements, but each element has an &lt;code&gt;a&lt;/code&gt; tag.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7nycotx6kbkqtqh39edo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7nycotx6kbkqtqh39edo.png" alt="Anchor tag for a single quest" width="800" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can capture these anchor elements in our selector:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tr:not(:first-child) &amp;gt; td:first-child &amp;gt; a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then we can use the JQuery function &lt;code&gt;index(selector)&lt;/code&gt; to find the index of a matching selector. In this case, we'll use an attribute selector on the &lt;code&gt;title&lt;/code&gt; attribute.&lt;/p&gt;

&lt;p&gt;Putting this together, we can do something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tr:not(:first-child) &amp;gt; td:first-child &amp;gt; a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[title="A Saga in Stone"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives us 3, which is a classic off-by-one error. Since &lt;code&gt;index&lt;/code&gt; looks at it like an array, we can add 1 to give us the position instead of the 0-based index.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tr:not(:first-child) &amp;gt; td:first-child &amp;gt; a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[title="A Saga in Stone"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meaning if you're on the quest "A Saga in Stone", you're on the 4th quest of the Dawntrail quest line!&lt;/p&gt;

</description>
      <category>jquery</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Easy Approximations with Monte Carlo Simulations</title>
      <dc:creator>Stephen Hara</dc:creator>
      <pubDate>Tue, 25 Jun 2024 07:43:22 +0000</pubDate>
      <link>https://dev.to/tarsir/easy-approximations-with-monte-carlo-simulations-4oia</link>
      <guid>https://dev.to/tarsir/easy-approximations-with-monte-carlo-simulations-4oia</guid>
      <description>&lt;p&gt;Hi there! Today, I was writing a different blog post, but it started getting pretty long, so I decided to pivot and talk about something a little simpler: Monte Carlo simulations!&lt;/p&gt;

&lt;p&gt;I first learned about the &lt;a href="https://en.wikipedia.org/wiki/Monte_Carlo_method"&gt;Monte Carlo&lt;/a&gt; method of calculating answers to probabilistic situations in university as part of a class on numerical methods. To quickly summarize: given some scenario with non-trivial but easily understood base probabilities, rather than going through the complicated process of determining the concrete answer of any particular question, in a Monte Carlo simulation you instead make a large number of observations based on the known probabilities to answer the question.&lt;/p&gt;

&lt;p&gt;In that class, we used it to estimate integrals for a function over a specified range. Building up to that can be done in a few high-level steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, we need to be able to calculate the function;&lt;/li&gt;
&lt;li&gt;Then, we need to take randomized samples within the range;&lt;/li&gt;
&lt;li&gt;Last, we need to accumulate a large number of samples and average them, then multiply that by the range&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The average of all those samples will be the integral over the range. Let's build a Monte Carlo simulation for the square function: $f(x) = x^2$&lt;/p&gt;

&lt;p&gt;First, let's make our function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple enough! Let's also try to call it a number of times:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// results in...&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="mi"&gt;49&lt;/span&gt;
&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;
&lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="mi"&gt;81&lt;/span&gt;
&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cool! Next, how can we take randomized samples? We'll need to use the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random"&gt;Math.random()&lt;/a&gt; function in JS to get a random number between 0 and 1. Since we'll likely want to use a different range - say, -10 to 10 - we have to do a little bit of finagling and math.&lt;/p&gt;

&lt;p&gt;We can use the random number as a measure of &lt;em&gt;how far into the range&lt;/em&gt; we want to sample. Then, we multiply the random number by the total range, and add the lower limit of our range to that result, and that will give us the value for "x" we sample.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lowerLimit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;upperLimit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;upperLimit&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;lowerLimit&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sample&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lowerLimit&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// example output&lt;/span&gt;
&lt;span class="mf"&gt;0.2442285408573639&lt;/span&gt; &lt;span class="mf"&gt;0.059647580169317066&lt;/span&gt;
&lt;span class="mf"&gt;3.845802381476089&lt;/span&gt; &lt;span class="mf"&gt;14.790195957367157&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.5799238892346903&lt;/span&gt; &lt;span class="mf"&gt;0.33631171730508935&lt;/span&gt;
&lt;span class="mf"&gt;8.47264325104629&lt;/span&gt; &lt;span class="mf"&gt;71.78568365950024&lt;/span&gt;
&lt;span class="mf"&gt;8.705075937763862&lt;/span&gt; &lt;span class="mf"&gt;75.77834708223538&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.4103879134353559&lt;/span&gt; &lt;span class="mf"&gt;1.9891940663645369&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;5.962861318180601&lt;/span&gt; &lt;span class="mf"&gt;35.555715099854496&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;7.21220376021984&lt;/span&gt; &lt;span class="mf"&gt;52.01588307892919&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;5.478958693659344&lt;/span&gt; &lt;span class="mf"&gt;30.0189883668253&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;7.5575637333194035&lt;/span&gt; &lt;span class="mf"&gt;57.11676958318472&lt;/span&gt;
&lt;span class="mf"&gt;2.1570867021239906&lt;/span&gt; &lt;span class="mf"&gt;4.653023040480154&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! We're almost there. Now we just need to add up all the samples, average, and multiply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// set some of our variables up here&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sampleCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lowerLimit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;upperLimit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;upperLimit&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;lowerLimit&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;sampleCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// get the sample location...&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sample&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lowerLimit&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// and add the sample result to the rolling sum&lt;/span&gt;
  &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// make a rectangle (as described below)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;sampleCount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// technically 2000/3 but #fractionsincode&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expectedAnswer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;666.6666667&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// find out how wrong the estimate is&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expectedAnswer&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// make it a percentage for clearer presentation&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errorPercent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;expectedAnswer&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// some pretty output&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Approximate area under the curve for range [&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;lowerLimit&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;upperLimit&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;]: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Error of &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;errorPercent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%)`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// here's a couple of runs&lt;/span&gt;
&lt;span class="nx"&gt;Approximate&lt;/span&gt; &lt;span class="nx"&gt;area&lt;/span&gt; &lt;span class="nx"&gt;under&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;curve&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="mf"&gt;667.6623214481579&lt;/span&gt;
&lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="mf"&gt;0.9956547481579037&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.14934821221621816&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;Approximate&lt;/span&gt; &lt;span class="nx"&gt;area&lt;/span&gt; &lt;span class="nx"&gt;under&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;curve&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="mf"&gt;666.6071783517447&lt;/span&gt;
&lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="mf"&gt;0.05948834825528593&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.008923252237846726&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;Approximate&lt;/span&gt; &lt;span class="nx"&gt;area&lt;/span&gt; &lt;span class="nx"&gt;under&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;curve&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="mf"&gt;663.6055831735898&lt;/span&gt;
&lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="mf"&gt;3.0610835264101297&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.45916252893856135&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's pretty much it! As you can see, it's not perfect, but it's not &lt;em&gt;too&lt;/em&gt; wrong if you just need to get an estimate. Plus, it's pretty simple!&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Monte Carlo simulation is a great way to explore problem spaces. I've previously used it to simulate leveling gathering jobs in Final Fantasy 14 as I &lt;a href="https://www.stephenhara.com/posts/monte_carlo"&gt;talked about in a blog post a couple years ago&lt;/a&gt;. Unfortunately the code is missing and I'm not sure where it is, but once I find it I'll update that post!&lt;/p&gt;

&lt;p&gt;If you enjoyed this post, why not &lt;a href="https://stephenhara.ck.page/profile"&gt;subscribe to my newsletter?&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Appendix: Why Multiply By the Range?
&lt;/h2&gt;

&lt;p&gt;I sorta forgot that you need to multiply by the range when I started working on this post, and it wasn't quite clear to me why the initial answers were wrong, so I figure it might be helpful to re-hash my re-learning. For posterity!&lt;/p&gt;

&lt;p&gt;Let's start with a very crude sketch of our function, $x^2$:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5jpcdvt2v9juqsfox9r6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5jpcdvt2v9juqsfox9r6.png" alt="Crude sketch of y=x^2" width="673" height="585"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we do the sampling process, we end up getting the &lt;em&gt;height of the function&lt;/em&gt; at a bunch of random spots on the x-axis:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo44b3331p2i1pnar28c6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo44b3331p2i1pnar28c6.png" alt="Sampling process on the function" width="673" height="585"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we then divide by the number of samples, we get the estimated average height of the function across the range. In order to get the estimated area, we need to turn it into a rectangle, so we multiply it by the range - or, the length of the desired rectangle.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3zumgcok1s0qqr3w4hl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3zumgcok1s0qqr3w4hl.png" alt="The " width="673" height="585"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>math</category>
    </item>
    <item>
      <title>Some Books to Upskill Communication For Software Engineers</title>
      <dc:creator>Stephen Hara</dc:creator>
      <pubDate>Mon, 17 Jun 2024 14:21:39 +0000</pubDate>
      <link>https://dev.to/tarsir/some-books-to-upskill-communication-for-software-engineers-4mdp</link>
      <guid>https://dev.to/tarsir/some-books-to-upskill-communication-for-software-engineers-4mdp</guid>
      <description>&lt;p&gt;&lt;em&gt;(Full disclosure: This post includes affiliate links which, if you click through and purchase the product, will earn me a small commission. This helps support my writing so I can keep writing helpful posts like this!)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When we write code and build software, we're not just communicating to the computer the instructions we want it to perform. We're also communicating various intents to our future selves and our team members:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What the system should do now, as the code available to be executed&lt;/li&gt;
&lt;li&gt;What the system should do in the future, as code hidden behind feature flags and other forms of prevented execution&lt;/li&gt;
&lt;li&gt;How we want the code to grow with the system, as architectures and design patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ultimately, we are doing an awful lot of communicating in our work as developers. And "work on communication" is pretty common advice, but it's hard to find specifics. So I'd like to share 3 books I found incredibly helpful for my growth and improving my communication skills!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Science of Effective Communication
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://amzn.to/4crQ0Zb"&gt;The Science of Effective Communication by Ian Tuhovsky&lt;/a&gt; is a general book on communication and how it's used to build and maintain connections of all kinds. It goes over virtually all aspects of communication, from the first chapter about listening to the last chapter about interview skills. &lt;/p&gt;

&lt;p&gt;In between, it addresses how to keep conversations alive; how to handle discussions with high emotions; persuasion and why you shouldn't feel bad about trying to be a little persuasive; complaining; communicating with non-native speakers and hearing-impaired speakers; and a whole lot more.&lt;/p&gt;

&lt;p&gt;Software developers spend a lot of time talking to other people: our team, our manager, their manager, the product manager, HR, recruiters, clients, and on and on. This book is full of actionable tips and ways to think about thoughtful conversations so you can improve your career, improve your relationships be it business or personal, and carry yourself with more confidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing for Busy Readers
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://amzn.to/3VLhLGg"&gt;Writing for Busy Readers by Todd Rogers and Jessica Lasky-fink&lt;/a&gt; is specifically about writing and communicating through text and accompanying media. The advice is based on studies and real successful work by the authors in increasing outcomes for clients like schools, political parties, and enterprises. &lt;/p&gt;

&lt;p&gt;The main conceit of the book is that readers in today's world are &lt;em&gt;really busy&lt;/em&gt;. What that means is you need to reduce the barriers of understanding your writing as much as possible, with strategies like using simple language, using layout and formatting effectively, and make your intended outcomes easy for the reader.&lt;/p&gt;

&lt;p&gt;The easiest way for software developers to increase our &lt;a href="https://www.pathtostaff.com/blog/20231214-visibility"&gt;impact and visibility&lt;/a&gt; is by writing. It leaves a permanent mark on the organization that says "I contributed to our body of knowledge or systems of value". Whether it be design docs, proposals, code documents, or just a Slack message asking for thoughts, writing is a critical skill to develop for developers.&lt;/p&gt;

&lt;p&gt;The authors also offer several &lt;a href="https://writingforbusyreaders.com/resources/"&gt;free resources&lt;/a&gt; on the book's website, so you can get a lot of benefit before buying the book as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docs for Developers
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://amzn.to/4c4n4Xb"&gt;Docs for Developers by Jared Bhatti, Sarah Corleissen, Jen Lambourne, David Nunez, Heidi Waterhouse&lt;/a&gt; is more specifically about writing documentation, but documentation is an incredible exercise in effective communication. You can't know what the right documentation to write is without knowing what your reader needs, and that's a foundation of communication.&lt;/p&gt;

&lt;p&gt;Much like software products, documentation requires planning, drafting and revision, and evolution and maintenance. The book goes through these steps from the perspective of a fictional cuddly dog-to-human translation service called Corg.ly. It covers the pre-work, the work itself, and the continuous aspects of documentation, as well as how to include code and visual content, publishing, organization, and more.&lt;/p&gt;

&lt;p&gt;One of the more important takeaways from this book for me was the idea that there are different kinds of documentation: tutorials, API references, glossaries, etc. It's more helpful to decide on one for each piece of documentation than to try and do multiple things with one piece. Similar to the idea of &lt;a href="https://en.wikipedia.org/wiki/Separation_of_concerns"&gt;separation of concerns&lt;/a&gt;. There's a &lt;a href="https://www.writethedocs.org/videos/eu/2017/the-four-kinds-of-documentation-and-why-you-need-to-understand-what-they-are-daniele-procida/"&gt;great talk by Daniele Procida&lt;/a&gt; that has the same idea, but presented differently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Communication is an integral part of our work as software developers, and we should strive to improve our skills in communication as much as we should strive to improve our technical skills. I thought these books were all tremendously helpful, and I think if you haven't read them, you'd be doing yourself a great favor if you did!&lt;/p&gt;

</description>
      <category>books</category>
      <category>communication</category>
    </item>
  </channel>
</rss>
