<?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: Neeraj Kashyap</title>
    <description>The latest articles on DEV Community by Neeraj Kashyap (@zomglings).</description>
    <link>https://dev.to/zomglings</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%2F512380%2F4a68320d-d091-4419-b097-a675b1fea2df.jpeg</url>
      <title>DEV Community: Neeraj Kashyap</title>
      <link>https://dev.to/zomglings</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zomglings"/>
    <language>en</language>
    <item>
      <title>See the errors your users are experiencing. From your IDE. Live.</title>
      <dc:creator>Neeraj Kashyap</dc:creator>
      <pubDate>Thu, 06 May 2021 18:47:41 +0000</pubDate>
      <link>https://dev.to/zomglings/see-the-errors-your-users-are-experiencing-from-your-ide-live-19id</link>
      <guid>https://dev.to/zomglings/see-the-errors-your-users-are-experiencing-from-your-ide-live-19id</guid>
      <description>&lt;p&gt;If you have built a library, command line tool, or API, Bugout helps you understand:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Who your users are&lt;/li&gt;
&lt;li&gt;How they are using your software&lt;/li&gt;
&lt;li&gt;What errors they experience&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you &lt;a href="https://bugout.dev/app/public/d550eb09-7c85-4fdc-b687-9f04b730f6e1/entries/07b21356-2e3f-4fa9-bd77-764fe903a640?sidebar=true" rel="noopener noreferrer"&gt;set up an integration&lt;/a&gt; and &lt;a href="https://github.com/bugout-dev/humbug" rel="noopener noreferrer"&gt;instrument your code&lt;/a&gt;, you can access your user reports at &lt;a href="https://bugout.dev" rel="noopener noreferrer"&gt;https://bugout.dev&lt;/a&gt;. This gives you a live view of what your users are experiencing:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs3.amazonaws.com%2Fstatic.simiotics.com%2Fbugout-dev-docs%2Fhumbug-journal.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs3.amazonaws.com%2Fstatic.simiotics.com%2Fbugout-dev-docs%2Fhumbug-journal.png" alt="Live view of user reports"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This week, we released the latest version of the &lt;a href="https://marketplace.visualstudio.com/items?itemName=bugout.Bugout" rel="noopener noreferrer"&gt;Bugout VSCode extension&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now you can see the latest issues your users have had from VSCode. Just hover over an exception to see how many users were affected by it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo3oz8m6ngdl3p6oam301.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo3oz8m6ngdl3p6oam301.png" alt="Hover over an exception to see how many users were affected by it"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can even click through to see their stack traces:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs3.amazonaws.com%2Fstatic.simiotics.com%2Fbugout-dev-docs%2Fbugout-vscode-exception-traceback.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs3.amazonaws.com%2Fstatic.simiotics.com%2Fbugout-dev-docs%2Fbugout-vscode-exception-traceback.png" alt="See your users' stack traces right in VSCode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is just a taste of things to come. If you use VSCode and would like to try this out, Bugout supports Python, Go, and Javascript.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://bugout.dev/register" rel="noopener noreferrer"&gt;Sign up and get started!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>showdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Humbug: Usage and crash reports for Python developer tools</title>
      <dc:creator>Neeraj Kashyap</dc:creator>
      <pubDate>Thu, 18 Mar 2021 23:44:55 +0000</pubDate>
      <link>https://dev.to/zomglings/usage-and-crash-reports-for-python-developer-tools-h4k</link>
      <guid>https://dev.to/zomglings/usage-and-crash-reports-for-python-developer-tools-h4k</guid>
      <description>&lt;p&gt;Developer tools are unlike any other kind of software. All your users are power users. This blurs the line between your users and your code.&lt;/p&gt;

&lt;p&gt;GitHub issues and Slack conversations are a poor guide to real usage of your software. Only a small proportion of the people who ever used your tool will be motivated enough to speak with you through these channels. The issues that these users have may not be representative of the real issues - the ones, for example, that drive people away from your "Getting started" guide.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://bugout.dev" rel="noopener noreferrer"&gt;https://bugout.dev&lt;/a&gt;, we are building a huge knowledge base of bugfixes to help developers overcome issues with the tools and libraries they depend on. We are also trying to help developer tool maintainers gain a better understanding of how their users use their software.&lt;/p&gt;

