<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>MJ&apos;s Blog</title><description>MJ&apos;s Blog</description><link>https://marc-julian.com/</link><item><title>AirPlay Receiver Runs on Port 5000</title><link>https://marc-julian.com/blog/posts/airplay-receiver-macos-port-5000/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/airplay-receiver-macos-port-5000/</guid><pubDate>Mon, 08 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today I learned that the AirPlay Receiver on macOS runs on port 5000. Killing the process listening on this port reloads the menubar, but the port gets instantly occupied again as the process restarts automatically.&lt;/p&gt;
&lt;p&gt;Disabling the AirPlay Receiver in System Settings stops the process, and the port is clear again.&lt;/p&gt;
&lt;p&gt;You can toggle it here:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;System Settings → General → AirDrop &amp;#x26; Handoff → AirPlay Receiver off&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content:encoded></item><item><title>AltTab does not work anymore</title><link>https://marc-julian.com/blog/posts/alt-tab-bug/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/alt-tab-bug/</guid><description>Sometimes the problem is sitting in front of the screen</description><pubDate>Mon, 08 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today I learned, when AltTab does not work anymore, you might just have it configured to use a different shortcut than the one you are expecting (especially when freshly installed).&lt;/p&gt;
&lt;p&gt;In my case it was set to &lt;code&gt;alt + tab&lt;/code&gt; instead of &lt;code&gt;cmd + tab&lt;/code&gt;. Sometimes the problem is sitting in front of the screen…&lt;/p&gt;</content:encoded></item><item><title>Neapolitan Pizza Dough Calculator</title><link>https://marc-julian.com/blog/posts/pizza-dough-calculator/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/pizza-dough-calculator/</guid><pubDate>Mon, 08 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;My former colleague Hendrik (known for his YouTube channel &lt;a href=&quot;https://www.youtube.com/@the_bread_code&quot;&gt;The Bread Code&lt;/a&gt;) wrote this &lt;a href=&quot;https://github.com/hendricius/pizza-dough&quot;&gt;amazing guide&lt;/a&gt; on how to create the best possible pizza dough in the Neapolitan style as well as &lt;a href=&quot;https://pizza-calculator.the-bread-code.io/&quot;&gt;this calculator&lt;/a&gt; to infer the precise amounts of flour, water and yeast to use.&lt;/p&gt;
&lt;p&gt;It is great if you need all the options and features. For me though, I wanted to have a more stripped down version with only the most important steps and a single Neapolitan style calculation. So here it is, on &lt;a href=&quot;https://tools.marc-julian.com/tools/pizza/&quot;&gt;tools.marc-julian.com/tools/pizza/&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>Fixing macOS Cursor Hover Not Working</title><link>https://marc-julian.com/blog/posts/macos-cursor-hover-change-issue/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/macos-cursor-hover-change-issue/</guid><pubDate>Fri, 05 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I often encounter the problem that something steals my macOS cursor focus, and from that moment on, the cursor icon no longer changes on hover (pointer, finger, hand, arrows, etc.).&lt;/p&gt;
&lt;p&gt;Today I learned that moving your mouse violently (a macOS feature that briefly increases the cursor size so you can find it on a big screen), will temporarily fix the problem until it comes back at some random point in time. I don’t like that we have to rely on some weird mouse-movement hack instead of Apple fixing this, but hey, you now know how to fix it in that moment.&lt;/p&gt;</content:encoded></item><item><title>Engineering Notebook Experiment</title><link>https://marc-julian.com/blog/posts/engineering-notebook-experiment/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/engineering-notebook-experiment/</guid><pubDate>Mon, 25 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I read about engineering notebooks here: &lt;a href=&quot;https://ntietz.com/blog/using-an-engineering-notebook/&quot;&gt;https://ntietz.com/blog/using-an-engineering-notebook/&lt;/a&gt; and for me the aspects that stood out the most were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it is an append-only notebook (no modifications or deletions)&lt;/li&gt;
&lt;li&gt;you write notes before doing a code change
&lt;ul&gt;
&lt;li&gt;this requires thinking through the problem before writing any code, potentially leading to better code&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;writing the note (and the thinking before writing) is the main selling point here. Reading back old notes not so much&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Will try this out for at least a week in my day-to-day job. For personal projects I don’t see the benefit yet as long as you are still in the fast paced prototyping stage of your project. Maybe this will change after the week. Will keep a record on this.&lt;/p&gt;</content:encoded></item><item><title>Curl This Website</title><link>https://marc-julian.com/blog/posts/curl-me/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/curl-me/</guid><pubDate>Wed, 22 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Small easter egg on this website.&lt;/p&gt;
&lt;p&gt;Try running this:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;curl&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; marc-julian.com&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or this:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;curl&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; marc-julian.com/email&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;in your favorite terminal.&lt;/p&gt;</content:encoded></item><item><title>Cooking With Claude Code</title><link>https://marc-julian.com/blog/posts/cooking-with-claude-code/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/cooking-with-claude-code/</guid><pubDate>Thu, 19 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I was inspired by &lt;a href=&quot;https://simonwillison.net/2025/Dec/23/cooking-with-claude/#atom-everything&quot;&gt;this post on Simon Willison’s Blog&lt;/a&gt; to try out cooking with Claude Code / Claude. There are multiple ways to do this. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;generating recipes based on a list of available ingredients&lt;/li&gt;
&lt;li&gt;simply asking for a specific recipe&lt;/li&gt;
&lt;li&gt;planning an entire dinner (including cooking, managing time, shopping groceries, structuring the work)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;recipe-generation&quot;&gt;&lt;a href=&quot;#recipe-generation&quot;&gt;Recipe Generation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;During the last few months I tried the second and third option. Claude “came up” with this surprisingly tasty herbal butter by grinding thyme and rosemary in a 3:1 ratio and mixing it with garlic, salt and butter to taste. It was great. Simple to cook and went really well with beef tenderloin. You can find the recipe here on my new recipe website: &lt;a href=&quot;https://recipes.marc-julian.com/recipe/kraeuterbutter/&quot;&gt;recipes.marc-julian.com&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;dinner-planning&quot;&gt;&lt;a href=&quot;#dinner-planning&quot;&gt;Dinner Planning&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Planning an entire dinner was a great use case for Claude Code. I created a new git repository in a local folder, spun up Claude Code and asked it to write down many notes to plan my dinner. I had already picked most dishes and just needed help planning it all together. To get the timings right, be prepared, have all ingredients, hardware and tableware ready and overall have a nice oversight on what to do the next two days. If you want, you can take a look at the resulting notes after some conversations with Claude Code, here.&lt;/p&gt;
&lt;p&gt;Here are some pictures of the dinner managed by Claude Code:&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/claude-dinner-overview.jpg&quot; alt=&quot;Claude Dinner Appetizer&quot;&gt;&lt;figcaption&gt;Claude Dinner Appetizer&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/claude-dinner-main.jpg&quot; alt=&quot;Claude Dinner Main Course&quot;&gt;&lt;figcaption&gt;Claude Dinner Main Course&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/claude-dinner-dessert.jpg&quot; alt=&quot;Claude Dinner Dessert&quot;&gt;&lt;figcaption&gt;Claude Dinner Dessert&lt;/figcaption&gt;&lt;/figure&gt;</content:encoded></item><item><title>How to Slim Down a Vite App</title><link>https://marc-julian.com/blog/posts/vite-bundle-chunk-size-improvements/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/vite-bundle-chunk-size-improvements/</guid><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I recently encountered this warning in one of my Vite apps:&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/rollup-chunk-warning.jpg&quot; alt=&quot;Rollup Chunk Warning in Terminal&quot;&gt;&lt;figcaption&gt;Rollup Chunk Warning in Terminal&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;This chunking warning will often appear if you add large dependencies to a project. To find out which dependencies are the culprit, analyze the bundle size using the rollup visualizer plugin. It can be configured like this in &lt;code&gt;vite.config.ts&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;ts&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; { visualizer } &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;rollup-plugin-visualizer&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt; default&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; defineConfig&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;  plugins&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;    react&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;    tailwindcss&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;    visualizer&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;      filename&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;stats.html&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;      emitFile&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; true&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;      template&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;treemap&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;    })&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;  ]&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;  resolve&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;    alias&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;      &quot;@&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; path&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;resolve&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(__dirname&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;./src&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;    }&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;  }&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;})&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After building the project (e.g. by running &lt;code&gt;pnpm build&lt;/code&gt;) you can open the &lt;code&gt;stats.html&lt;/code&gt; file from the &lt;code&gt;dist&lt;/code&gt; folder (e.g. by running &lt;code&gt;open ./dist/stats.html&lt;/code&gt;).
Depending on the selected &lt;code&gt;template&lt;/code&gt;, different visualization types will open:&lt;/p&gt;
&lt;h2 id=&quot;treemap&quot;&gt;&lt;a href=&quot;#treemap&quot;&gt;Treemap&lt;/a&gt;&lt;/h2&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/rollup-visualizer-treemap.jpg&quot; alt=&quot;Rollup Visualizer Treemap&quot;&gt;&lt;figcaption&gt;Rollup Visualizer Treemap&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;flamegraph&quot;&gt;&lt;a href=&quot;#flamegraph&quot;&gt;Flamegraph&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I found this to be the most useful and easy to understand version. It clearly shows the different layers and big chunks are quick to find.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/rollup-visualizer-flamegraph.jpg&quot; alt=&quot;Rollup Visualizer Flamegraph&quot;&gt;&lt;figcaption&gt;Rollup Visualizer Flamegraph&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;sunburst&quot;&gt;&lt;a href=&quot;#sunburst&quot;&gt;Sunburst&lt;/a&gt;&lt;/h2&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/rollup-visualizer-sunburst.jpg&quot; alt=&quot;Rollup Visualizer Sunburst&quot;&gt;&lt;figcaption&gt;Rollup Visualizer Sunburst&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;treemap-3d&quot;&gt;&lt;a href=&quot;#treemap-3d&quot;&gt;Treemap 3D&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This one is crazy, looks a bit like a microcontroller.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/rollup-visualizer-treemap-3d.jpg&quot; alt=&quot;Rollup Visualizer Treemap 3D&quot;&gt;&lt;figcaption&gt;Rollup Visualizer Treemap 3D&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;what-to-do-about-big-chunks&quot;&gt;&lt;a href=&quot;#what-to-do-about-big-chunks&quot;&gt;What to do about big chunks?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This kind of depends on the type of chunk and how prominently it is used in your app. The React dependency for example is hard to chunk if your app is a React app.
But if your dependency is only used on certain pages (for example a PDF viewer) you might want to only load it when it is actually viewed by the user.&lt;/p&gt;
&lt;p&gt;You can do this by lazy importing dependencies or more complex pages. In this example, the &lt;code&gt;&amp;#x3C;Page&gt;&lt;/code&gt; component could include a PDF viewer that you only want to load when the component mounts/loads:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;ts&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; Page &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; lazy&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; import&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;./pages/page&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content:encoded></item><item><title>Speeding Through Git</title><link>https://marc-julian.com/blog/posts/oh-my-zsh-git-plugin/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/oh-my-zsh-git-plugin/</guid><pubDate>Wed, 03 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The best tool for speeding up git workflows (imo) is the &lt;a href=&quot;https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/git&quot;&gt;oh-my-zsh git plugin&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Doing something like the following feels like magic:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;gsw&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; main&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;gl&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;gsw&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; feature/my-feature&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;gst&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;gstu&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;grb&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; main&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;gpf&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;gstp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;switching to main branch&lt;/li&gt;
&lt;li&gt;pulling newest changes on main&lt;/li&gt;
&lt;li&gt;switching back to feature branch&lt;/li&gt;
&lt;li&gt;checking status of my files&lt;/li&gt;
&lt;li&gt;stashing all changes (including untracked)&lt;/li&gt;
&lt;li&gt;rebasing feature branch onto main&lt;/li&gt;
&lt;li&gt;force pushing the rebased branch to the remote&lt;/li&gt;
&lt;li&gt;popping the stashed changes to continue working&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All that in about 10 seconds because the commands get into muscle memory fast. Could not live without it anymore.&lt;/p&gt;</content:encoded></item><item><title>Obsidian Dataview Serializer</title><link>https://marc-julian.com/blog/posts/obsidian-dataview-serializer/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/obsidian-dataview-serializer/</guid><pubDate>Sat, 21 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The popular &lt;a href=&quot;https://github.com/blacksmithgu/obsidian-dataview&quot;&gt;Obsidian Dataview plugin&lt;/a&gt; let’s you query markdown notes with SQL-like syntax. It uses the YAML frontmatter (also known as Obsidian properties) as attributes. This enables powerful workflows. For example, &lt;a href=&quot;https://github.com/marcjulianschwarz/obsidian-vault-blog&quot;&gt;all of my blog posts&lt;/a&gt; contain these YAML properties:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;blog-title&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blog-tags&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blog-published&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blog-author&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blog-archived&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blog-skip&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With these, I can create lists and tables about my blog posts. For example, the following query results in a table of all posts that are currently published, sorted by publishing date:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;TABLE blog-published&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;FROM &quot;Posts&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;WHERE blog-skip != true and blog-archive != true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;SORT blog-published desc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But you can also build more complex queries. The following adds a markdown formatted link to the actual published blog post website as a new column:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;TABLE WITHOUT ID (&quot;[&quot; + blog-title + &quot;](&quot; + &quot;https://marc-julian.com/blog/posts/&quot; + replace(file.name, &quot;.md&quot;, &quot;&quot;) + &quot;)&quot;) AS &quot;URL&quot;, blog-published as &quot;Published&quot; FROM &quot;Posts&quot; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;WHERE blog-skip != true and blog-archive != true &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;SORT blog-published desc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;obsidian-dataview-serializer&quot;&gt;&lt;a href=&quot;#obsidian-dataview-serializer&quot;&gt;Obsidian Dataview Serializer&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The tables created with dataview are great inside of the Obsidian editor, but they won’t render in other markdown editors/viewers (e.g. GitHub READMEs). &lt;a href=&quot;https://github.com/dsebastien/obsidian-dataview-serializer&quot;&gt;The Obsidian Dataview Serializer&lt;/a&gt; solves this specific problem by live-updating a &lt;em&gt;“serialized”&lt;/em&gt; markdown version of the table. Every time the underlying data or the query changes, the plugin will update the markdown table accordingly.&lt;/p&gt;
&lt;h3 id=&quot;examples&quot;&gt;&lt;a href=&quot;#examples&quot;&gt;Examples&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Check out &lt;a href=&quot;https://github.com/marcjulianschwarz/obsidian-vault-blog&quot;&gt;this README of my blog post repository&lt;/a&gt; on GitHub to see it in action. It uses the second more complex query to provide links to all posts right in the README. There you should even be able to see this very post you are reading right now.&lt;/p&gt;
&lt;p&gt;What I like about this approach is that it works in all places that can render markdown tables. For example, I am also using the plugin to render a table of different types of coffee bean varieties on our German coffee and espresso wiki &lt;a href=&quot;https://the-brew-code.de/Kaffee/Kaffee-%C3%9Cbersicht&quot;&gt;the-brew-code.de&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>Copy Permalink to Line in Zed</title><link>https://marc-julian.com/blog/posts/copy-permalink-to-line-in-zed/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/copy-permalink-to-line-in-zed/</guid><pubDate>Sat, 31 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today I learned that you can copy a permanent link to a line of source code in Zed. It’s as simple as a right-click and selecting &lt;code&gt;Copy Permalink&lt;/code&gt; (the last option in the context menu). It will copy a GitHub link to that exact line of code to your clipboard. This is great for sharing an exact location in the codebase with your colleagues.&lt;/p&gt;</content:encoded></item><item><title>Serve Hugging Face Models in Ollama</title><link>https://marc-julian.com/blog/posts/huggingface-models-in-ollama/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/huggingface-models-in-ollama/</guid><pubDate>Sat, 31 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Ollama can &lt;strong&gt;serve&lt;/strong&gt; many Hugging Face models locally. Concretely, you can run any &lt;a href=&quot;https://github.com/ggml-org/ggml/blob/master/docs/gguf.md&quot;&gt;GGUF&lt;/a&gt; model from the Hugging Face Hub. Use &lt;a href=&quot;https://huggingface.co/models?library=gguf&quot;&gt;this GGUF filter&lt;/a&gt; on the Hugging Face website to get a list of models that Ollama support  (about 121,000 models at the time of writing). From the model card, you can click “&lt;em&gt;Use this model&lt;/em&gt;” to copy the ollama run command. For example:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;ollama run hf.co/unsloth/DeepSeek-R1-0528-Qwen3-8B-GGUF:Q4_K_M&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The commands have following structure:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;ollama run hf.co/{username}/{repository}:{quantization-scheme}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you leave out the &lt;code&gt;quantization-scheme&lt;/code&gt; part, Hugging Face will choose either &lt;code&gt;Q4_K_M&lt;/code&gt; when available and a reasonable version if not. See &lt;a href=&quot;https://huggingface.co/docs/hub/ollama&quot;&gt;this article on Hugging Face&lt;/a&gt; for more information.&lt;/p&gt;
&lt;h2 id=&quot;typescript-ollama-client&quot;&gt;&lt;a href=&quot;#typescript-ollama-client&quot;&gt;TypeScript Ollama Client&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Given an Ollama server running on &lt;code&gt;OLLAMA_API_BASE_URL&lt;/code&gt;, you can use the Ollama TypeScript client to do inference on any of those models like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;ts&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; { Ollama } &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &apos;ollama&apos;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; ollama &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; Ollama&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;({ host&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; OLLAMA_API_BASE_URL })&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;// Example to do inference with an embedding model&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; output &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;ollama&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;embed&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;      model&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;hf.co/chris-code/multilingual-e5-large-Q8_0-GGUF:Q8_0&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;      input&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;some text to be embedded&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;    })&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content:encoded></item><item><title>OpenTelemetry gRPC Exporter</title><link>https://marc-julian.com/blog/posts/grpcphoenix/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/grpcphoenix/</guid><pubDate>Sat, 12 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This is an update / followup for last weeks post on &lt;a href=&quot;https://marc-julian.com/blog/posts/phoenixllmtracing/&quot;&gt;OpenTelemetry LLM App Tracing with Phoenix&lt;/a&gt; which ended with following statement:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;because I noticed some span exporting issues to Phoenix I tried a different span/traces exporter: &lt;code&gt;ZipkinExporter&lt;/code&gt; with the &lt;a href=&quot;https://zipkin.io/&quot;&gt;Zipkin UI&lt;/a&gt; and there is still an &lt;a href=&quot;https://github.com/Arize-ai/phoenix/discussions/7041#discussioncomment-12736322&quot;&gt;open discussion&lt;/a&gt; on GitHub about the problems I noticed with Phoenix. Will update this post accordingly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After further debugging (breaking at every single &lt;code&gt;span.end()&lt;/code&gt; call) I was able to see that during some span creations, the error &lt;code&gt;Exception has occurred: Error: read ECONNRESET&lt;/code&gt; and &lt;code&gt;Exception has occurred: Error: socket hang up&lt;/code&gt; showed up. These spans were missing in Phoenix. &lt;a href=&quot;https://github.com/RogerHYang&quot;&gt;Roger Yang&lt;/a&gt; suggested to use the &lt;a href=&quot;https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-grpc&quot;&gt;experimental gRPC exporter&lt;/a&gt; like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;ts&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; { OTLPTraceExporter } &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;@opentelemetry/exporter-trace-otlp-grpc&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; provider &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; NodeTracerProvider&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;  spanProcessors&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;    new&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; SimpleSpanProcessor&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;      new&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; OTLPTraceExporter&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;        url&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;http://localhost:4317&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;      })&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;    )&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;  ]&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;})&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;registerInstrumentations&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;  instrumentations&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; OpenAIInstrumentation&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;()]&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;})&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;provider&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;register&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This exports spans directly via gRPC to port &lt;code&gt;4317&lt;/code&gt; of your Phoenix app. Make sure to use the &lt;a href=&quot;https://docs.arize.com/phoenix/self-hosting&quot;&gt;Docker images provided by Phoenix&lt;/a&gt; which automatically expose this port next to the default &lt;code&gt;6006&lt;/code&gt; port.&lt;/p&gt;
&lt;p&gt;With the above exporter configured, no spans go missing anymore and Phoenix captures even complex long running traces.&lt;/p&gt;</content:encoded></item><item><title>Remove macOS Sequoia Screen Capture Notifications</title><link>https://marc-julian.com/blog/posts/macos-screen-access-notifications/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/macos-screen-access-notifications/</guid><pubDate>Sat, 12 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;With a recent macOS Sequoia update, apps capturing your screen would trigger a new notification that shows next to the menubar. For apps like &lt;a href=&quot;https://alt-tab-macos.netlify.app/&quot;&gt;AltTab&lt;/a&gt; which take screenshots of your screen for their functionality, this results in a constant flood of notifications every time you use the app.&lt;/p&gt;
&lt;p&gt;Apparently, this new &lt;em&gt;“feature”&lt;/em&gt; was not on purpose. It should show a notification once every 30 days. But through some misconfiguration of the timestamps in the &lt;code&gt;ScreenCaptureApprovals.plist&lt;/code&gt; file, the notification was not limited to 30 days.
To fix this, find the file with:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;open&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; $HOME&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;/Library/Group&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt;\ &lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;Containers/group.com.apple.replayd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and move or delete the &lt;code&gt;ScreenCaptureApprovals.plist&lt;/code&gt; file from the opened folder. Then directly restart your Mac. The macOS system will automatically rewrite the file with corrected timestamps and the screen capture notifications don’t show up anymore.&lt;/p&gt;</content:encoded></item><item><title>Debugger Nest.js App</title><link>https://marc-julian.com/blog/posts/til-debugger-nestjs/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/til-debugger-nestjs/</guid><pubDate>Sat, 12 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today I learned that it’s easier than I thought to attach a debugger to a NestJS app in VS Code. Run the following commands in the command palette:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Debug: Toggle Auto Attach&lt;/li&gt;
&lt;li&gt;(Debug: Attach to Node Process)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the terminal, run the NestJS app in the usual way, for example &lt;code&gt;yarn start:dev&lt;/code&gt;. The debugger will now attach automatically.&lt;/p&gt;
&lt;p&gt;No need to edit any &lt;code&gt;launch.json&lt;/code&gt; files, awesome!&lt;/p&gt;</content:encoded></item><item><title>1-year Anniversary at AHEAD Automotive</title><link>https://marc-julian.com/blog/posts/aheadanniversary/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/aheadanniversary/</guid><pubDate>Sun, 06 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This week I had my &lt;strong&gt;1-year anniversary&lt;/strong&gt; at AHEAD Automotive. In this short time we built an entire product from scratch, which is now used by over 60 car workshops in Germany and soon released for everyone. The product, called &lt;a href=&quot;https://www.linkedin.com/company/qira-ai/&quot;&gt;Qira&lt;/a&gt;, is the intelligent assistant for the automotive aftermarket. Qira combines detailed repair information from data providers and original car manufacturers at a single point of access. With a simple natural language input field, car mechanics can ask Qira for&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;detailed vehicle data 🚗&lt;/li&gt;
&lt;li&gt;lubricants 💧&lt;/li&gt;
&lt;li&gt;component locations 📍&lt;/li&gt;
&lt;li&gt;repair manuals 🔧&lt;/li&gt;
&lt;li&gt;recalls ⚠️&lt;/li&gt;
&lt;li&gt;technical drawings 📝&lt;/li&gt;
&lt;li&gt;and much more…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Qira also interprets error codes to precisely describe their symptoms, causes and effects. Qira can predict affected components and suggests solutions based on past reports with the same error code. Qira will even guide users through step by step diagnosis instructions to accurately pin down faults in electrical components.&lt;/p&gt;
&lt;p&gt;All answers by Qira use reliable data sources and we made sure that our systems can not alter the provided information, so you can always be sure to get the most up to date and accurate information.&lt;/p&gt;
&lt;p&gt;I am proud that our hard work can now see the light of day and that Qira is already &lt;a href=&quot;https://www.linkedin.com/posts/qira-ai_werkstattzukunft-qira-ki-activity-7310308463698411521-s56_?utm_source=share&amp;#x26;utm_medium=member_desktop&amp;#x26;rcm=ACoAAFZNsFoBY9zXWmwyaotjwH3DzubIQ945gsk&quot;&gt;assisting car mechanics with their daily work.&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>OpenTelemetry LLM App Tracing with Phoenix</title><link>https://marc-julian.com/blog/posts/phoenixllmtracing/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/phoenixllmtracing/</guid><pubDate>Sun, 06 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I wanted to setup tracing for an LLM app with &lt;a href=&quot;https://phoenix.arize.com/&quot;&gt;Phoenix&lt;/a&gt; and while doing so I had some learnings that I wanted to document:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;you have to take &lt;code&gt;SimpleSpanProcessor&lt;/code&gt; by its name. It’s a &lt;strong&gt;simple&lt;/strong&gt; span processor. It’s nice for development but for production you should be using the &lt;code&gt;BatchSpanProcessor&lt;/code&gt; because it batches span exports, saving tons of network requests and probably avoiding some concurrency issues&lt;/li&gt;
&lt;li&gt;always make sure to end spans at the correct position, not too early, not too late, with &lt;code&gt;span.end()&lt;/code&gt;. If you are using one central place to create spans, end them right there after you added attributes to it&lt;/li&gt;
&lt;li&gt;if you use &lt;code&gt;SemanticConventions&lt;/code&gt;, make sure to check which attributes you actually need to set to get any visual on some dashboards (like Phoenix)&lt;/li&gt;
&lt;li&gt;separate tracing from business logic as much as possible. I am using a decorator for that specific purpose. It has access to the functions input, output and you call it by decorating a function with it. Now it stays out of the way of your business logic.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is an example implementation of such a &lt;code&gt;Trace&lt;/code&gt; decorator.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;ts&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; Trace&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;A&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; R&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;   traceName&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;   traceFunction&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; Span&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; args&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; A&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; R&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; ) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;   return&lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;     target&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt; unknown&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;     propertyKey&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;     descriptor&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; PropertyDescriptor&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;   ) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;     const&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; originalMethod &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; descriptor&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;     descriptor&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;args&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; A&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;       return&lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; tracer&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;startActiveSpan&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(traceName&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; Span&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;         const&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; result &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; originalMethod&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;call&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; args)&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;         traceFunction&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(span&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; args&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; result)&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;         span&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;end&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;         return&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;       })&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;     }&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;     return&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; descriptor&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;   }&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here is an example on how you can use it. As you can see the business logic in &lt;code&gt;doingSomeWork()&lt;/code&gt; is free of any tracing logic. Removing the &lt;code&gt;@Trace()&lt;/code&gt; decorator removes any tracing from it.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;ts&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; DoingSomeWorkParams&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	input&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;Trace&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;Doing Some Work&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; DoingSomeWorkParams&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; doingSomeWork&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;args&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; DoingSomeWorkParams&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; Promise&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;	// ... doing some work with args.input&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;	return&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; result&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; traceDoingSomeWork&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; Span&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; args&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; DoingSomeWorkParams&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt; string&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	span&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;setAttributes&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;     [SemanticConventions&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;OPENINFERENCE_SPAN_KIND]&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; OpenInferenceSpanKind&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;AGENT&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;     [SemanticConventions&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;INPUT_VALUE]&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; args&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;     [SemanticConventions&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;OUTPUT_VALUE]&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;    })&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Going on with the list of learnings:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;either use a &lt;code&gt;ConsoleSpanExporter&lt;/code&gt; or &lt;code&gt;diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);&lt;/code&gt; to see a lot of details about the tracing. Interesting are the &lt;code&gt;traceId&lt;/code&gt;, &lt;code&gt;parentId&lt;/code&gt; and &lt;code&gt;id&lt;/code&gt; attributes of each span. Here you can check whether the context got propagated nicely between the spans.&lt;/li&gt;
&lt;li&gt;because I noticed some span exporting issues to Phoenix I tried a different span/traces exporter: &lt;code&gt;ZipkinExporter&lt;/code&gt; with the &lt;a href=&quot;https://zipkin.io/&quot;&gt;Zipkin UI&lt;/a&gt; and there is still an &lt;a href=&quot;https://github.com/Arize-ai/phoenix/discussions/7041#discussioncomment-12736322&quot;&gt;open discussion&lt;/a&gt; on GitHub about the problems I noticed with Phoenix. Will update this post accordingly.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>Ghostty - My Favourite Terminal Emulator</title><link>https://marc-julian.com/blog/posts/ghostty/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/ghostty/</guid><pubDate>Mon, 13 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I stumbled upon &lt;a href=&quot;https://ghostty.org/&quot;&gt;Ghostty&lt;/a&gt; a nice looking open source terminal emulator. It feels fast, even comparable to native terminals. I have been using it for the past weeks in my macOS setup and found it to come close to the macOS &lt;code&gt;Terminal.app&lt;/code&gt; experience.&lt;/p&gt;
&lt;p&gt;What I enjoy most about Ghostty is its easy configuration. You can open and edit the config file with the keyboard shortcut &lt;code&gt;cmd + ,&lt;/code&gt; and reload it with &lt;code&gt;shift + cmd + ,&lt;/code&gt;. These are the settings I am using right now:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;background-opacity=0.9&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;background-blur-radius=30&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;font-size = 18&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;theme = GitHub Dark&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;background = #28394a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;foreground = #fafafb&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;palette = 0=#1d1f21&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;palette = 1=#c5474e&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;palette = 2=#68cd66&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;palette = 3=#d4ac3a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;palette = 4=#4386f6&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;palette = 5=#d856a6&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;palette = 6=#6ae1e4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;palette = 7=#feffff&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;palette = 8=#686767&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;palette = 9=#c6474e&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;palette = 10=#9ce5a3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;palette = 11=#d3ac3a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;palette = 12=#4386f6&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;palette = 13=#d856a6&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;palette = 14=#6ae1e4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;palette = 15=#feffff&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;window-padding-x = 15&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;window-padding-y = 10&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;keybind = option+super+left=previous_tab&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;keybind = option+super+right=next_tab&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;working-directory = home&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;window-inherit-working-directory = true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Btw, there is also this beautiful looking open source &lt;a href=&quot;https://ghostty.zerebos.com/&quot;&gt;Ghostty Config Generator&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title>Command Line - Aliases and Functions</title><link>https://marc-julian.com/blog/posts/tilterminalaliases/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/tilterminalaliases/</guid><pubDate>Wed, 05 Jul 2023 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Edit&lt;/strong&gt; (17.12.2024): After more than a year of using Oh My Zsh and custom aliases, my most used and favourite aliases are &lt;code&gt;go &amp;#x3C;marker-name&gt;&lt;/code&gt; (for going to a marked directory) and &lt;code&gt;b&lt;/code&gt; (short for back + performing &lt;code&gt;cd ..&lt;/code&gt;).  Oh My Zsh is awesome!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Edit&lt;/strong&gt; (20.07.2023): The open source framework &lt;a href=&quot;https://github.com/ohmyzsh/ohmyzsh&quot;&gt;ohmyzsh&lt;/a&gt;  makes it even easier to manage complex zsh configurations and there are tons of plugins that add useful aliases.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Today I learned (&lt;a href=&quot;https://www.marc-julian.de/tags/TIL.html&quot;&gt;TIL&lt;/a&gt;) that you can define aliases and functions inside of most command line applications like bash or zsh shells.
For zsh, you can find the &lt;code&gt;.zshrc&lt;/code&gt; config file directly in the user folder. You can edit it in any text editor (on some systems, you might need to open it as an admin or run your preferred command with &lt;code&gt;sudo&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Run the following command to execute the file and reload all defined aliases and functions.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;shell&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt;source&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; .zshrc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are some of &lt;em&gt;my favorites&lt;/em&gt;:&lt;/p&gt;
&lt;h2 id=&quot;conda&quot;&gt;&lt;a href=&quot;#conda&quot;&gt;Conda&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;shell&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# Run to get bash autocomplete functions in zsh shell &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt;autoload&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; bashcompinit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;bashcompinit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt;autoload&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -Uz&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; compinit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;compinit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# List all conda environments&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; envs&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;	conda&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; info&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; --env&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# Activate environment with autocompletion&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; aenv&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    conda&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; activate&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; $1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; extract_env_names&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;    # Extracts the names of the environments from the output of `conda info --env`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    conda&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; info&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; --env&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; awk&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -F&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &apos;{print $1}&apos;&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; tail&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -n&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; +3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; _aenv&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;    # Get the current word being completed&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;    local&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; cur&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;${COMP_WORDS[COMP_CWORD]}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;    # Generate possible matches and store them in the COMPREPLY variable&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;    # -W expects a list of possible matches&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;    COMPREPLY&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;($(&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;compgen&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -W&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;$(&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;extract_env_names&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;)&quot;&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; --&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; $cur))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# Register the completion function to be called for the aenv command&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;complete&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -F&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; _aenv&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; aenv&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; denv&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    conda&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; deactivate&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# Create a conda environment with a name and python version&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; cenv&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    conda&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; create&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -n&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; $1&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; python=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;$2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; renv&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    conda&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; remove&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -n&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; $1&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; --all&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# Create a python kernel from a conda environment&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; envtokernel&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    python&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -m&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; ipykernel&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; --user&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; --name&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; $1&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; --display-name&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;Python (&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;$1&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;)&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# Create a conda environment with some sane default packages that I use a lot in data science projects &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; defaultenv&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    cenv&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; $1&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; $2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    conda&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; activate&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; $1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    pip&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; pandas&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; numpy&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; matplotlib&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; seaborn&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; scikit-learn&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; notebook&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    envtokernel&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; $1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;mark-paths-to-directly-jump-to-them-from-anywhere&quot;&gt;&lt;a href=&quot;#mark-paths-to-directly-jump-to-them-from-anywhere&quot;&gt;Mark paths to directly jump to them from anywhere&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Inspired by the &lt;code&gt;mark&lt;/code&gt; and &lt;code&gt;cdd&lt;/code&gt; function in this &lt;a href=&quot;https://chris-said.io/2014/10/16/jumping-quickly-between-deep-directories/&quot;&gt;blog post&lt;/a&gt; by Chris Said, I added two more functions &lt;code&gt;opend&lt;/code&gt; and &lt;code&gt;coded&lt;/code&gt; to  open a folder in Finder or VSCode.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;shell&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# Run to get bash autocomplete functions in zsh shell &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt;autoload&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; bashcompinit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;bashcompinit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt;autoload&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -Uz&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; compinit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;compinit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; MARKPATH&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;/Users/username/marks&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# jump to a marked path&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; cdd&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;    # change directory to the marked path, if it does not exist, ignore the error and print &quot;No such mark: $1&quot; instead&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt;    cd&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -P&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;$MARKPATH&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;$1&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; 2&gt;&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;/dev/null&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; echo&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;No such mark: &lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;$1&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; opend&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    open&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;$MARKPATH&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;$1&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; 2&gt;&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;/dev/null&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; echo&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;No such mark: &lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;$1&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; coded&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    code&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;$MARKPATH&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;$1&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; 2&gt;&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;/dev/null&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; echo&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;No such mark: &lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;$1&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# mark a path for quick access&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; mark&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;    # create a folder to store marks&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    mkdir&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -p&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;$MARKPATH&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;    # create a symlink in the mark folder to the current directory&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    ln&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -s&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;$(&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt;pwd&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;)&quot;&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;$MARKPATH&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;$1&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# delete a mark&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; unmark&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;    # remove the symlink&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    rm&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -i&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;$MARKPATH&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;$1&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# list all marks&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; marks&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;    # list all symlinks in the mark folder with some formatting magic to make it look nicer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    \ls&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -l&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;$MARKPATH&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; tail&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -n&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; +2&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; sed&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &apos;s/  / /g&apos;&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; cut&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -d&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -f9-&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; awk&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -F&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &apos; -&gt; &apos;&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &apos;{printf &quot;%-10s -&gt; %s\n&quot;, $1, $2}&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# autocomplete marks&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; _cdd&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;    # get the current word being completed&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;    local&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; cur&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;${COMP_WORDS[COMP_CWORD]}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;    # generate possible matches and store them in the COMPREPLY variable&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;    COMPREPLY&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;($(&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;compgen&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -W&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;$(&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;ls&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; $MARKPATH&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;)&quot;&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; --&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; $cur))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# register the completion function to be called for the cdd command&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;complete&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -F&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; _cdd&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; cdd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;complete&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -F&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; _cdd&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; opend&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;complete&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -F&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; _cdd&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; coded&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;python&quot;&gt;&lt;a href=&quot;#python&quot;&gt;Python&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;shell&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; py&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    python&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; $1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; pyv&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    python&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; --version&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;streamlit&quot;&gt;&lt;a href=&quot;#streamlit&quot;&gt;Streamlit&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;shell&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; strun&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    streamlit&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; $1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;jupyter&quot;&gt;&lt;a href=&quot;#jupyter&quot;&gt;Jupyter&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;shell&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;alias&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; jnb&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;jupyter notebook&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;git&quot;&gt;&lt;a href=&quot;#git&quot;&gt;Git&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;shell&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; gitc&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    git&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; commit&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -m&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;$1&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;alias&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; gits&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;git status&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;alias&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; gitp&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;git push&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;alias&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; gitpl&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;git pull&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;alias&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; gitb&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;git branch&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;alias&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; gitl&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;git log&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;alias&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; gitd&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;git diff&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;npm&quot;&gt;&lt;a href=&quot;#npm&quot;&gt;NPM&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;shell&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;alias&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; ninit&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;npm init -y&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;alias&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; nstart&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;npm start&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;alias&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; nbuild&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;npm run build&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;alias&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; ntest&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;npm run test&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;alias&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; ninstall&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;npm install&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;imagemagick&quot;&gt;&lt;a href=&quot;#imagemagick&quot;&gt;ImageMagick&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;shell&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# d for do mogrify &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# I use this to automatically convert images for this blog &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; dmog&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;    mogrify&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -format&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; jpg&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -geometry&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; 1300x&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -quality&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; $1&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;.png&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content:encoded></item><item><title>Implementing a Simple Perceptron for Binary Classification</title><link>https://marc-julian.com/blog/posts/simpleperceptron/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/simpleperceptron/</guid><pubDate>Tue, 27 Jun 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We’ll be implementing a simple perceptron model for binary classification tasks using Python, and discussing the fundamentals of the perceptron model, including how it makes predictions and updates its weights during training.&lt;/p&gt;
&lt;p&gt;The first step in implementing a simple perceptron model is to define a class that contains the weights, training loop, and prediction methods.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; Perceptron&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;	def&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; __init__&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; lr&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;0.01&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; epochs&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;		self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;lr &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; lr &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;		self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;epochs &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; epochs &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;		self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;init_weights&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-light-font-style:italic;--shiki-dark:#FF8F40;--shiki-dark-font-style:italic&quot;&gt;TODO&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, we already set default values for hyperparameters like the learning rate (lr) and the number of epochs that the model should train for. We already initialize the weight and bias values with the &lt;code&gt;init_weights&lt;/code&gt; method.&lt;/p&gt;
&lt;h2 id=&quot;weight--bias-initialization&quot;&gt;&lt;a href=&quot;#weight--bias-initialization&quot;&gt;Weight &amp;#x26; Bias Initialization&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To initialize the weights and bias, we can either use constant values like 0 and 1, or we can choose random numbers.
Since our training data has two features, we need one weight per feature, so we use two random values for the weights here.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; init_weights&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;	self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;weights &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; torch&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;rand&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;) &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;	self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;bias &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; torch&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;rand&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;training-loop&quot;&gt;&lt;a href=&quot;#training-loop&quot;&gt;Training Loop&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now we are ready to work on the training loop. The basic idea is that we start predicting classes with random weight values in the model. We then compare the predicted (probably misclassified) class label with the expected class label to compute the error that the model has made.&lt;/p&gt;
&lt;p&gt;We then use the error to update the weights and bias by a small amount to get better predictions. We iterate over this process until the model converges or we reach the maximum epoch limit.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/percep8.jpg&quot; alt=&quot;&quot;&gt;&lt;/figure&gt;
&lt;p&gt;At each learning step (epoch), we loop through the entire data set and update the weights and bias by a small delta value.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/percep2.svg&quot; alt=&quot;&quot;&gt;&lt;/figure&gt;
&lt;p&gt;In the code, we can use two loops to iteratively update the values.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; fit&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; X&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; y&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;	for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; epoch &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; range&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;epochs)&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;		# for every data point and label&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;		for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; xi&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; yi &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; zip&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(X&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; y)&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;			weight_delta &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; ...&lt;/span&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt; # &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-light-font-style:italic;--shiki-dark:#FF8F40;--shiki-dark-font-style:italic&quot;&gt;TODO&lt;/span&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;			bias_delta &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; ...&lt;/span&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt; # &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-light-font-style:italic;--shiki-dark:#FF8F40;--shiki-dark-font-style:italic&quot;&gt;TODO&lt;/span&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;			# Update weigths&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;			self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;weights &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;weight_delta &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;			self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;bias &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;bias_delta&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Of course, the important part is calculating the correct delta values.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/percep3.svg&quot; alt=&quot;&quot;&gt;&lt;/figure&gt;
&lt;p&gt;can take different values depending on the predictions.
If the true and predicted classes are the same (0,0 or 1,1), the error will be equal to 0. In this case, everything is fine and we don’t need to update the weights.
In the two cases of misclassification (0,1 or 1,0), the error will be either  -1 or 1. Here we want to update the weights to hopefully get the prediction closer to the correct class in the next epoch.&lt;/p&gt;
&lt;p&gt;As you can see from the formula below, we update the weight according to the actual data points. This way, our data has an influence on the weight updates. Large values will have a higher impact than small values. This implies that our model benefits from feature scaling. One of the methods that could help is &lt;strong&gt;standardization&lt;/strong&gt; where you subtract the mean and divide by the standard deviation to center and scale your data points.&lt;/p&gt;
&lt;p&gt;We multiply by the learning rate to make smaller steps, which helps to get better convergence. The magnitude of the learning rate plays an essential role. Too large values will lead to rapid but unstable convergence, too low values will make the model converge slowly and it may even get stuck in local minima.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/percep4.svg&quot; alt=&quot;&quot;&gt;&lt;/figure&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; fit&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; X&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; y&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;	for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; epoch &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; range&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;epochs)&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;		for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; xi&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; yi &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; zip&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(X&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; y)&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;			# Compute the error and weight updates&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;			error &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; yi &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;predict&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(xi) &lt;/span&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-light-font-style:italic;--shiki-dark:#FF8F40;--shiki-dark-font-style:italic&quot;&gt;TODO&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;			weight_delta &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;lr &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; error &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; xi  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;			bias_delta &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;lr &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; error&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;			self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;weights &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;weight_delta &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;			self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;bias &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;bias_delta&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lastly, we have to implement the &lt;code&gt;predict&lt;/code&gt; method to be able to calculate the error.&lt;/p&gt;
&lt;h2 id=&quot;prediction&quot;&gt;&lt;a href=&quot;#prediction&quot;&gt;Prediction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For prediction, we compute a linear combination of the input data using the trained weights and bias. To get the corresponding class labels, we need to clip the values with a step function. This gives us a binary output, like the target variable.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; predict&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; X&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	output &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; X &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;weights &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;bias&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;	# Activation Function (in this case a simple step function)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	pred &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; torch&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;where&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(output &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0.0&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;) &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;	return&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; pred&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;using-the-perceptron-model&quot;&gt;&lt;a href=&quot;#using-the-perceptron-model&quot;&gt;Using the Perceptron Model&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To use the perceptron model, we first need to create some sample data using the scikit-learns &lt;code&gt;make_classification&lt;/code&gt; function. The resulting synthetic data set has two classes with two features.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;X_train&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; y_train &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; make_classification&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(n_samples&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; n_features&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; n_informative&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; n_redundant&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; random_state&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;40&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;plt&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;scatter&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(X_train[&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; X_train[&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; marker&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&apos;o&apos;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; c&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;y_train&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; s&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;25&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;plt&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;show&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/percep5.jpg&quot; alt=&quot;Scatter Plot for Binary Classification Problem&quot;&gt;&lt;figcaption&gt;Scatter Plot for Binary Classification Problem&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h3 id=&quot;prediction-with-random-weights&quot;&gt;&lt;a href=&quot;#prediction-with-random-weights&quot;&gt;Prediction with Random Weights&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;First, we create a perceptron instance and predict classes without training the model.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;perceptron &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; Perceptron&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(lr&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;0.01&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; epochs&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;y_pred &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; perceptron&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;predict&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(X_train)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;plt&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;scatter&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(X_train[&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; X_train[&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; marker&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&apos;o&apos;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; c&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;y_pred&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; s&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;25&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;plt&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;show&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can see that the random weights did not do a good job of separating the two classes.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/percep6.jpg&quot; alt=&quot;Bad Binary Classification Scatter Plot&quot;&gt;&lt;figcaption&gt;Bad Binary Classification Scatter Plot&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h3 id=&quot;prediction-with-trained-weights&quot;&gt;&lt;a href=&quot;#prediction-with-trained-weights&quot;&gt;Prediction with Trained Weights&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Now, let us fit the perceptron and see whether the results are any better.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;perceptron&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;fit&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(X_train&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; y_train)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;y_pred &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; perceptron&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;predict&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(X_train)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here we can see two different plots for the predictions. For the left one, I did not use any activation function which is why it shows the full range of values that the model predicted. For the right side, I used the step function from above.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/percep7.jpg&quot; alt=&quot;Good Binary Classification Scatter Plot&quot;&gt;&lt;figcaption&gt;Good Binary Classification Scatter Plot&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;After training, the model seems to be able to discriminate between the two classes. But, when comparing the predictions with the original data set we can see that some samples were still misclassified. This is expected because the perceptron model is trying to fit a &lt;strong&gt;linear&lt;/strong&gt; decision boundary while the two classes are actually &lt;strong&gt;not linearly&lt;/strong&gt; separable.
We could solve this problem by introducing more features, since in a higher dimensional space there may be a hyperplane that perfectly separates the classes. Of course, this will not always be possible which is why we need more complex models that can fit nonlinear decision boundaries.&lt;/p&gt;
&lt;h2 id=&quot;code&quot;&gt;&lt;a href=&quot;#code&quot;&gt;Code&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can find the complete code here and on &lt;a href=&quot;https://github.com/marcjulianschwarz/jupyter-notebooks&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; torch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; matplotlib&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;pyplot &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; plt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; sklearn&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;datasets &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; make_classification&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt; Perceptron&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;    def&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; __init__&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; lr&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;0.01&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; epochs&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;lr &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; lr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;epochs &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; epochs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;init_weights&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;    def&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; init_weights&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;weights &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; torch&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;rand&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;bias &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; torch&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;Tensor&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;([&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;    def&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; fit&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; X&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; y&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;        X &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; torch&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;Tensor&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(X)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;        y &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; torch&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;Tensor&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(y)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;        for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; epoch &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; range&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;epochs)&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;            total_error &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;            for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; xi&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; yi &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; zip&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(X&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; y)&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;                y_pred &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;predict&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(xi)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;                error &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; yi &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; y_pred&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;                self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;weights &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;lr &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; error &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; xi&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt;                self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;bias &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;lr &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; error&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;                total_error &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; error&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; epoch &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 10&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt;                print&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&apos;epoch &lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;epoch&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; \t&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; error &lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;total_error&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;    def&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; predict&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; X&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; activation&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;        X &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; torch&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;Tensor&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(X)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;        output &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; X &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;weights &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-light-font-style:italic;--shiki-dark:#39BAE6;--shiki-dark-font-style:italic&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;bias&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; activation&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;            output &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; torch&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;where&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(output &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0.0&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; output&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;perceptron &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; Perceptron&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(lr&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;0.01&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; epochs&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;200&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;perceptron&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;fit&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(X_train&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; y_train)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;y_pred &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; perceptron&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;predict&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(X_train)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content:encoded></item><item><title>VSCode Regex Group Reference in Find and Replace</title><link>https://marc-julian.com/blog/posts/tilvscoderegex/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/tilvscoderegex/</guid><pubDate>Tue, 13 Jun 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today I learned (&lt;a href=&quot;https://www.marc-julian.de/tags/TIL.html&quot;&gt;TIL&lt;/a&gt;) that you can reference regex groups in the &lt;em&gt;“Find and Replace”&lt;/em&gt; search of VSCode.&lt;/p&gt;
&lt;p&gt;For example, if you want to find a certain HTML tag to replace it with a different one, you could use the following regex expression in the search&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;p&gt;([.\W\w]*?)&amp;#x3C;/p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and use the captured group &lt;code&gt;$1&lt;/code&gt; in the replacement like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&amp;#x3C;h1&gt;$1&amp;#x3C;/h1&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ensure that you enabled regex syntax using the button in the search field on the right side.&lt;/p&gt;</content:encoded></item><item><title>Highlights from ML Prague Conference 2023</title><link>https://marc-julian.com/blog/posts/mlprague/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/mlprague/</guid><description>Insights and Takeaways</description><pubDate>Thu, 08 Jun 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Last week, I joined machine learning enthusiasts from around the world in Prague for Europe’s biggest conference on ML and AI applications, &lt;a href=&quot;https://mlprague.com/&quot;&gt;ML Prague 2023&lt;/a&gt;.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/mlprague_sign.jpg&quot; alt=&quot;ML Prague Conference 2023 sign at the entrance&quot;&gt;&lt;figcaption&gt;ML Prague Conference 2023 sign at the entrance&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;The event featured a broad lineup of speakers, covering a wide range of topics - from the latest breakthroughs in natural language processing to cutting-edge computer vision applications. In this blog post, I want to write about some of the most interesting talks from the conference and highlight the key takeaways. Without further ado, let’s dive in and start with two topics from the area of image processing.&lt;/p&gt;
&lt;h2 id=&quot;image-processing&quot;&gt;&lt;a href=&quot;#image-processing&quot;&gt;Image Processing&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;3d-pose-estimation-in-sport&quot;&gt;&lt;a href=&quot;#3d-pose-estimation-in-sport&quot;&gt;3D Pose Estimation in Sport&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.linkedin.com/in/piotr-skalski-36b5b4122/&quot;&gt;Piotr Skalski&lt;/a&gt; from Roboflow showed us how he was able to reproduce parts of the Video Assistant Referee (VAR) system shown in the following clip.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube-nocookie.com/embed/WycjDx6giVE&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;He used &lt;a href=&quot;https://github.com/WongKinYiu/yolov7&quot;&gt;YOLOv7&lt;/a&gt; and two cameras that record from different perspectives to track a skeleton of his body.&lt;/p&gt;
&lt;p&gt;When using this technique, there are some key points to consider:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;at least&lt;/strong&gt; two cameras with the same configuration
&lt;ul&gt;
&lt;li&gt;For best results, position them above the playing field to reduce player occlusions&lt;/li&gt;
&lt;li&gt;For better results, use more than two cameras&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Avoid or remove any lens distortion before processing the video recordings.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Take a look at his &lt;a href=&quot;https://github.com/SkalskiP/sport&quot;&gt;GitHub repository&lt;/a&gt; to see the results.&lt;/p&gt;
&lt;h3 id=&quot;multi-model-machine-learning-based-industrial-vision-tool-for-assembly-part-quality-control&quot;&gt;&lt;a href=&quot;#multi-model-machine-learning-based-industrial-vision-tool-for-assembly-part-quality-control&quot;&gt;Multi-Model Machine Learning based Industrial Vision Tool for Assembly Part Quality Control&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.linkedin.com/in/aimira-baitieva/?originalSubdomain=cz&quot;&gt;Aimira Baitieva&lt;/a&gt; from Valeo offered insights into anomaly detection in images using neural networks.&lt;/p&gt;
&lt;p&gt;One interesting idea was to train a model that outputs embeddings for images, which represent their information well enough. You could then create a &lt;em&gt;“good”&lt;/em&gt; embedding for normal parts (without anomalies) to compare against. If an embedded image has a dissimilarity above a certain threshold when compared with the good embedding, one can mark it as an anomaly.&lt;/p&gt;
&lt;p&gt;Their final &lt;strong&gt;multi-model&lt;/strong&gt; approach, consisted of three steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a segmented anomaly map:
&lt;ol&gt;
&lt;li&gt;Segment the image to get a segmentation map&lt;/li&gt;
&lt;li&gt;Use an anomaly detector to get an anomaly map&lt;/li&gt;
&lt;li&gt;Combine both maps&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Extract features from this map&lt;/li&gt;
&lt;li&gt;Classify the image based on the features.&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/mlprague_valeo.jpg&quot; alt=&quot;Image at Conference of multi-model approach&quot;&gt;&lt;figcaption&gt;Image at Conference of multi-model approach&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;This turned out to work well and is in use right now.&lt;/p&gt;
&lt;h2 id=&quot;large-language-models&quot;&gt;&lt;a href=&quot;#large-language-models&quot;&gt;Large Language Models&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;llm-driven-game-characters&quot;&gt;&lt;a href=&quot;#llm-driven-game-characters&quot;&gt;LLM-driven Game Characters&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.linkedin.com/in/marekrosa1/?originalSubdomain=cz&quot;&gt;Marek Rosa&lt;/a&gt; from GoodAI shared their progress in creating LLM-driven game characters.&lt;/p&gt;
&lt;p&gt;In their AI Game, characters use a large language model to generate their thoughts, actions and speech. The player can interact with them via a chat interface and with normal in-game actions like exchanging objects.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube-nocookie.com/embed/G7ZAPwji4i0?start=92&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;Every character has a long-term memory in the form of a vector database. The app preprocesses new thoughts and interactions and saves them into the database. When needed, it queries the database based on&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;recency&lt;/li&gt;
&lt;li&gt;importance&lt;/li&gt;
&lt;li&gt;and relevance.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The current context of the language model forms the short-term memory. This combination of short and long-term memory let’s agents learn continually by using it to plan actions based on past observations, experience, its current environment and thoughts.&lt;/p&gt;
&lt;p&gt;Personally, I think that LLMs will redefine the role of NPCs (Non-Player Characters) in video games. Today, the player-controlled character is often the central figure in the game’s story while other characters are less important.
In the future, the player will take on a more supporting role and the game does not have a defined protagonist. The story will be open-ended and allows the players &lt;strong&gt;and&lt;/strong&gt; NPCs to make choices that affect the outcome and direction of it.
More games will adopt a sandbox-style approach, like Minecraft, where there is no clear goal or ending of the game.&lt;/p&gt;
&lt;p&gt;Other interesting projects that try to use LLMs to create autonomous agents are&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Significant-Gravitas/Auto-GPT&quot;&gt;AutoGPT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/MineDojo/Voyager&quot;&gt;Voyager Minecraft Agent&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a href=&quot;#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In conclusion, the ML Prague Conference 2023 was a fantastic opportunity for ML professionals to come together, learn about the latest trends and innovations in the field, and connect with others. I had a great time and am glad that I was able to be there. I hope you enjoyed this short recap of the conference. If you’ve been there too, let’s connect on &lt;a href=&quot;https://www.linkedin.com/in/marcjulian/&quot;&gt;LinkedIn&lt;/a&gt; and have a chat about &lt;strong&gt;your&lt;/strong&gt; favorite talks.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/mlprague_evening.jpg&quot; alt=&quot;Prague City with evening sun&quot;&gt;&lt;figcaption&gt;Prague City with evening sun&lt;/figcaption&gt;&lt;/figure&gt;</content:encoded></item><item><title>Hackbay 2023 - A hackathon for everyone</title><link>https://marc-julian.com/blog/posts/hackbay/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/hackbay/</guid><description>Disrupting the DATEV HR Process with AI</description><pubDate>Mon, 05 Jun 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Last month, I attended the two-day &lt;a href=&quot;https://www.hackbay.de/&quot;&gt;Hackbay 2023 Hackathon&lt;/a&gt; and, together with &lt;a href=&quot;https://www.linkedin.com/in/maximilian-kasper-693648174/&quot;&gt;Maximilian Kasper&lt;/a&gt;, we worked on DATEV’s challenge called &lt;em&gt;“Disrupting DATEV’s HR Process with AI”&lt;/em&gt;.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/hackbay.jpg&quot; alt=&quot;Hackathon&quot;&gt;&lt;figcaption&gt;Hackathon&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;our-prototype&quot;&gt;&lt;a href=&quot;#our-prototype&quot;&gt;Our Prototype&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;On day one, we started with some brainstorming to generate good ideas that could make the HR process as easy and frictionless as possible for both the applicant and the company. In the end, we decided to concentrate on the part of the process where applicants search for job opportunities and companies try to find fitting candidates for their job offers.&lt;/p&gt;
&lt;p&gt;We wanted to create a job-offer platform that uses new advances in Natural Language Processing (NLP) to automatically suggest fitting jobs based on &lt;strong&gt;raw resume text&lt;/strong&gt; files. Applicants should be able to upload their resume and instantly see jobs that fit their academic and professional career, their skills, languages, and interests. Also, the applicant should be able to weigh their experiences and interests in a way such that the platform shows them relevant jobs.&lt;/p&gt;
&lt;p&gt;The platform removes the need for creating a detailed profile and relies on the applicant’s resume. This way, no extra work is necessary.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/hackbay_mac.jpg&quot; alt=&quot;Coding at the hackathon&quot;&gt;&lt;figcaption&gt;Coding at the hackathon&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;We decided to use &lt;a href=&quot;https://streamlit.io/&quot;&gt;Streamlit&lt;/a&gt; as the frontend framework to create a user interface that was fast to iterate on.&lt;/p&gt;
&lt;p&gt;For the recommendation system, we used the following approach:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create an embedding for the resume text
&lt;ol&gt;
&lt;li&gt;Use a &lt;code&gt;BertTokenizer&lt;/code&gt; to encode the text&lt;/li&gt;
&lt;li&gt;Use a &lt;code&gt;BertModel&lt;/code&gt; to embed the encoded tokens&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Create an embedding for every job posting
&lt;ol&gt;
&lt;li&gt;Use a &lt;code&gt;BertTokenizer&lt;/code&gt; to encode the text&lt;/li&gt;
&lt;li&gt;Use a &lt;code&gt;BertModel&lt;/code&gt; to embed the encoded tokens&lt;/li&gt;
&lt;li&gt;Use an &lt;code&gt;AnnoyIndex&lt;/code&gt; to store the embedding vectors for easy and fast retrieval via their similarity  (&lt;a href=&quot;https://github.com/spotify/annoy&quot;&gt;spotify/annoy&lt;/a&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Query the index with the resume embedding to get the &lt;strong&gt;k&lt;/strong&gt; most similar job postings&lt;/li&gt;
&lt;li&gt;Filter and sort similar job postings based on the user’s selected weights and hard constraints (e.g. location, language, etc.)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In the end, an applicant was able to upload their raw resume to the platform, which would automatically find the most fitting job postings and output them as a sorted list. The applicant could then apply to one or more of the listed jobs.&lt;/p&gt;
&lt;p&gt;Of course, this was a prototype, so there were still a lot of issues that one would have to tackle to actually bring the platform into production.&lt;/p&gt;
&lt;p&gt;For example, at the moment, companies and/or applicants could &lt;em&gt;hack&lt;/em&gt; the recommender by writing their job postings and resumes in a way such that they are semantically similar. An applicant could achieve this with long keyword lists that outweigh all other factors.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a href=&quot;#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In summary, we developed a prototype job-offer platform that utilizes NLP to suggest fitting job opportunities based solely on a resume text file. The platform removes the need for an applicant to create a detailed profile, simplifying the hiring process for both employers and applicants.&lt;/p&gt;
&lt;p&gt;Attending the Hackbay 2023 Hackathon was a valuable experience that allowed us to challenge ourselves to develop a ML solution within a short timeframe.&lt;/p&gt;
&lt;p&gt;You can check out the aftermovie for the 2023 Hackbay Hackathon to get a glimpse of the event’s highlights:&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube-nocookie.com/embed/IyNvbw1OFq4&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&gt;&lt;/iframe&gt;</content:encoded></item><item><title>Obsidian for Raycast - Now in New Hands</title><link>https://marc-julian.com/blog/posts/obsraycastnew/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/obsraycastnew/</guid><pubDate>Mon, 15 May 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As of 15th May 2023, I will no longer be an active developer for the &lt;a href=&quot;https://www.raycast.com/KevinBatdorf/obsidian&quot;&gt;Obsidian Raycast extension&lt;/a&gt; because I want to invest even more time for data science related topics.&lt;/p&gt;
&lt;p&gt;I want to thank all &lt;strong&gt;20,000&lt;/strong&gt; users and &lt;a href=&quot;https://github.com/KevinBatdorf/&quot;&gt;Kevin Batdorf&lt;/a&gt; for his effort in taking over the extension and further maintaining it to keep it alive for the community.&lt;/p&gt;</content:encoded></item><item><title>The Tensor Tournament 2023</title><link>https://marc-julian.com/blog/posts/tensortournament/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/tensortournament/</guid><description>Hackathon at FAU - organized by Machine Learning and Data Analytics Lab</description><pubDate>Fri, 03 Feb 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I had the opportunity to take part in &lt;a href=&quot;https://www.mad.tf.fau.de/2023/01/26/the-tensor-tournament-t3-recap/&quot;&gt;The Tensor Tournament Hackathon&lt;/a&gt; (organized by the &lt;a href=&quot;https://www.mad.tf.fau.de/&quot;&gt;Machine Learning and Data Analytics Lab&lt;/a&gt; at FAU) and I am happy to announce that our team, &lt;a href=&quot;https://www.linkedin.com/in/maximilian-kasper-693648174/&quot;&gt;Maximilian Kasper&lt;/a&gt; and &lt;a href=&quot;https://www.linkedin.com/in/marcjulian/&quot;&gt;me&lt;/a&gt;, emerged as the winners!
The hackathon was a six-hour event where teams had to solve three machine learning and deep learning problems. It was an intense and challenging experience, but also incredibly rewarding to put our skills to the test and come out on top.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/ttt_winners.jpg&quot; alt=&quot;Winning Team and Organizers&quot;&gt;&lt;figcaption&gt;Winning Team and Organizers&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;first-problem-the-gingerbread-chef&quot;&gt;&lt;a href=&quot;#first-problem-the-gingerbread-chef&quot;&gt;First Problem: The Gingerbread Chef&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The first problem was to build a machine learning model that could accurately &lt;strong&gt;predict the quality&lt;/strong&gt; of gingerbread on a scale of 0 (garbage) to 4 (delicious) based on the ingredients. This required us to use regression or classification models. After trying some models we ended up using a simple regression model. Our scores were good but not as good as we’d like, so we decided to try a rather unconventional approach by leveraging the AutoML package &lt;a href=&quot;https://auto.gluon.ai/stable/index.html&quot;&gt;AutoGluon&lt;/a&gt; to automatically train and evaluate lots of models with various hyperparameters. In the end, the model produced by AutoGluon was better than any of the other submissions. Apparently, simple problems become less relevant as automatic modeling gets better.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/ttt_scores.jpg&quot; alt=&quot;Score Leaderboard&quot;&gt;&lt;figcaption&gt;Score Leaderboard&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;second-problem-keep-your-distance&quot;&gt;&lt;a href=&quot;#second-problem-keep-your-distance&quot;&gt;Second Problem: Keep Your Distance&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Adaptive cruise control is a driver assist feature that automatically keeps a set distance to the car in front, or maintains the set speed if there is none. The correct estimation of the distance between yourself and other vehicles is thus paramount. Instead of costly radar or lidar sensors you intend to use a simple video camera for that purpose.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The dataset for the next problem consisted of a total of 1074 images with 1442 vehicle bounding boxes and their measured distance to the car.&lt;/p&gt;
&lt;p&gt;The goal of this problem was to &lt;strong&gt;predict the distance&lt;/strong&gt; from the given images and bounding boxes for each vehicle. To get a good first baseline we decided to use the tabular annotation data and leave the images for a later model.
To our surprise, after some feature engineering, a simple random forest regressor evaluated to a score of 0.95 on the test set. We suspect that the  features &lt;em&gt;“area of  bounding box”&lt;/em&gt; and “&lt;em&gt;angle to camera&lt;/em&gt;” were enough to explain the distance. The area has a direct causal relationship with the distance.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/ttt_cars.jpg&quot; alt=&quot;Example Train Image with cars and annotations&quot;&gt;&lt;figcaption&gt;Example Train Image with cars and annotations&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;final-problem-find-the-numbers&quot;&gt;&lt;a href=&quot;#final-problem-find-the-numbers&quot;&gt;Final Problem: Find The Numbers&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The final problem was by far the hardest one as it had an unusual train test split. The train dataset consisted of 24 images while the test set had over 10,000 images. Each image contained a random number of &lt;a href=&quot;https://www.tensorflow.org/datasets/catalog/mnist&quot;&gt;MNIST&lt;/a&gt; digits between 0 and 9 with random sizes in random positions.
The task was to &lt;strong&gt;recognize all digits&lt;/strong&gt; in the given images. The prediction for the following image could for example be &lt;em&gt;776186792825&lt;/em&gt;. The order of digits doesn’t matter, so &lt;em&gt;277698718625&lt;/em&gt; would also be a valid prediction.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/tensor_tournament.jpg&quot; alt=&quot;Example Train Image&quot;&gt;&lt;figcaption&gt;Example Train Image&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;The first approach we tried was to use an OCR-tool like &lt;a href=&quot;https://pypi.org/project/pytesseract/&quot;&gt;Python-tesseract&lt;/a&gt; to directly recognize the digits embedded in the image. After some preprocessing of the image (e.g. inverting the colors) we were able to classify some images, but the accuracy wasn’t great.&lt;/p&gt;
&lt;p&gt;We know that the images are from the MNIST dataset. As a lot of good models already exist for classifying MNIST digits, we decided to try cutting out the digits and classify each digit separately.
We used &lt;a href=&quot;https://opencv.org/&quot;&gt;OpenCV&lt;/a&gt; functions to cut out the digits, scale them to the correct size, sharpen the images, and perform other preprocessing steps to make them look as similar as possible to the MNIST digits.
We then trained a simple MNIST model and used it to classify each image in the test set. This approach worked much better than the previous OCR attempt.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a href=&quot;#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The hackathon was an incredible experience and I am grateful to have had the opportunity to be part of it. I would like to thank the organizers of the hackathon for putting on such a great event, and to Maximilian for being an incredible teammate. I am excited to see what the future holds for us in the world of data science.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/ttt_plakat.jpg&quot; alt=&quot;The Tensor Tournament Banner&quot;&gt;&lt;figcaption&gt;The Tensor Tournament Banner&lt;/figcaption&gt;&lt;/figure&gt;</content:encoded></item><item><title>Gurobi - Solving Mixed Integer Problems with Python</title><link>https://marc-julian.com/blog/posts/gurobi/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/gurobi/</guid><description>Capacitated and Uncapacitated Lot-Sizing Problems</description><pubDate>Sat, 31 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Solving a Mixed Integer Programming (MIP) Problem with Gurobi requires the &lt;a href=&quot;https://www.gurobi.com/products/gurobi-optimizer/&quot;&gt;Gurobi Optimizer&lt;/a&gt; and the Python package &lt;a href=&quot;https://support.gurobi.com/hc/en-us/articles/360044290292-How-do-I-install-Gurobi-for-Python-&quot;&gt;GurobiPy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Install the GurobiPy package with pip or conda:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;python&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -m&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; pip&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; gurobipy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;conda&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; -c&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; gurobi&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; gurobi&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;importing-package&quot;&gt;&lt;a href=&quot;#importing-package&quot;&gt;Importing package&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Import &lt;code&gt;gurobipy&lt;/code&gt; like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; gurobipy &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; gp&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; gurobipy &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; GRB&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;initialize-model&quot;&gt;&lt;a href=&quot;#initialize-model&quot;&gt;Initialize Model&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The next step is to initialize a Gurobi model. For this example problem, setting a constant with the name capacitated to &lt;code&gt;False&lt;/code&gt; will be necessary too. This variable defines whether you want to have production capacity constraints (LS-C) or not (LS-U).&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;m &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; gp&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;Model&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;ls&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;capacitated &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; False&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;constants&quot;&gt;&lt;a href=&quot;#constants&quot;&gt;Constants&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The situation for the example problem is the following:&lt;/p&gt;
&lt;p&gt;A production facility wants to make a plan for the next 8 months. They want to know the amount of products that the factory has to produce each month to fulfill the demand in that month and reduce the costs which consist of&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Production costs for one product: 100€&lt;/li&gt;
&lt;li&gt;Preparing the machines at the beginning of a month (if the machines are running in that month):  5000€&lt;/li&gt;
&lt;li&gt;Storing one product for a month:  5€&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are all constants that won’t change during the optimization of the model. That’s why you don’t have to add them to the model.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# Time (e.g. months)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;n &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 8&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;t &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; range&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; n)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# Costs for production of one product for each month&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;p &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; t]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# Costs for storing a product for each month&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;h &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; t]  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# Costs for armoring the machines for each month (at most once for each month)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;q &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;5000&lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; t]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# Demand for products for each month&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;d &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;400&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 400&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 800&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 800&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 1200&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 1200&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 1200&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 1200&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;add-variables&quot;&gt;&lt;a href=&quot;#add-variables&quot;&gt;Add Variables&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To describe the objective function and constraints of the model, add variables with specified types to the model.&lt;/p&gt;
&lt;p&gt;The number of products produced each month (&lt;code&gt;x&lt;/code&gt;) will have to be an integer variable as the facility can’t produce fractions of a product. The same constraint holds for the storage of finished products (&lt;code&gt;s&lt;/code&gt;).
The storage amount will have one extra entry in comparison to the other variables as there will be an initial stock from the month before.&lt;/p&gt;
&lt;p&gt;The variable &lt;code&gt;y&lt;/code&gt; is binary as it controls whether the facility has to prepare the machines (1) or not (0).&lt;/p&gt;
&lt;p&gt;The one difference between the Uncapacitated and Capacitated Lot-Sizing problem lies in the definition of the capacity constraining variable &lt;code&gt;M&lt;/code&gt;.
For the uncapacitated case, the variable has no bound and will always be big enough to produce any amount of products. In the capacitated case it will consist of a list of capacities.
In the code example below, the model selects capacities in a way to minimize the preparation costs of the machines.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# Production Amount for each month&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; m&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;addVars&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(n&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; vtype&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt;GRB&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt;INTEGER&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# Storage Amount for each month&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;s &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; m&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;addVars&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(n &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;s&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; vtype&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt;GRB&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt;INTEGER&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# Production Preparation necessary for each month (0 or 1)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;y &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; m&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;addVars&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(n&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;y&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; vtype&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt;GRB&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt;BINARY&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# Production Capacity for each month (in this case unbounded -&gt; LS-U)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; capacitated&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	M &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;7000&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	M &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; m&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;addVars&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(n&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;M&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; vtype&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt;GRB&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt;INTEGER&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;objective-function&quot;&gt;&lt;a href=&quot;#objective-function&quot;&gt;Objective Function&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As described above, the facility wants to minimize the costs. They consist of the sum of costs for producing products, preparing machines, and storing products.
Thus, the objective function has to look like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;m&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;setObjective&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(gp&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;quicksum&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(p[i] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; x[i] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; q[i] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; y[i] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; h[i] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; s[i&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; t)&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt; GRB&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt;MINIMIZE&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;linear-constraints&quot;&gt;&lt;a href=&quot;#linear-constraints&quot;&gt;(Linear) Constraints&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now, define all constraints of the model.&lt;/p&gt;
&lt;p&gt;The first two constraints ensure that the facility fulfills their demand and stores the excess for the next month.&lt;/p&gt;
&lt;p&gt;Constraints three and four will control the initial and final stock.&lt;/p&gt;
&lt;p&gt;Constraint five adds capacity constraints to the model. As stated before, &lt;code&gt;M&lt;/code&gt; will either not have a bound or have specific capacity restrictions.&lt;/p&gt;
&lt;p&gt;The last three positivity constraints make sure that the machines don’t produce negative amounts of products and that the storage does not contain a negative amount of stored products.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# Stored products from the previous month plus the number of products produced in the current&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# month must fulfill the demand while the rest of the products must be stored for the next month&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;m&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;addConstrs&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;((s[i&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; x[i&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; d[i&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; s[i] &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; range&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; n&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;))&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;c1&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;m&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;addConstr&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;((s[&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; x[&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; d[&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; s[&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;])&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;c2&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# The number of products stored in the first month must be equal to 200 (Initial stock)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;m&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;addConstr&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(s[&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 200&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;c3&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# The number of products stored in the last month must be equal to 0 (Final stock)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;m&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;addConstr&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(s[n] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;c4&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# If products are being produced in the current month the machines must be prepared&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;m&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;addConstrs&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;((x[i] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;&amp;#x3C;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; M[i]&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;y[i] &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; t)&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;c5&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# There cant be a negative number of products stored in the warehouse or produced&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;m&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;addConstrs&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;((x[i] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; t)&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;c6&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;m&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;addConstrs&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;((s[i] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; t)&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;c7&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;m&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;addConstrs&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;((M[i] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; t)&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;c8&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#E65050;--shiki-dark:#D95757&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;mathematical-model&quot;&gt;&lt;a href=&quot;#mathematical-model&quot;&gt;Mathematical Model&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The resulting mathematical model would look like this:&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/LS_U_Problem_Model.svg&quot; alt=&quot;Mathematical LP model&quot;&gt;&lt;figcaption&gt;Mathematical LP model&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;optimizing&quot;&gt;&lt;a href=&quot;#optimizing&quot;&gt;Optimizing&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The function call&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;m&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;optimize&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;does everything we need to solve this optimization problem.&lt;/p&gt;
&lt;p&gt;Gurobi will use the Branch-and-Bound algorithm as the model consists solely of linear constraints and a linear objective function, with (mixed) integer variables (IP).&lt;/p&gt;
&lt;h2 id=&quot;evaluation&quot;&gt;&lt;a href=&quot;#evaluation&quot;&gt;Evaluation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;These are the results for the given problem:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Gurobi Optimizer version 9.5.2 build v9.5.2rc0 (mac64[rosetta2])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Thread count: 10 physical cores, 10 logical processors, using up to 10 threads&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Optimize a model with 35 rows, 33 columns and 53 nonzeros&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Model fingerprint: 0xa7ef1cf7&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Model has 8 quadratic constraints&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Variable types: 0 continuous, 33 integer (8 binary)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Coefficient statistics:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Matrix range     [1e+00, 1e+00]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  QMatrix range    [1e+00, 1e+00]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  QLMatrix range   [1e+00, 1e+00]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Objective range  [5e+00, 5e+03]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Bounds range     [1e+00, 1e+00]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  RHS range        [2e+02, 1e+03]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Presolve removed 29 rows and 4 columns&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Presolve time: 0.00s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Presolved: 30 rows, 53 columns, 74 nonzeros&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Presolved model has 16 SOS constraint(s)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Variable types: 0 continuous, 53 integer (16 binary)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Found heuristic solution: objective 859000.00000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Found heuristic solution: objective 830000.00000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Found heuristic solution: objective 822000.00000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Root relaxation: objective 7.170501e+05, 13 iterations, 0.00 seconds (0.00 work units)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Nodes    |    Current Node    |     Objective Bounds      |     Work&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;     0     0 717050.070    0    6 822000.000 717050.070  12.8%     -    0s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;H    0     0                    737000.00000 717050.070  2.71%     -    0s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;H    0     0                    736000.00000 727633.403  1.14%     -    0s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;     0     0 736000.000    0    5 736000.000 736000.000  0.00%     -    0s&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Cutting planes:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Implied bound: 7&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Flow cover: 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Explored 1 nodes (20 simplex iterations) in 0.01 seconds (0.00 work units)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Thread count was 10 (of 10 available processors)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Solution count 5: 736000 737000 822000 ... 859000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Optimal solution found (tolerance 1.00e-04)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Best objective 7.360000000000e+05, best bound 7.360000000000e+05, gap 0.0000%&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As one can see the optimal solution is equal to 736,000€ of costs.&lt;/p&gt;
&lt;p&gt;Printing out the variables reveals the number of products that the facility has to produce in each month to achieve these minimal costs.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; v &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; m&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;getVars&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;	if&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; v&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;varName&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;startswith&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt;		print&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;Produce &lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt;{}&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; products in month &lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt;{}&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;format&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(v&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; v&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;varName[&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;]))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;--------------------------------&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;Total cost: &lt;/span&gt;&lt;span style=&quot;color:#4CBF99;--shiki-dark:#95E6CB&quot;&gt;{}&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;format&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(m&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;objVal))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Produce 600.0 products in month [0] &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Produce 0.0 products in month [1] &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Produce 1600.0 products in month [2] &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Produce 0.0 products in month [3] &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Produce 1200.0 products in month [4] &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Produce 1200.0 products in month [5] &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Produce 1200.0 products in month [6] &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Produce 1200.0 products in month [7] &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;-------------------------------- &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Total cost: 736000.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content:encoded></item><item><title>Text Generation using Markov Chains</title><link>https://marc-julian.com/blog/posts/textgenmarkov/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/textgenmarkov/</guid><pubDate>Mon, 25 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Let’s create a simple text generation model using Markov chains. You can play with &lt;a href=&quot;https://marcjulianschwarz-markov-chain-text-genera-generate-text-m4bkd9.streamlitapp.com&quot;&gt;this demo&lt;/a&gt; to see what we’re trying to build today.&lt;/p&gt;
&lt;h2 id=&quot;what-is-a-markov-chain&quot;&gt;&lt;a href=&quot;#what-is-a-markov-chain&quot;&gt;What is a Markov Chain?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A basic Markov chain consist of three main parts&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a state space,&lt;/li&gt;
&lt;li&gt;a transition matrix&lt;/li&gt;
&lt;li&gt;and an initial distribution&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We will go through the example of &lt;strong&gt;Weather Forecast for the next X days&lt;/strong&gt; to get a better understanding of the different parts.&lt;/p&gt;
&lt;p&gt;For a state space we could think of the following states:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rain 🌧️&lt;/li&gt;
&lt;li&gt;Sun ☀️&lt;/li&gt;
&lt;li&gt;Snow ❄️&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Of course, to model the real weather we might want to increase the size of the state space by a lot.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now, we can model the weather by providing different probabilities to get from one state to another.&lt;/p&gt;
&lt;p&gt;The probabilities (also known as &lt;strong&gt;transition matrix&lt;/strong&gt;) could for example be&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;0.2 for 🌧️  → ☀️&lt;/li&gt;
&lt;li&gt;0.3 for 🌧️ → ❄️&lt;/li&gt;
&lt;li&gt;0.5 for 🌧️ → 🌧️&lt;/li&gt;
&lt;li&gt;0.3 for ❄️ → 🌧️&lt;/li&gt;
&lt;li&gt;0.1 for ❄️ → ☀️&lt;/li&gt;
&lt;li&gt;0.6 for ❄️ → ❄️&lt;/li&gt;
&lt;li&gt;0.1 for ☀️ → ❄️&lt;/li&gt;
&lt;li&gt;0.2 for ☀️ → 🌧️&lt;/li&gt;
&lt;li&gt;0.7 for ☀️ → ☀️&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now let us do a 5 day weather forecast and on day one the sun is shining (this first state is also known as the &lt;strong&gt;Initial Distribution&lt;/strong&gt;). We have to sample from our state space with the probabilities from above to determine the next state for a given current state.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Day 1&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Current State: ☀️&lt;/li&gt;
&lt;li&gt;Sample State: ☀️&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Day 2&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Current State: ☀️&lt;/li&gt;
&lt;li&gt;Sample State: ☀️&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Day 3&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Current State: ☀️&lt;/li&gt;
&lt;li&gt;Sample State: 🌧️&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Day 4&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Current State: 🌧️&lt;/li&gt;
&lt;li&gt;Sample  State: 🌧️&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Day 5&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Current State: 🌧️&lt;/li&gt;
&lt;li&gt;Sample State: ❄️&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, the weather forecast will look like this:&lt;/p&gt;
&lt;p&gt;☀️ → ☀️ → 🌧️ → 🌧️ → ❄️ → …&lt;/p&gt;
&lt;h2 id=&quot;text-generation-with-markov-chains&quot;&gt;&lt;a href=&quot;#text-generation-with-markov-chains&quot;&gt;Text Generation with Markov Chains&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We can apply the same concept to words of a given text. Each unique word represents a single state. A sentence is a sequence of states that were sampled from a state space.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a state space&lt;/li&gt;
&lt;li&gt;Compute probabilities for the transition matrix&lt;/li&gt;
&lt;li&gt;Sample from the state space with the transition matrix&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;1-create-a-state-space&quot;&gt;&lt;a href=&quot;#1-create-a-state-space&quot;&gt;1. Create a State Space&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;We will create the state space from a given source text.&lt;/p&gt;
&lt;p&gt;To do this, we read in the text as a string and split the text into individual words, often called &lt;strong&gt;tokens&lt;/strong&gt;. Then we make sure that we have unique states by creating a set which is often called the &lt;strong&gt;vocab&lt;/strong&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;with&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; open&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;source_text.txt&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;r&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	source_text &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;read&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# Split the text into all tokens (words)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;tokens &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; source_text&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;# This will make sure that we only have unique states&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;states &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(tokens))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;2-calculate-probabilites-transition-matrix&quot;&gt;&lt;a href=&quot;#2-calculate-probabilites-transition-matrix&quot;&gt;2. Calculate Probabilites (Transition Matrix)&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The transition matrix contains all possibilities of a state &lt;code&gt;i&lt;/code&gt; followed by a state &lt;code&gt;j&lt;/code&gt;. So we create a matrix with &lt;code&gt;len(states)&lt;/code&gt; rows and &lt;code&gt;len(states)&lt;/code&gt; columns:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;transition_matrix &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;zeroes&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(states)&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; len&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(states)))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First, we count the number of occurrences for each state and each state transition (i.e. two words following each other).&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;state_transition_counts &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;state_counts &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; state &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; enumerate&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(states)&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;	if&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; len&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(states) &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;		# Get the transition from current to next state&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;		state_transition &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; (state&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; states[i &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;		state_transition_counts[from_to] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; state_transition_counts&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(state_transition&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;		state_counts[state] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; state_counts&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(state&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, for each state transition, we calculate its relative frequency and store this probability in the transition matrix at an index that we get by encoding each state transition with two integers (the two states index in the vocab list).&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; state_transition&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; count &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; state_transition_counts&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;items&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	from_state&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; to_state &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; state_transition&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#ADAEB1;--shiki-light-font-style:italic;--shiki-dark:#5A6673;--shiki-dark-font-style:italic&quot;&gt;	# Relative Frequency &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	probability &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; count &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; state_counts[from_state]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	matrix_row_index &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; states&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(from_state)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	matrix_col_index &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; states&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(to_state)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	transition_matrix[matrix_row_index&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; matrix_col_index] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; probability&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/transition_matrix.jpg&quot; alt=&quot;Scatter Plot of a Transition Matrix&quot;&gt;&lt;figcaption&gt;Scatter Plot of a Transition Matrix&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h3 id=&quot;3-sample-from-the-transition-matrix&quot;&gt;&lt;a href=&quot;#3-sample-from-the-transition-matrix&quot;&gt;3. Sample from the Transition Matrix&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Now, we are ready to sample words from the transition matrix. As we saw above, we need a &lt;em&gt;current&lt;/em&gt; state to begin generating more states.
A more sophisticated way than having a fixed first state is to provide an &lt;strong&gt;initial distribution&lt;/strong&gt; that contains probabilities for each word to come first.&lt;/p&gt;
&lt;p&gt;The initial distribution is a vector of length &lt;code&gt;len(states)&lt;/code&gt;. With it we can force certain words to be more likely to start the Markov chain. In an extreme case we might want the generated text to start with a certain word (e.g.: &lt;em&gt;“The”&lt;/em&gt;). We look for the index of &lt;em&gt;“The”&lt;/em&gt; in our states and set that index to 1 in the initial distribution vector and all other indices to 0.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;initial_distribution &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;zeroes&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(states))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;initial_distribution[states&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;The&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;)] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We could also use a list of possible sentence beginnings, which should all start a sentence with equal probability.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;initial_distribution &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;zeroes&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(states))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;sentence_beginnings &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt;&quot;The&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;This&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;I&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;You&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;We&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;That&quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; sentence_beginning &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; sentence_beginnings&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;								 &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	initial_distribution[states&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(sentence_beginning)] &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; /&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; len&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(sentence_beginnings)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To generate a text, we sample words from the list of states with a probability determined by the initial distribution and the transition matrix until we reach a maximum text length. If there is no initial distribution, we randomly choose a starting word.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt; generate_text&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;tokens&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; List[&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; length&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt; int&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; P_matrix&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;ndarray&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; P_init&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;ndarray&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt;None&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;-&gt;&lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt; str&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	text &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;	if&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; P_init &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;is&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt; not&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; None&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;		current_token &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;random&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;choice&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(tokens&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; p&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;P_init)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;	else&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;		current_token &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;random&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;choice&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(tokens)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;	text&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;append&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(current_token)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;	for&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#F07171;--shiki-dark:#F07178&quot;&gt; range&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(length)&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;		current_token &lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;random&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;choice&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(tokens&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; p&lt;/span&gt;&lt;span style=&quot;color:#F2A191;--shiki-dark:#F29668&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;P_matrix[tokens&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(current_token)])&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;		text&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;append&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(current_token)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FA8532;--shiki-dark:#FF8F40&quot;&gt;	return&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot; &quot;&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;join&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(text)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;try-it&quot;&gt;&lt;a href=&quot;#try-it&quot;&gt;Try it&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now have fun generating texts. Be sure to try different source texts and see how that affects the quality of the generated text.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA400;--shiki-dark:#FFB454&quot;&gt;generate_text&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;(states&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A37ACC;--shiki-dark:#D2A6FF&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt; transition_matrix)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also try out the &lt;a href=&quot;https://marcjulianschwarz-markov-chain-text-genera-generate-text-m4bkd9.streamlitapp.com/&quot;&gt;text generation web app&lt;/a&gt; I built and take a look at the &lt;a href=&quot;https://github.com/marcjulianschwarz/markov-chain-text-generation&quot;&gt;GitHub repo&lt;/a&gt; which contains the source code.&lt;/p&gt;
&lt;h2 id=&quot;examples&quot;&gt;&lt;a href=&quot;#examples&quot;&gt;Examples&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Some German examples.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Winchester, Spring Valley, das Anstauen des Colorado River und teuer, um diese Gärten der Wasserknappheit &gt; Wir sind die Bevölkerung muss als in Hotelzimmern von Las Vegas, der Stadt, näher betrachtet werden mit etwa vier Prozent aus dem Haus kein wertvoller Baugrund verwendet, welches bis zu minimieren, muss das Licht auf die Wiederverwendung von Las Vegas. Um die Sicherung der Wasserversorgung&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Glücksspielmetropole der Hotels können selbst schon durch diesen neuen wassersparenden Technologien wie Kakteen in der größte Bereich der vielen exotischen Pflanzen und hat sich als in sonnenbetriebene Kraftwerke investieren. Besonders die Zukunft der Bau des Wassers ist der Lebensraum geraubt. Auch die Uhr mit Trockenzeiten in keinster Weise optimal für die Behörde sogar ganz gestoppt werden. Ein bekannter botanischer Garten, ist &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;individuellen Leistungsstand an die Höhe in Extremsportarten in den Rest des Selbstbewusstseins und unabhängig an positiven Gefühle, die er sich mit ihr umzugehen und hilft uns vor einem keine allgemeine Definition für sich relativ einfach nur das eigene Wohlempfinden zu gefährden, lässt sich lohnt dieses Risiko verbunden. Durch die Angst. Die Angst die Bremsen nicht vorhanden. 5 Fazit vorgestellt, in Hunderten&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content:encoded></item><item><title>ESP8266 Height-Adjustable Desk Control with Home Assistant Integration</title><link>https://marc-julian.com/blog/posts/hacking-my-smart-desk/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/hacking-my-smart-desk/</guid><pubDate>Thu, 12 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;project-overview&quot;&gt;&lt;a href=&quot;#project-overview&quot;&gt;Project Overview&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The goal of this project is to control a height-adjustable desk from a Home Assistant button while still preserving the functionality of the manual button controls on the table itself.&lt;/p&gt;
&lt;h2 id=&quot;prerequisites&quot;&gt;&lt;a href=&quot;#prerequisites&quot;&gt;Prerequisites&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;These are the exact tools, hardware, and software I used. You can exchange most components with other similar ones.&lt;/p&gt;
&lt;h3 id=&quot;hardware&quot;&gt;&lt;a href=&quot;#hardware&quot;&gt;Hardware&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;NodeMCU Lua Lolin V3 Module ESP8266 ESP-12F WIFI Development Board with CH340&lt;/li&gt;
&lt;li&gt;At least 8 jumper wires&lt;/li&gt;
&lt;li&gt;One &lt;em&gt;2-Channel Relay Module 5V with Optocoupler Low-Level Trigger&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Three &lt;em&gt;WAGO 221 Terminal Block 3 Connectors&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;USB-A to Micro-USB cable for powering the board and flashing code&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;tools&quot;&gt;&lt;a href=&quot;#tools&quot;&gt;Tools&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Scissors to cut the cable&lt;/li&gt;
&lt;li&gt;Cable insulation stripping tool&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;software&quot;&gt;&lt;a href=&quot;#software&quot;&gt;Software&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.arduino.cc/software/ide/#ide-v2&quot;&gt;Arduino IDE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Running &lt;a href=&quot;https://www.home-assistant.io/&quot;&gt;Home Assistant&lt;/a&gt; instance&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;safety-warnings&quot;&gt;&lt;a href=&quot;#safety-warnings&quot;&gt;Safety Warnings&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The instructions contain steps that permanently alter parts of the desk. If not followed properly, they &lt;strong&gt;CAN damage&lt;/strong&gt; the desk controller, engine, and other parts on or around the table. Make sure to remove any items on, around, and under the desk before performing the steps.&lt;/p&gt;
&lt;p&gt;The instructions are generally safe to follow, as they deal with low-voltage parts of the table. Nonetheless, be careful and do NOT make any changes to parts that run high voltages. Always check the components with a multimeter before working on them and unplug all cables.&lt;/p&gt;
&lt;h2 id=&quot;step-by-step-guide&quot;&gt;&lt;a href=&quot;#step-by-step-guide&quot;&gt;Step-by-Step Guide&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;understanding-the-desk-controls&quot;&gt;&lt;a href=&quot;#understanding-the-desk-controls&quot;&gt;Understanding the Desk Controls&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The desk controls consist of three cables. The following figures show a schematic view of those cables. The colors are for illustrative purposes and might be different for your specific desk.&lt;/p&gt;
&lt;p&gt;The green (left) cable connects the controller with the &lt;code&gt;Raise&lt;/code&gt; button, and the blue (right) one connects with the &lt;code&gt;Lower&lt;/code&gt; button. One black cable connects both buttons back to the table to form a closed circuit. The open buttons interrupt this loop. Pressing a button closes the respective circuit, letting the desk controller know to start the engine for raising or lowering the table.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/desk-diag.jpg&quot; alt=&quot;&quot;&gt;&lt;/figure&gt;
&lt;p&gt;At this point, it’s straightforward to intercept the button presses by directly connecting the green and blue wires with the orange wire, thereby creating a closed circuit before the button is even reached.&lt;/p&gt;
&lt;h3 id=&quot;cut-the-cable&quot;&gt;&lt;a href=&quot;#cut-the-cable&quot;&gt;Cut the Cable&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To get access to the individual cables, cut the cable running from the button controls to the desk, and remove the insulation around it and the individual smaller cables for about 1-2 cm.&lt;/p&gt;
&lt;h4 id=&quot;automating-a-button-click&quot;&gt;&lt;a href=&quot;#automating-a-button-click&quot;&gt;Automating a Button Click&lt;/a&gt;&lt;/h4&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/desk-relay-diag.jpg&quot; alt=&quot;&quot;&gt;&lt;/figure&gt;
&lt;h4 id=&quot;controlling-the-relays&quot;&gt;&lt;a href=&quot;#controlling-the-relays&quot;&gt;Controlling the Relays&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Relays don’t do anything on their own. You need a microcontroller to control them. For example, you can use the NodeMCU ESP8266 development board. The board has to provide power, ground, and two data pins. Each data pin controls one of the relays. Now the circuit is complete, and you can program the ESP.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/desk-controller-diag.jpg&quot; alt=&quot;&quot;&gt;&lt;/figure&gt;
&lt;h3 id=&quot;programming-the-controller&quot;&gt;&lt;a href=&quot;#programming-the-controller&quot;&gt;Programming the Controller&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Open &lt;a href=&quot;/esp8266.ino&quot;&gt;esp8266.ino&lt;/a&gt; in the Arduino IDE and set all configuration variables.&lt;/p&gt;
&lt;h3 id=&quot;home-assistant-setup&quot;&gt;&lt;a href=&quot;#home-assistant-setup&quot;&gt;Home Assistant Setup&lt;/a&gt;&lt;/h3&gt;
&lt;h4 id=&quot;1-install-mqtt-broker&quot;&gt;&lt;a href=&quot;#1-install-mqtt-broker&quot;&gt;1. Install MQTT Broker&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Install &lt;a href=&quot;https://www.home-assistant.io/integrations/mqtt/&quot;&gt;Mosquitto Broker Add-on&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Start Add-on with default configuration&lt;/li&gt;
&lt;li&gt;Add new &lt;code&gt;mqtt&lt;/code&gt; user under &lt;code&gt;Settings &gt; People&lt;/code&gt; and allow login&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;2-add-mqtt-integration&quot;&gt;&lt;a href=&quot;#2-add-mqtt-integration&quot;&gt;2. Add MQTT Integration&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;The MQTT integration should appear under &lt;code&gt;Settings &gt; Devices &amp;#x26; services&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add the integration&lt;/li&gt;
&lt;li&gt;Here you can try publishing packets to the &lt;code&gt;desk&lt;/code&gt; topic. Set your payload to &lt;code&gt;down&lt;/code&gt; or &lt;code&gt;up&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;3-add-switch-in-home-assistant-configuration&quot;&gt;&lt;a href=&quot;#3-add-switch-in-home-assistant-configuration&quot;&gt;3. Add Switch in Home Assistant Configuration&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Use the Text Editor add-on to edit the &lt;code&gt;configuration.yaml&lt;/code&gt; file of your Home Assistant instance. Add the following entry to the file.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt;mqtt&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt;  switch&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#5C6166;--shiki-dark:#BFBDB6&quot;&gt;    - &lt;/span&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;Desk Switch&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt;      unique_id&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; desk_switch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt;      command_topic&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;desk&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt;      payload_on&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;up&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#55B4D4;--shiki-dark:#39BAE6&quot;&gt;      payload_off&lt;/span&gt;&lt;span style=&quot;color:#5C6166B3;--shiki-dark:#BFBDB6B3&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; &quot;down&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After restarting Home Assistant, this will add a new switch device that sends &lt;code&gt;up&lt;/code&gt; and &lt;code&gt;down&lt;/code&gt; payloads to the &lt;code&gt;desk&lt;/code&gt; MQTT topic.&lt;/p&gt;
&lt;h2 id=&quot;optional-raycast-integration&quot;&gt;&lt;a href=&quot;#optional-raycast-integration&quot;&gt;Optional Raycast Integration&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The repository includes &lt;a href=&quot;https://github.com/marcjulianschwarz/ha-desk-automation/blob/main/raycast-scripts&quot;&gt;two python files&lt;/a&gt; that you can include in a &lt;a href=&quot;https://github.com/raycast/script-commands&quot;&gt;script commands directory&lt;/a&gt; for &lt;a href=&quot;https://www.raycast.com/&quot;&gt;Raycast&lt;/a&gt;. They will add the commands &lt;code&gt;⬆️ Raise Desk&lt;/code&gt; and &lt;code&gt;⬇️ Lower Desk&lt;/code&gt;.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/raycast.jpg&quot; alt=&quot;Screenshot of Raycast Script Commands in Raycast Search&quot;&gt;&lt;figcaption&gt;Screenshot of Raycast Script Commands in Raycast Search&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h3 id=&quot;install&quot;&gt;&lt;a href=&quot;#install&quot;&gt;Install&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To use the scripts, install the MQTT python client.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes ayu-light ayu-dark&quot; style=&quot;background-color:#f8f9fa;--shiki-dark-bg:#0d1017;color:#5c6166;--shiki-dark:#bfbdb6; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#22A4E6;--shiki-dark:#59C2FF&quot;&gt;pip&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#86B300;--shiki-dark:#AAD94C&quot;&gt; paho-mqtt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then change the shebang line to point to the Python environment where you installed the client, set the MQTT broker hostname, user, password, and add both Python scripts to your script commands directory. You should now be able to raise and lower your desk from Raycast 🎉.&lt;/p&gt;</content:encoded></item><item><title>Obsidian Raycast Extension - Update 1.4 and 1.5</title><link>https://marc-julian.com/blog/posts/obsraycastupdate2/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/obsraycastupdate2/</guid><description>Check out the new look of the Search Note command</description><pubDate>Thu, 05 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Since my last post, I released version 1.4 and 1.5 for the &lt;a href=&quot;https://www.raycast.com/marcjulian/obsidian&quot;&gt;Obsidian Raycast Extension&lt;/a&gt;. These are the new features:&lt;/p&gt;
&lt;h2 id=&quot;daily-note-command&quot;&gt;&lt;a href=&quot;#daily-note-command&quot;&gt;Daily Note command&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The new &lt;em&gt;Daily Note&lt;/em&gt; command allows users to open or create a daily note. Select a vault, press enter and start typing. It requires the Advanced URI plugin for Obsidian.&lt;/p&gt;
&lt;h2 id=&quot;pinned-notes-command&quot;&gt;&lt;a href=&quot;#pinned-notes-command&quot;&gt;Pinned Notes command&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use the &lt;em&gt;Pinned Notes&lt;/em&gt; command to show a list of your pinned notes. You can use the same actions as with the &lt;em&gt;Search Note&lt;/em&gt; command. This makes it easy to open, edit or view an important note.&lt;/p&gt;
&lt;h2 id=&quot;new-actions-and-new-look-for-search-note-command&quot;&gt;&lt;a href=&quot;#new-actions-and-new-look-for-search-note-command&quot;&gt;New actions and new look for Search Note command&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;actions&quot;&gt;&lt;a href=&quot;#actions&quot;&gt;Actions&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;With the &lt;em&gt;Append Selected Text to Note&lt;/em&gt; action you are now able to append selected text to a note. Use the keyboard shortcut &lt;code&gt;opt + s&lt;/code&gt; to trigger it.&lt;/p&gt;
&lt;p&gt;You can now pin and unpin notes using the &lt;em&gt;Pin Note&lt;/em&gt; and &lt;em&gt;Unpin Note&lt;/em&gt; actions. Pinned notes will appear in the &lt;em&gt;Pinned Notes&lt;/em&gt; command.&lt;/p&gt;
&lt;h3 id=&quot;new-look&quot;&gt;&lt;a href=&quot;#new-look&quot;&gt;New Look&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Enabeling &lt;em&gt;Detail View&lt;/em&gt; in preferences will show the content of a note on the right side.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/search_note.jpg&quot; alt=&quot;Search Note&quot;&gt;&lt;figcaption&gt;Search Note&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;new-preferences&quot;&gt;&lt;a href=&quot;#new-preferences&quot;&gt;New Preferences&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;append-prefix&quot;&gt;&lt;a href=&quot;#append-prefix&quot;&gt;Append Prefix&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Append Prefix&lt;/em&gt; is a new preference that appends a given prefix to text. This makes it  easy to maintain bullet or checkbox lists.&lt;/p&gt;
&lt;h3 id=&quot;open-note-on-creation&quot;&gt;&lt;a href=&quot;#open-note-on-creation&quot;&gt;Open Note on Creation&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If turned on this setting will open a note created with the &lt;em&gt;Create Note&lt;/em&gt; command after creation.&lt;/p&gt;
&lt;h3 id=&quot;hide-latex&quot;&gt;&lt;a href=&quot;#hide-latex&quot;&gt;Hide LaTeX&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You can now hide LaTeX from Quick Look, Detail View and all copy/paste commands.&lt;/p&gt;
&lt;h3 id=&quot;default-note-name&quot;&gt;&lt;a href=&quot;#default-note-name&quot;&gt;Default Note Name&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If the note name in the &lt;em&gt;Create Note&lt;/em&gt; command is empty, this default note name replaces it.&lt;/p&gt;
&lt;h3 id=&quot;folder-actions&quot;&gt;&lt;a href=&quot;#folder-actions&quot;&gt;Folder Actions&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You can now provide a list of folders (paths) to the &lt;em&gt;Create Note&lt;/em&gt; command. These folders will automatically create keyboard shortcuts (actions) to create notes in a specific folder. This is helpful if you are using &lt;a href=&quot;https://silentvoid13.github.io/Templater/introduction.html&quot;&gt;Obsidians Templater Plugin&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;store-page-update&quot;&gt;&lt;a href=&quot;#store-page-update&quot;&gt;Store page update&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The store page got a new look with images, category and version history.&lt;/p&gt;
&lt;div class=&quot;rehype-figure-container&quot;&gt;&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/store_images.jpg&quot; alt=&quot;Store Images&quot;&gt;&lt;figcaption&gt;Store Images&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/store_changelog.jpg&quot; alt=&quot;Store Changelog&quot;&gt;&lt;figcaption&gt;Store Changelog&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;h2 id=&quot;other&quot;&gt;&lt;a href=&quot;#other&quot;&gt;Other&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Commands with a single vault will now trigger without prior vault selection.&lt;/p&gt;
&lt;h2 id=&quot;feature-requests&quot;&gt;&lt;a href=&quot;#feature-requests&quot;&gt;Feature Requests&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you know of a feature that’s still missing or want to contribute otherwise, make sure to visit the projects &lt;a href=&quot;https://github.com/marcjulianschwarz/obsidian-raycast&quot;&gt;GitHub repo&lt;/a&gt;. With these two updates I restructured the entire codebase which should make it a lot easier to contribute.&lt;/p&gt;</content:encoded></item><item><title>Obsidian Raycast Extension - Update</title><link>https://marc-julian.com/blog/posts/obsraycastupdate/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/obsraycastupdate/</guid><description>Notes, notes, notes ...</description><pubDate>Sun, 06 Mar 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;My Raycast extension “Obsidian” has been in the &lt;a href=&quot;https://www.raycast.com/marcjulian/obsidian&quot;&gt;Raycast Store&lt;/a&gt; for some months now and lots of people are already using it. In this post I would like to introduce some of the new features that I added.&lt;/p&gt;
&lt;h2 id=&quot;create-note&quot;&gt;&lt;a href=&quot;#create-note&quot;&gt;Create Note&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With the new command &lt;em&gt;Create Note&lt;/em&gt; you can now create new notes on the fly. Like the other commands you can access it system-wide which makes it a great tool for jotting down some notes while working in another application.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/create_note.jpg&quot; alt=&quot;Create Note Command&quot;&gt;&lt;figcaption&gt;Create Note Command&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;The form accepts a name, local path (the command will automatically create a folder structure when the path doesn’t exist), a customizable tag picker and a big content field.&lt;/p&gt;
&lt;h3 id=&quot;customize-the-tag-picker&quot;&gt;&lt;a href=&quot;#customize-the-tag-picker&quot;&gt;Customize the tag picker&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Use the Racast Search to find the extensions preferences by searching for &lt;em&gt;Extensions&lt;/em&gt;. Scroll down to &lt;em&gt;Obsidian&lt;/em&gt; and select the &lt;em&gt;Create Note&lt;/em&gt; command. You will see a list of settings pop up on the right side. In the tags section you can enter a comma separated list of tags. For example: “daily, blog, project, todo, read”.&lt;/p&gt;
&lt;h3 id=&quot;other-settings&quot;&gt;&lt;a href=&quot;#other-settings&quot;&gt;Other settings&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Entering a default path and tag will auto-fill the corresponding fields when running the command. This might be helpful when you always want to add notes to a certain folder or always tag them with the same tag.&lt;/p&gt;
&lt;h2 id=&quot;new-keyboard-shortcuts-for-search-note&quot;&gt;&lt;a href=&quot;#new-keyboard-shortcuts-for-search-note&quot;&gt;New keyboard shortcuts for Search Note&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The new update comes with two new keyboard shortcuts for the &lt;em&gt;Search Note&lt;/em&gt; command. You can now use &lt;code&gt;opt + l&lt;/code&gt; to copy a markdown link for the note to your clipboard or &lt;code&gt;opt + u&lt;/code&gt; to copy the notes &lt;a href=&quot;https://help.obsidian.md/Advanced+topics/Using+obsidian+URI&quot;&gt;Obsidian URI&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;feature-requests&quot;&gt;&lt;a href=&quot;#feature-requests&quot;&gt;Feature Requests&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you know of a feature that’s still missing or want to contribute otherwise, make sure to visit the projects &lt;a href=&quot;https://github.com/marcjulianschwarz/obsidian-raycast&quot;&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>Obsidian Raycast Extension</title><link>https://marc-julian.com/blog/posts/obsraycast/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/obsraycast/</guid><description>Second Brain at your fingertips</description><pubDate>Thu, 06 Jan 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.raycast.com&quot;&gt;Raycast&lt;/a&gt; is a free to use productivity tool. It’s basically a replacement for the default macOS Spotlight Search and offers similar functionalities like searching for files and applications.&lt;/p&gt;
&lt;p&gt;Or to put it in Raycasts words:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Raycast is a blazingly fast, totally extendable launcher. It lets you complete tasks, calculate, share common links, and much more.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The biggest difference is that it’s extendable through extensions which you can install in Raycast’s own store. There you will find everything from a YouTube Launcher, Visual Studio Code Search, GitHub actions, home control and so much more. The store is growing everyday and developers create new useful extensions.&lt;/p&gt;
&lt;p&gt;As I enjoy the concept of a search/launcher to be the main hub on my Mac and because I am a big fan and extensive user of the note taking app &lt;a href=&quot;https://obsidian.md&quot;&gt;Obsidian&lt;/a&gt;, I decided to create my own &lt;a href=&quot;https://www.raycast.com/marcjulian/obsidian&quot;&gt;raycast extension for Obsidian.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Right now it consists of the following two commands but I work on new features while you are reading this sentence.&lt;/p&gt;
&lt;h2 id=&quot;search-note&quot;&gt;&lt;a href=&quot;#search-note&quot;&gt;Search Note&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With the command &lt;em&gt;Search Note&lt;/em&gt; you can search for every note in your vault.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/search_note_06_01_2022.jpg&quot; alt=&quot;Search Note Command&quot;&gt;&lt;figcaption&gt;Search Note Command&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Actions are available when you select a note. You can view the note using &lt;em&gt;Quick Look&lt;/em&gt; to get a glance at the content or use &lt;em&gt;Open in Obsidian&lt;/em&gt; to directly open it in Obsidian itself. With &lt;em&gt;Append to note&lt;/em&gt; you can add text to the note, this is useful to add entries to lists or tables. The &lt;em&gt;Copy note content&lt;/em&gt; is self-explanatory and &lt;em&gt;Paste note content&lt;/em&gt; will paste the text into the last used application.&lt;/p&gt;
&lt;h3 id=&quot;preferences&quot;&gt;&lt;a href=&quot;#preferences&quot;&gt;Preferences&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In the commands settings you are able to exclude folders from the search. This is useful if you have lots of reference notes or some sort of “database” which you don’t want to search through.
For Quick Look, copy and paste actions it could be a good idea to hide the YAML frontmatter and wiki-links as other applications might not need them. Which is why a setting for hiding this content is available too. Lastly, you can configure the primary action (enter key) to trigger &lt;em&gt;Quick Look&lt;/em&gt; or &lt;em&gt;Open in Obsidian&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&quot;open-vault&quot;&gt;&lt;a href=&quot;#open-vault&quot;&gt;Open Vault&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With the command &lt;em&gt;Open Vault&lt;/em&gt; you can open one of your vaults which you can specify in the preferences. This allows for quick switching between different vaults and removes the rather annoying way of using Obsidian’s vault switcher.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/open_vault.jpg&quot; alt=&quot;Open Vault Command&quot;&gt;&lt;figcaption&gt;Open Vault Command&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;contribute&quot;&gt;&lt;a href=&quot;#contribute&quot;&gt;Contribute&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you want to contribute to this extension you can visit the &lt;a href=&quot;https://github.com/marcjulianschwarz/obsidian-raycast&quot;&gt;GitHub repository&lt;/a&gt; and open a new issue.  I am open to work on feature requests and would welcome it if you report any bugs or wrong behavior.&lt;/p&gt;</content:encoded></item><item><title>My Obsidian Knowledge Graph</title><link>https://marc-julian.com/blog/posts/my-obsidian-knowledge-graph/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/my-obsidian-knowledge-graph/</guid><pubDate>Thu, 05 Aug 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;graph-view&quot;&gt;&lt;a href=&quot;#graph-view&quot;&gt;Graph View&lt;/a&gt;&lt;/h2&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/graph_full.jpg&quot; alt=&quot;Whole Graph&quot;&gt;&lt;figcaption&gt;Whole Graph&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;This is the knowledge graph of my second brain, markdown notes written in &lt;a href=&quot;https://obsidian.md/&quot;&gt;Obsidian&lt;/a&gt;. It stores ideas, thoughts, and knowledge.&lt;/p&gt;
&lt;p&gt;The colors represent individual groups, defined via folders, tags, or keywords. In my case, the colors represent overarching topics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Green → University Notes&lt;/li&gt;
&lt;li&gt;Blue → Bible Study Notes&lt;/li&gt;
&lt;li&gt;Red → Other (Inbox, Projects, Blog, Private)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Zooming in reveals the more complex graph structure with its links between notes of different topics. The note names become readable, and you can see distinct links.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/graph2.jpg&quot; alt=&quot;Zoomed in Graph&quot;&gt;&lt;figcaption&gt;Zoomed in Graph&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/graph4.jpg&quot; alt=&quot;Zoomed in Graph&quot;&gt;&lt;figcaption&gt;Zoomed in Graph&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;local-graph&quot;&gt;&lt;a href=&quot;#local-graph&quot;&gt;Local Graph&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The local graph allows you to see specific parts of the graph that relate to one note. For example, the following image shows a local graph with a depth of 2, which means that notes with a distance of up to 2 edges are part of it. This can be helpful for navigating between notes on the same topic.&lt;/p&gt;
&lt;figure class=&quot;rehype-figure&quot;&gt;&lt;img src=&quot;/images/local_graph.jpg&quot; alt=&quot;Local Graph of Note&quot;&gt;&lt;figcaption&gt;Local Graph of Note&lt;/figcaption&gt;&lt;/figure&gt;</content:encoded></item><item><title>What I like and don&apos;t like about iOS 15</title><link>https://marc-julian.com/blog/posts/ios15/</link><guid isPermaLink="true">https://marc-julian.com/blog/posts/ios15/</guid><description>A personal view on the new features</description><pubDate>Mon, 21 Jun 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As of today I have tested the first iOS 15 Beta for at least two weeks. And, I am happy with the new features added. But some of them stood out to me:&lt;/p&gt;
&lt;h2 id=&quot;safari&quot;&gt;&lt;a href=&quot;#safari&quot;&gt;Safari&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Apple markets it to be &lt;em&gt;reimagined for the way we browse today.&lt;/em&gt; The tab and search bar dropped from the top of the screen right to the bottom where it’s easier to reach with one hand. Swiping across the bar will switch between all opened tabs. At first I wasn’t a fan of the new UI, it took some time to get used to the new gestures. But to be fair, Safari got lots of other great new functionalities. A customizable start page, privacy protections with &lt;em&gt;iCloud+ Private Relay&lt;/em&gt; (although I wasn’t able to use it in the beta version yet), the ability to add web extensions and a grid-like tab overview.&lt;/p&gt;
&lt;h2 id=&quot;notifications&quot;&gt;&lt;a href=&quot;#notifications&quot;&gt;Notifications&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Apple made long requested changes to the notification system. Notifications are now ranked by priority to make sure that the most urgent ones are always at the top. iOS now delivers a helpful notification summary every day so you can see what’s new at a glance.&lt;/p&gt;
&lt;h2 id=&quot;focus&quot;&gt;&lt;a href=&quot;#focus&quot;&gt;Focus&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Strongly connected to notifications is the all new &lt;em&gt;Focus&lt;/em&gt; mode. It’s basically an extension to the  &lt;em&gt;“Do not disturb mode”&lt;/em&gt; which silences all incoming notifications. Focus can automatically filter notifications to your liking. But thats not all. You can even specify which homescreens iOS will show during an activated Focus mode.&lt;/p&gt;
&lt;h2 id=&quot;spotlight-search--live-text&quot;&gt;&lt;a href=&quot;#spotlight-search--live-text&quot;&gt;Spotlight Search + Live Text&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The already beloved spotlight search got a complete revamp. It’s now faster, more detailed and the new live text feature adds so much more functionality to it. You can now search for text which appears in your images. For people who take lots of screenshots, this can be a big time-saver.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a href=&quot;#conclusion&quot;&gt;Conclusion:&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I can see the problems people might have with the updated Safari UI but I do think that they will get used to it and in the end appreciate having the ability to use Safari one-handedly.&lt;/p&gt;
&lt;p&gt;For me personally, the best feature in iOS 15 is the Focus mode. I already set up a &lt;em&gt;Learning mode&lt;/em&gt; which automatically changes my homescreen to display relevant apps and widgets (e.g. Notability, Calendar, Reminders, Files, and other university related apps). Also any messages which weren’t sent by my fellow students or professors don’t show up. It helps me get less distracted when learning or working.&lt;/p&gt;
&lt;p&gt;As I said in the beginning, iOS 15 gave us lots of small upgrades which will enhance the experience with your Apple devices. Nothing big, but great nonetheless.&lt;/p&gt;</content:encoded></item></channel></rss>