&lt;p&gt;We have taken a big step forward this week with the release of &lt;a href="https://github.com/bugout-dev/humbug" rel="noopener noreferrer"&gt;Humbug&lt;/a&gt;, which helps developer tool maintainers collect usage and crash reports from their users &lt;strong&gt;only with their full consent&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is a short video showing how to use Humbug in your Python developer tool:&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/-k2c8o_sXC4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Find out more about how to set up Humbug on the GitHub repository:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/bugout-dev" rel="noopener noreferrer"&gt;
        bugout-dev
      &lt;/a&gt; / &lt;a href="https://github.com/bugout-dev/humbug" rel="noopener noreferrer"&gt;
        humbug
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Get usage metrics and crash reports for your API, library, or command line tool.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;humbug&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Humbug helps you understand what keeps users coming back to your developer tool as well as any
friction they experience.&lt;/p&gt;
&lt;p&gt;Humbug lets you collect basic system information and crash reports while respecting your users'
privacy. In addition to getting reports, you get to be &lt;a href="https://gdpr-info.eu/" rel="nofollow noopener noreferrer"&gt;GDPR&lt;/a&gt;-compliant from
day one.&lt;/p&gt;
&lt;p&gt;Humbug is currently available in the following programming languages:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/bugout-dev/humbug./python" rel="noopener noreferrer"&gt;Python&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System information report&lt;/li&gt;
&lt;li&gt;Error traceback report&lt;/li&gt;
&lt;li&gt;Packages available in the current Python process report&lt;/li&gt;
&lt;li&gt;Logs report&lt;/li&gt;
&lt;li&gt;Environment variables report&lt;/li&gt;
&lt;li&gt;Custom report with full content control&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/bugout-dev/humbug./go" rel="noopener noreferrer"&gt;Go&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System information report&lt;/li&gt;
&lt;li&gt;Panic report&lt;/li&gt;
&lt;li&gt;Custom report with full content control&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/bugout-dev/humbug./javascript" rel="noopener noreferrer"&gt;Javascript&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;System information report&lt;/li&gt;
&lt;li&gt;Error traceback report&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you would like support for another programming language, please &lt;a href="https://github.com/bugout-dev/humbug/issues/new" rel="noopener noreferrer"&gt;create an issue&lt;/a&gt;.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Using Humbug&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Setup&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;Follow the instructions in the &lt;a href="https://bugout.dev/app/public/d550eb09-7c85-4fdc-b687-9f04b730f6e1/entries/07b21356-2e3f-4fa9-bd77-764fe903a640" rel="nofollow noopener noreferrer"&gt;Getting started with usage and crash reporting&lt;/a&gt; guide.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h4 class="heading-element"&gt;From development to production&lt;/h4&gt;

&lt;/div&gt;
&lt;p&gt;We recommend generating one token for development and testing and using different…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/bugout-dev/humbug" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Go and Javascript support are coming soon!&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>python</category>
      <category>analytics</category>
      <category>devrel</category>
    </item>
    <item>
      <title>A better command history</title>
      <dc:creator>Neeraj Kashyap</dc:creator>
      <pubDate>Sat, 13 Feb 2021 00:03:20 +0000</pubDate>
      <link>https://dev.to/zomglings/using-bugout-dev-to-build-a-better-command-history-ko9</link>
      <guid>https://dev.to/zomglings/using-bugout-dev-to-build-a-better-command-history-ko9</guid>
      <description>&lt;p&gt;If you spend a lot of time at the command line, you know how powerful the command history is. Especially if you use &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-use-bash-history-commands-and-expansions-on-a-linux-vps" rel="noopener noreferrer"&gt;&lt;code&gt;Ctrl + r&lt;/code&gt;, and other advanced history-related features&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As powerful as the command history is, it could be a &lt;em&gt;lot&lt;/em&gt; better.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's wrong with history?
&lt;/h3&gt;

&lt;p&gt;The two biggest problems with the command history are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It is &lt;a href="https://unix.stackexchange.com/questions/131504/how-to-sync-terminal-session-command-history-in-bash" rel="noopener noreferrer"&gt;very&lt;/a&gt; difficult to build a central command history across multiple terminal sessions and multiple computers.&lt;/li&gt;
&lt;li&gt;Command histories only store the commands themselves. They do not store the output of the commands or even the exit code.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Command history is great when running commands that you use frequently and are already quite familiar with.&lt;/p&gt;

&lt;p&gt;If you want to perform an operation that you are unfamiliar with and very rarely use, your command history tends to be useless. Especially when you can't remember which terminal or even machine you ran that operation on previously.&lt;/p&gt;

&lt;h3&gt;
  
  
  Storing command history in Bugout
&lt;/h3&gt;

&lt;p&gt;For context, &lt;a href="https://bugout.dev" rel="noopener noreferrer"&gt;Bugout.dev&lt;/a&gt; is an automated knowledge base for developers and software teams. It is free to use for individuals and for small teams (up to 5 members).&lt;/p&gt;

&lt;p&gt;Bugout has a very simple API that you can use to add knowledge into your knowledge base and it offers search over your knowledge base out of the box.&lt;/p&gt;

&lt;p&gt;Bugout comes with a command line tool called &lt;code&gt;bugout&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/bugout-dev" rel="noopener noreferrer"&gt;
        bugout-dev
      &lt;/a&gt; / &lt;a href="https://github.com/bugout-dev/bugout-go" rel="noopener noreferrer"&gt;
        bugout-go
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      The Bugout Go SDK
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;bugout-go&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;This repository contains the Bugout Go client library. It is also the home of the &lt;code&gt;bugout&lt;/code&gt; command
line tool.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Pre-built binaries&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;You can get the latest pre-built release of the &lt;code&gt;bugout&lt;/code&gt; command line tool on the
&lt;a href="https://github.com/bugout-dev/bugout-go/releases" rel="noopener noreferrer"&gt;Releases&lt;/a&gt; page.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;go get&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;If you are familiar with golang and have it installed, you can also get bugout using:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;go get github.com/bugout-dev/bugout-go&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;This will install the Bugout client library in &lt;code&gt;$GOPATH/src/github.com/bugout-dev/bugout-go&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It will also put the &lt;code&gt;bugout&lt;/code&gt; command line interface in your &lt;code&gt;$GOPATH/bin&lt;/code&gt; directory.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Using the bugout command line tool&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Access tokens and the BUGOUT_ACCESS_TOKEN environment variable&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Many &lt;code&gt;bugout&lt;/code&gt; commands require you to pass a Bugout token as the &lt;code&gt;-t&lt;/code&gt;/&lt;code&gt;--token&lt;/code&gt; argument. You can
generate an access token by logging into &lt;a href="https://bugout.dev/account/tokens" rel="nofollow noopener noreferrer"&gt;https://bugout.dev/account/tokens&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Once you have generated an access token, if you would like &lt;code&gt;bugout&lt;/code&gt; to use it automatically without
having to explicitly pass it using &lt;code&gt;-t&lt;/code&gt;/&lt;code&gt;--token&lt;/code&gt;…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/bugout-dev/bugout-go" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;code&gt;bugout&lt;/code&gt; has a command, &lt;code&gt;bugout trap&lt;/code&gt;, which captures a command from your terminal into your knowledge base. &lt;code&gt;bugout trap&lt;/code&gt; not only captures the command, but also its:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;exit code&lt;/li&gt;
&lt;li&gt;stdout&lt;/li&gt;
&lt;li&gt;stderr&lt;/li&gt;
&lt;li&gt;(optionally) the environment variables it was run with&lt;/li&gt;
&lt;li&gt;(optionally) any additional tags you would like to associate with it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Below are some examples of how I use &lt;code&gt;bugout trap&lt;/code&gt; to turn my knowledge base into a centralized command history:&lt;/p&gt;

&lt;h4&gt;
  
  
  Example: Capturing API requests, responses, and headers with curl
&lt;/h4&gt;


&lt;div class="ltag_asciinema"&gt;
  
&lt;/div&gt;


&lt;p&gt;The link takes us to the new knowledge base entry:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fstkkorxg51zb3mfldpjv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fstkkorxg51zb3mfldpjv.png" alt="GitHub rate limit request, response, and headers"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Example: Image format conversions
&lt;/h4&gt;

&lt;p&gt;I rarely use &lt;a href="https://imagemagick.org/index.php" rel="noopener noreferrer"&gt;&lt;code&gt;ImageMagick&lt;/code&gt;&lt;/a&gt; directly - and never remember that its shell command is &lt;code&gt;convert&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;I only had an SVG version of the cover image for this post and wanted to use ImageMagick to transform it to PNG (dev.to does not accept SVG images).&lt;/p&gt;

&lt;p&gt;I searched my history for occurrences of &lt;code&gt;svg&lt;/code&gt; or &lt;code&gt;png&lt;/code&gt;: &lt;code&gt;history | grep svg&lt;/code&gt; and &lt;code&gt;history | grep png&lt;/code&gt;. Unfortunately, I only found a bunch of commands where I opened image files: commands like &lt;code&gt;xdg-open &amp;lt;filename&amp;gt;.svg&lt;/code&gt; and &lt;code&gt;xdg-open &amp;lt;filename&amp;gt;.png&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This time, when I figured it out, I used &lt;code&gt;bugout trap&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_asciinema"&gt;
  
&lt;/div&gt;


&lt;p&gt;The entry:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnessubb7vqv72kpnys1m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnessubb7vqv72kpnys1m.png" alt="ImageMagick command to convert SVG to PNG - ImageMagick is pretty awesome and easy to use!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Best of all, we can search this history from our command line and view it in our editor:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_asciinema"&gt;
  
&lt;/div&gt;


&lt;p&gt;Note how we can filter the search by exit code using &lt;code&gt;"tag:exit:0"&lt;/code&gt; in the search query. We can also restrict our search only to invocations that caused errors by using the query &lt;code&gt;"!tag:exit:0"&lt;/code&gt;. This is very powerful when working with teammates to debug an issue with a command.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example: Tracking production database migrations
&lt;/h4&gt;

&lt;p&gt;At Bugout, we are heavy &lt;a href="https://www.postgresql.org/" rel="noopener noreferrer"&gt;Postgres&lt;/a&gt; users. Our backend is written in Python. We use &lt;a href="https://www.sqlalchemy.org/" rel="noopener noreferrer"&gt;SQLAlchemy&lt;/a&gt; to interact with our database and &lt;a href="https://alembic.sqlalchemy.org/en/latest/" rel="noopener noreferrer"&gt;Alembic&lt;/a&gt; to manage our database migrations.&lt;/p&gt;

&lt;p&gt;We run migrations manually in production, and &lt;code&gt;bugout trap&lt;/code&gt; is very useful to keep a record of when each database migration was run so the whole team can see. This is how we use it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bugout &lt;span class="nb"&gt;trap&lt;/span&gt; &lt;span class="nt"&gt;--title&lt;/span&gt; &lt;span class="s2"&gt;"Database migration: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;alembic &lt;span class="nb"&gt;history&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-n1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;--tags&lt;/span&gt; db,migration,prod &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    alembic upgrade &lt;span class="nb"&gt;head&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Trapping commands we run in production into our team's knowledge base helps us stay synchronized across 15 time zones.&lt;/p&gt;

&lt;h3&gt;
  
  
  Try it yourself
&lt;/h3&gt;

&lt;p&gt;If this workflow sounds compelling to you, you can try it out yourself. Bugout is free for individual developers (and for small teams), so all you have to do is sign up for an account at &lt;a href="https://bugout.dev" rel="noopener noreferrer"&gt;https://bugout.dev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Reach out to me in the comments if you need any help setting up!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Thank you, &lt;a class="mentioned-user" href="https://dev.to/nickmaris"&gt;@nickmaris&lt;/a&gt; , for &lt;a href="https://dev.to/nickmaris/comment/1b5eh"&gt;suggesting I create this kind of content&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>bash</category>
      <category>webdev</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Bugout.dev - a knowledge base that builds itself</title>
      <dc:creator>Neeraj Kashyap</dc:creator>
      <pubDate>Wed, 03 Feb 2021 20:30:39 +0000</pubDate>
      <link>https://dev.to/zomglings/bugout-dev-a-knowledge-base-that-builds-itself-4ikd</link>
      <guid>https://dev.to/zomglings/bugout-dev-a-knowledge-base-that-builds-itself-4ikd</guid>
      <description>&lt;p&gt;Bugout is a knowledge base for programmers. It's a great place to take notes for yourself, or to share with your team.&lt;/p&gt;

&lt;p&gt;You can integrate Bugout with your code editor, your GitHub repositories, and your Slack workspaces. This makes it easy easy to add knowledge to your knowledge base directly - and &lt;strong&gt;automatically&lt;/strong&gt; - from those sources.&lt;/p&gt;

&lt;p&gt;You can sign up and start using it for free at &lt;a href="https://bugout.dev" rel="noopener noreferrer"&gt;https://bugout.dev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After you sign up and verify your email, you should see a &lt;code&gt;Personal&lt;/code&gt; journal with a document on how to get started. It will also help you set up the integrations with VSCode, GitHub, or Slack if you are interested in those.&lt;/p&gt;

&lt;p&gt;Quick demo of the VSCode integration:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7qhbrs7p7bir705nxsfc.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7qhbrs7p7bir705nxsfc.gif" alt="Bugout in VSCode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quick demo of Slack integration:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F902kv2mp2ntztfuq5ji0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F902kv2mp2ntztfuq5ji0.gif" alt="Bugout in Slack"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The power of Bugout is in collaboration, and you can create small teams (of up to 5 people) for free to share knowledge with.&lt;/p&gt;

&lt;p&gt;You can create teams on your Account screen (get there by clicking on your username in the top right), and then add these teams to journals on the journal settings screen (little gear icon next to each journal name). Really useful for shared projects, especially with our Slack integration.&lt;/p&gt;

&lt;p&gt;I'd really appreciate any feedback that you have, and will work quickly to fix any issues. Thank you!&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Entropy for developers</title>
      <dc:creator>Neeraj Kashyap</dc:creator>
      <pubDate>Sun, 20 Dec 2020 17:27:29 +0000</pubDate>
      <link>https://dev.to/zomglings/tl-dr-entropy-30b5</link>
      <guid>https://dev.to/zomglings/tl-dr-entropy-30b5</guid>
      <description>&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Entropy_(information_theory)" rel="noopener noreferrer"&gt;Entropy&lt;/a&gt; is a mathematical concept which quantifies the amount of information in an observation.&lt;/p&gt;

&lt;p&gt;This makes entropy useful to you, as a programmer, whenever you are working with data. When working with large datasets, entropy-based heuristics can tell you where to focus your attention to get the most bang for your buck.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://bugout.dev" rel="noopener noreferrer"&gt;Bugout&lt;/a&gt;, we have a tagging system for knowledge bases very similar to the tags that &lt;a href="https://dev.to"&gt;DEV&lt;/a&gt; uses for their posts. We calculate the informative power of each tag using entropy. We use these calculations to help our users categorize their knowledge and navigate their knowledge bases more efficiently. Entropy helps us power these user experiences with simple calculations we do in our database as opposed to using complicated machine learning models.&lt;/p&gt;

&lt;p&gt;Entropy and related information theoretic notions are very useful in machine learning, as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://towardsdatascience.com/entropy-how-decision-trees-make-decisions-2946b9c18c8" rel="noopener noreferrer"&gt;Decision tree algorithms tend to use entropy&lt;/a&gt; to learn effective branching structures.&lt;/p&gt;

&lt;p&gt;When training neural networks, entropy is usually incorporated into the training process via a loss function. &lt;a href="https://datascience.stackexchange.com/questions/9302/the-cross-entropy-error-function-in-neural-networks" rel="noopener noreferrer"&gt;Cross entropy&lt;/a&gt;, for example, is a commonly used loss function when training classifiers. A good understand of entropy not only helps you understand the behavior of such models, it also helps you tune your models more effectively.&lt;/p&gt;

&lt;p&gt;If you are curious to learn more about entropy and start using it to improve your data-related work, this post will get you started.&lt;/p&gt;

&lt;p&gt;Towards the end of the post, I also describe some instances during my career where the concept of entropy has come in handy.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post assumes a basic understanding of probability and some familiarity with mathematical notation.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Definition
&lt;/h3&gt;

&lt;p&gt;Say you have a probability distribution with outcomes 

&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;1,2,…,n1, 2, \ldots, n&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="minner"&gt;…&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, each of which can occur with probabilities 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;p1,p2,…,pnp_1, p_2, \ldots, p_n&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="minner"&gt;…&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
.&lt;/p&gt;

&lt;p&gt;The entropy of this probability distribution is:&lt;br&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;H(p1,…,pn):=−∑j=1npjlog(pj)
H(p_1, \ldots, p_n) := -\sum_{j=1}^n p_j log(p_j)
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;H&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="minner"&gt;…&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;:=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mop op-limits"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;j&lt;/span&gt;&lt;span class="mrel mtight"&gt;=&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="mop op-symbol large-op"&gt;∑&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;j&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;j&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  Properties
&lt;/h3&gt;

&lt;p&gt;Much more important than the definition are the properties that it embodies.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;entropy increases with the number of (equally likely) outcomes&lt;/strong&gt;:&lt;br&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;H(1n,…,1n)&amp;lt;H(1n+1,…,1n+1)H\left(\frac{1}{n}, \ldots, \frac{1}{n}\right) &amp;lt; H\left(\frac{1}{n+1},\ldots,\frac{1}{n+1}\right)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;H&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="minner"&gt;&lt;span class="mopen delimcenter"&gt;&lt;span class="delimsizing size3"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="minner"&gt;…&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose delimcenter"&gt;&lt;span class="delimsizing size3"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;H&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="minner"&gt;&lt;span class="mopen delimcenter"&gt;&lt;span class="delimsizing size3"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="minner"&gt;…&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose delimcenter"&gt;&lt;span class="delimsizing size3"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;
  Example: Coins and dice
  &lt;br&gt;


  &lt;span&gt;&lt;span&gt;&lt;span&gt;H(1/2,1/2)&amp;lt;H(1/6,1/6,1/6,1/6,1/6,1/6),H(1/2, 1/2) &amp;lt; H(1/6, 1/6, 1/6, 1/6, 1/6, 1/6),&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;H&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1/2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;1/2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;H&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1/6&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;1/6&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;1/6&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;1/6&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;1/6&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;1/6&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;br&gt;
which says that the roll of a fair die contains more information than the flip of a fair coin.&lt;br&gt;


&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;entropy is maximized when outcomes are equally likely&lt;/strong&gt;:&lt;br&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;H(p1,…,pn)&amp;lt;H(1n,…,1n)
H(p_1, \ldots, p_n) &amp;lt; H\left(\frac{1}{n}, \ldots, \frac{1}{n}\right)
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;H&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="minner"&gt;…&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;H&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="minner"&gt;&lt;span class="mopen delimcenter"&gt;&lt;span class="delimsizing size3"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="minner"&gt;…&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose delimcenter"&gt;&lt;span class="delimsizing size3"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;br&gt;
for any probability distribution 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;(p1,…,pn)(p_1, \ldots, p_n)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="minner"&gt;…&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 for which some 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;pj≠1/np_j \neq 1/n&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;j&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;&lt;span class="mrel"&gt;&lt;span class="mord vbox"&gt;&lt;span class="thinbox"&gt;&lt;span class="rlap"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="inner"&gt;&lt;span class="mord"&gt;&lt;span class="mrel"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="fix"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1/&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
.

&lt;p&gt;This feeds into our intuition that the &lt;strong&gt;amount of information in an event is the amount of uncertainty it resolves for us&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;
  Example: Fair coins and biased coins
  &lt;br&gt;


  &lt;span&gt;&lt;span&gt;&lt;span&gt;H(1/4,3/4)&amp;lt;H(1/2,1/2),
H(1/4, 3/4) &amp;lt; H(1/2, 1/2),
&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;H&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1/4&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;3/4&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;H&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1/2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;1/2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;br&gt;
which says that we get much less information when flipping a coin which is biased to land on heads only 25% of the time than when flipping a coin.&lt;br&gt;


&lt;/p&gt;

&lt;h3&gt;
  
  
  Units
&lt;/h3&gt;

&lt;p&gt;One of the choices you have to make when calculating the entropy of a probability distribution is the base you will choose for the logarithm.&lt;/p&gt;

&lt;p&gt;This choice doesn't usually matter much. This is because changing the base only changes the calculation by a constant factor. Since you usually use entropy to make comparisons between probability distributions, multiplying all calculations by a constant factor doesn't affect how they are placed relative to each other.&lt;/p&gt;

&lt;p&gt;Consider the calculation of&lt;br&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;H(1/2,1/2)=−[12log(12)+12log(12)]=−log(12)
H(1/2, 1/2) = -\left[\frac{1}{2}log\left(\frac{1}{2}\right) + \frac{1}{2}log\left(\frac{1}{2}\right)\right] = -log\left(\frac{1}{2}\right)
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;H&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;1/2&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1/2&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="minner"&gt;&lt;span class="mopen delimcenter"&gt;&lt;span class="delimsizing size3"&gt;[&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="minner"&gt;&lt;span class="mopen delimcenter"&gt;&lt;span class="delimsizing size3"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose delimcenter"&gt;&lt;span class="delimsizing size3"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="minner"&gt;&lt;span class="mopen delimcenter"&gt;&lt;span class="delimsizing size3"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose delimcenter"&gt;&lt;span class="delimsizing size3"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose delimcenter"&gt;&lt;span class="delimsizing size3"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="minner"&gt;&lt;span class="mopen delimcenter"&gt;&lt;span class="delimsizing size3"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose delimcenter"&gt;&lt;span class="delimsizing size3"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;If you take the logarithm to the base of 2, you get 
&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;H(1/2,1/2)=1H(1/2, 1/2) = 1&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;H&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;1/2&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1/2&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;If you generalize this calculation to powers of 2, you get:&lt;br&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;H(1/2n,…,1/2n)=nH(1/2^n, \ldots, 1/2^n) = n&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;H&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;1/&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="minner"&gt;…&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1/&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;For any probability distribution with equally likely outcomes, using a base of 2 on the logarithm, entropy counts the minimum number of bits required to represent the possible outcomes from the distribution.&lt;/p&gt;

&lt;p&gt;Claude Shannon, father of information theory (pictured above), made this connection more explicit:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__wikipedia--container"&gt;
  &lt;div class="ltag__wikipedia--header"&gt;
    &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fwikipedia-logo-0a3e76624c7b1c3ccdeb9493ea4add6ef5bd82d7e88d102d5ddfd7c981efa2e7.svg" class="ltag__wikipedia--logo" alt="Wikipedia Logo"&gt;
    &lt;a href="https://en.wikipedia.org/wiki/Shannon%27s_source_coding_theorem" rel="noopener noreferrer"&gt;Shannon's source coding theorem&lt;/a&gt;
  &lt;/div&gt;
  &lt;div class="ltag__wikipedia--extract"&gt;&lt;p&gt;In information theory, &lt;b&gt;Shannon's source coding theorem&lt;/b&gt; establishes the statistical limits to possible data compression for data whose source is an independent identically-distributed random variable, and the operational meaning of the Shannon entropy.&lt;/p&gt;&lt;/div&gt;
  &lt;div class="ltag__wikipedia--btn--container"&gt;
      &lt;a class="ltag__wikipedia--btn" href="https://en.wikipedia.org/wiki/Shannon%27s_source_coding_theorem" rel="noopener noreferrer"&gt;View on Wikipedia&lt;/a&gt;&amp;gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The important takeaway here is that you can think of entropy as answering the question, &lt;strong&gt;"What is the smallest number of bits I need to represent a sample from this probability distribution?"&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Real-world applications
&lt;/h3&gt;

&lt;p&gt;I list a few examples from my own career where knowing about entropy was extremely useful.&lt;/p&gt;

&lt;h4&gt;
  
  
  Bugout tags
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://bugout.dev" rel="noopener noreferrer"&gt;Bugout&lt;/a&gt; is a knowledge base that accepts knowledge from a variety of sources (Slack, GitHub, IDEs, terminals), and makes it discoverable to users wherever they work.&lt;/p&gt;

&lt;p&gt;This is what it looks like when someone adds knowledge to their knowledge base from Slack:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F18yvkd20sq9kg50ya2tv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F18yvkd20sq9kg50ya2tv.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We place no restriction on the number of tags a user can associate with an entry in their knowledge base. Instead, we rely on intelligently suggesting tags to users when they create content and when they are searching for knowledge.&lt;/p&gt;

&lt;p&gt;The first iteration of our tag suggestions were based on how frequently tags were used in a given knowledge base. Tags which appeared more commonly were higher up in the list of suggestions.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;engineering&lt;/code&gt; tag shows up on close to 80% of the entries in our team knowledge base. It certainly doesn't help too much when searching through a knowledge base. As developers repeatedly accept &lt;code&gt;engineering&lt;/code&gt; as a suggested tag when adding content into their knowledge base, the informative power of the &lt;code&gt;engineering&lt;/code&gt; tag just decreases as its frequency of use increases.&lt;/p&gt;

&lt;p&gt;We have found entropy to be a much better quantification of the importance of a tag than frequency. It delivers a much better user experience especially for users navigating a knowledge base.&lt;/p&gt;

&lt;p&gt;For each tag in a knowledge base, we think of each entry as an observation of whether or not the tag appears. With 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;ptagp_{tag}&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;g&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 as the proportion of entries having the given tag, the entropy of the tag is 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;H(ptag,1−ptag)H(p_{tag}, 1-p_{tag})&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;H&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;g&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;g&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
.&lt;/p&gt;

&lt;p&gt;The best thing about this is that it's easy to calculate in our Postgres database. Here is an example of an (unoptimized) entropy query for tags in Bugout knowledge bases (internally, knowledge bases are represented as &lt;code&gt;journals&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;journal_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;num_entries_with_tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;num_entries&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;num_entries_with_tag&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;num_entries&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;proportion_entries&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;num_entries_with_tag&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;num_entries&lt;/span&gt;
        &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_entries_with_tag&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;num_entries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;ln&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_entries_with_tag&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;num_entries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;num_entries&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;num_entries_with_tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;num_entries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;ln&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;num_entries&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;num_entries_with_tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;num_entries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;entropy&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;journal_entry_tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;journals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;journal_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;cast&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;journal_entries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;num_entries_with_tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;cast&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;journal_entries&lt;/span&gt;
                    &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;journal_entries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;journal_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;journals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;num_entries&lt;/span&gt;
        &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;journal_entries&lt;/span&gt;
            &lt;span class="k"&gt;inner&lt;/span&gt; &lt;span class="k"&gt;join&lt;/span&gt; &lt;span class="n"&gt;journal_entry_tags&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;journal_entries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;journal_entry_tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;journal_entry_id&lt;/span&gt;
            &lt;span class="k"&gt;inner&lt;/span&gt; &lt;span class="k"&gt;join&lt;/span&gt; &lt;span class="n"&gt;journals&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;journals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;journal_entries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;journal_id&lt;/span&gt;
        &lt;span class="k"&gt;group&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;journals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;journal_entry_tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;intermediate_stats&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Outperforming Amazon, Google, and Microsoft APIs on image classification tasks
&lt;/h4&gt;

&lt;p&gt;I used to run the AI team at &lt;a href="https://doc.ai" rel="noopener noreferrer"&gt;Doc.ai&lt;/a&gt;. At the time, we built image models that provided our users and their medical providers with valuable insights about their physical and mental health.&lt;/p&gt;

&lt;p&gt;Being serious about user privacy, especially when dealing with sensitive health data, we built our classification models to run on our users' mobile phones. This meant we couldn't just plug into AWS Rekognition, the Google ML APIs or Microsoft Cognitive Services, as that would leak user health information to Amazon, Google, and Microsoft.&lt;/p&gt;

&lt;p&gt;We set out to train models which were competitive with the major cloud APIs by collecting a LOT of relevant images (10s of millions) and boostrapping our model with the classifications returned by the cloud APIs.&lt;/p&gt;

&lt;p&gt;At the end of the day, we were able to outperform the cloud APIs in the many cases because of how we used entropy to our advantage.&lt;/p&gt;

&lt;p&gt;You can think of image classification results as a probability vector over the possible classes represented in an image or in a segment of that image. We calculated the entropy of the classification results that the cloud APIs returned for each of the images in our dataset. This calculation quantified the amount of uncertainty their models had about their results. This uncertainty decomposed into two components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The quality of the cloud API model in question&lt;/li&gt;
&lt;li&gt;The quality of the image for the given classification task&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For a given cloud API, we could take the entropy (largely) as a measure of image quality. Thus, filtering on entropy allowed us to cheaply build very high quality training and evaluation datasets without contracting any kind of labeling service (which would have been exorbitantly expensive at the scale of data we were working with).&lt;/p&gt;

&lt;p&gt;Entropy heuristics were also very important in helping us understand the hyperparameter spaces of the models we trained. For each model, during our hyperparameter tuning phase, we would run ~30 experiments concurrently, and it cost us thousands of dollars a week. As a tiny startup, it was important that we be efficient about hyperparameter tuning. Simple entropy and cross entropy calculations over our dataset and classifications performed by various model checkpoints helped us narrow in on high-performing hyperparameters very quickly.&lt;/p&gt;

&lt;p&gt;My team at Doc.ai released a lot of this work as the open source Tensor/IO framework (which also allows you to train models across many user devices using &lt;a href="https://en.wikipedia.org/wiki/Federated_learning" rel="noopener noreferrer"&gt;federated learning&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/doc-ai" rel="noopener noreferrer"&gt;
        doc-ai
      &lt;/a&gt; / &lt;a href="https://github.com/doc-ai/tensorio" rel="noopener noreferrer"&gt;
        tensorio
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Declarative, On-Device Machine Learning for iOS, Android, and React Native. Deploy. Predict. Train.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Introduction&lt;/h3&gt;
&lt;/div&gt;

&lt;p&gt;Tensor/IO is a lightweight, cross-platform library for on-device machine learning, bringing the power of TensorFlow and TensorFlow Lite to iOS, Android, and React Native applications. We now also support PyTorch on Android and will be bringing support for PyTorch to iOS soon. Tensor/IO does not implement any machine learning itself but works with an underlying library such as TensorFlow to simplify the process of deploying and using models on mobile phones.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h4 class="heading-element"&gt;Declarative&lt;/h4&gt;
&lt;/div&gt;

&lt;p&gt;Tensor/IO is above all a declarative interface to your model. Describe the input and output layers to your model using a plain-text language and Tensor/IO takes care of the transformations needed to prepare inputs for the model and to read outputs back out of it, allowing you to focus on what you know instead of a low-level C++ interface.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h4 class="heading-element"&gt;On-Device&lt;/h4&gt;
&lt;/div&gt;

&lt;p&gt;Tensor/IO runs on iOS and Android mobile phones, with bridging for React Native, and it runs the…&lt;/p&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/doc-ai/tensorio" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;





&lt;p&gt;Happy to answer any questions and continue the discussion. Just leave a comment below. :)&lt;/p&gt;

</description>
      <category>datascience</category>
      <category>machinelearning</category>
      <category>programming</category>
    </item>
    <item>
      <title>Bugout: Add checklists your GitHub pull requests</title>
      <dc:creator>Neeraj Kashyap</dc:creator>
      <pubDate>Mon, 07 Dec 2020 20:57:13 +0000</pubDate>
      <link>https://dev.to/zomglings/bugout-add-checklists-your-github-pull-requests-55f2</link>
      <guid>https://dev.to/zomglings/bugout-add-checklists-your-github-pull-requests-55f2</guid>
      <description>&lt;p&gt;Sometimes, you need human oversight on your pull requests before you can merge them.&lt;/p&gt;

&lt;p&gt;This is especially true for pull requests that change database schema, introduce new environment variables, or introduce changes with security or legal implications.&lt;/p&gt;

&lt;p&gt;Bugout adds a checklist to every pull request. To add a check to your checklist, just mention @bugout-dev on a PR comment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@bugout-dev check require &amp;lt;something important&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To cross an item off the checklist:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@bugout-dev check accept &amp;lt;something important&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is a live PR where you can try it out: &lt;a href="https://github.com/bugout-dev/github-demo/pull/2"&gt;https://github.com/bugout-dev/github-demo/pull/2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Actively looking for feedback - missing features, similar to existing apps, anything. Thank you!&lt;/p&gt;

</description>
      <category>github</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Break out of the deployment death loop</title>
      <dc:creator>Neeraj Kashyap</dc:creator>
      <pubDate>Thu, 03 Dec 2020 07:07:33 +0000</pubDate>
      <link>https://dev.to/zomglings/break-out-of-the-deployment-death-loop-9bg</link>
      <guid>https://dev.to/zomglings/break-out-of-the-deployment-death-loop-9bg</guid>
      <description>&lt;p&gt;Continuous integration services like &lt;a href="https://www.jenkins.io/"&gt;Jenkins&lt;/a&gt;, &lt;a href="https://bitbucket.org/product/features/pipelines"&gt;Bitbucket Pipelines&lt;/a&gt;, &lt;a href="https://circleci.com/"&gt;CircleCI&lt;/a&gt;, &lt;a href="https://github.com/features/actions"&gt;GitHub Actions&lt;/a&gt;, &lt;a href="https://docs.gitlab.com/ee/ci/"&gt;Gitlab CI/CD&lt;/a&gt; force extreme automation. They require your continuous integration flows to run non-interactively in remote environments. Most of these tools do not allow you to interact with the continuous integration environment.&lt;/p&gt;

&lt;p&gt;All of these tools require users to define deployment workflows in custom definition languages. It is very common in my experience that users of these services can only run their deployment workflows using the service in question.&lt;/p&gt;

&lt;p&gt;When something goes wrong with a deployment, debugging takes the form of a &lt;strong&gt;deployment death loop&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make changes locally (mostly to continuous integration configuration files).&lt;/li&gt;
&lt;li&gt;Push to the appropriate branch on your git host (usually master).&lt;/li&gt;
&lt;li&gt;Wait for a job to start on your continuous integration service.&lt;/li&gt;
&lt;li&gt;Wait minutes or even tens of minutes following the logs to see if your changes fixed the issue.&lt;/li&gt;
&lt;li&gt;Repeat this procedure until you have solved the problem.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Things are even worse when you have to debug configuration that lives in a database or on a configuration management system such as &lt;a href="https://www.vaultproject.io/"&gt;Vault&lt;/a&gt; or &lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html"&gt;Parameter Store&lt;/a&gt;. If you can’t manually trigger a workflow, you are forced to push superficial changes to your git repository (like adding punctuation or white space to your README) to see if your changes worked.&lt;/p&gt;

&lt;p&gt;How to break out of this death loop?&lt;/p&gt;

&lt;p&gt;Two suggestions:&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;any developer should be able to deploy from their local environment&lt;/strong&gt; (provided they have the required level of access). The continuous integration workflow definition should be secondary to this mechanism. If possible, it should make use of this mechanism.&lt;/p&gt;

&lt;p&gt;For example, at Bugout, our services are deployed by a bash script which can be executed on our servers via SSH. Even in production, if a developer has access to the production servers, they can run a deployment by simply running a git pull and then the deployment script over SSH. This is useful not only when debugging deployments but also when our continuous integration service goes down, &lt;a href="https://www.githubstatus.com/incidents/sxthxvdlljk4"&gt;which has been known to happen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;embrace checklists&lt;/strong&gt;. Have a checklist of external actions that must be taken before a change can be deployed. This checklist can include things like running database migrations, setting environment variables, or modifying a load balancer.&lt;/p&gt;

&lt;p&gt;It’s okay to check items off such a checklist manually. Manual checklists may invalidate ideas of fully automated deployments. This is alright. Deployments that require manual steps should be performed with human oversight.&lt;/p&gt;

&lt;p&gt;The general principle is to &lt;strong&gt;favor interactivity over automation&lt;/strong&gt;. Make your deployments interactive by default. You will not regret it.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cicd</category>
    </item>
  </channel>
</rss>
