<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ross-Li</title>
    <description>The latest articles on Forem by Ross-Li (@rossli).</description>
    <link>https://forem.com/rossli</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F870506%2F093be7cd-61d3-4dda-a89a-16c5d059c2da.jpeg</url>
      <title>Forem: Ross-Li</title>
      <link>https://forem.com/rossli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rossli"/>
    <language>en</language>
    <item>
      <title>Debug Diary: Vscode Extension Development Host Can't Fully Simulate Actual Vscode</title>
      <dc:creator>Ross-Li</dc:creator>
      <pubDate>Sat, 22 Jun 2024 01:00:03 +0000</pubDate>
      <link>https://forem.com/rossli/debug-diary-vscode-extension-development-host-cant-fully-simulate-actual-vscode-1gd3</link>
      <guid>https://forem.com/rossli/debug-diary-vscode-extension-development-host-cant-fully-simulate-actual-vscode-1gd3</guid>
      <description>&lt;p&gt;Encountered a problem while developing upon one of my favorite vscode extensions: &lt;a href="https://github.com/aaron-bond/better-comments"&gt;better comments&lt;/a&gt; by &lt;a href="https://github.com/aaron-bond"&gt;Aaron Bond&lt;/a&gt;. I have figured it out, learned much new stuff, considering researching it (specifically vscode's Extension Development Host) a bit more, raise an issue to vscode and most importantly, share it with you guys so that you may prevent encountering issues like me.&lt;/p&gt;

&lt;h2&gt;
  
  
  💀 Problem
&lt;/h2&gt;

&lt;p&gt;The extension works in vscode, but when I cloned the source code and test ran it in vscode's Extension Development Host, it fails to function properly (only some programming languages are properly highlighted).&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍 Cause (TLDR)
&lt;/h2&gt;

&lt;p&gt;vscode's Extension Development Host fails to simulate an actual vscode instance, resulting the extension not able to detect installed language support extensions, resulting the extension not functioning properly in Extension Development Host, but does function properly in ordinary vscode instances.&lt;/p&gt;

&lt;h2&gt;
  
  
  🪲 Debugging Process
&lt;/h2&gt;

&lt;p&gt;After briefly reading the source code, I found that this extension basically scans all extensions installed in user's vscode, pick extensions with language support, and store those language configurations, combined with user's customized comment configurations, finally decorate comments in the editor.&lt;/p&gt;

&lt;p&gt;Inside Extension Development Host (EDH), through debugging with breakpoints, I found that some of extensions's variables (specifically &lt;code&gt;commentConfig&lt;/code&gt; and &lt;code&gt;languageConfigFiles&lt;/code&gt; in the &lt;code&gt;configuration.ts&lt;/code&gt;) which should hold language configurations only contain a part of extensions by the time of decorating comments.&lt;/p&gt;




&lt;h3&gt;
  
  
  ⌛ &lt;em&gt;Interlude: I Was Wrong with "Watch" in vscode Debugging Variable Expressions...&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;While I tried to use the "watch" functionality in vscode debugging, for some time I really thought these 2 variables were not properly initialized into empty &lt;code&gt;Map&lt;/code&gt; objects, because the "watch" panel shows &lt;code&gt;Uncaught ReferenceError&lt;/code&gt; for these 2 variables after executing the initialization statements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;commentConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CommentConfig&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;languageConfigFiles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Turns out, my "watch" expressions were wrong. I should have used &lt;code&gt;this.commentConfig&lt;/code&gt; and &lt;code&gt;this.languageConfigFiles&lt;/code&gt; instead of &lt;code&gt;commentConfig&lt;/code&gt; and &lt;code&gt;languageConfigFiles&lt;/code&gt; in the "watch" panel. Seems that vscode's "watch" functionality have its own way of figuring out variable scopes, but I haven't really found the documentation for it. I would really appreciate it if you could point it out to me in the comment section.&lt;/p&gt;




&lt;h3&gt;
  
  
  Test the "better comments" Extension by Packaging the Source Code and Installing It to vscode
&lt;/h3&gt;

&lt;p&gt;If the problems lies in the EDH, then I should try to test the extension in an actual vscode instance. After packaging the source code into a &lt;code&gt;.vsix&lt;/code&gt; file, and installing it to vscode (also disabling the extension originally installed from extension marketplace), all languages are decorated properly, which means the extension powered by the source code functions properly!!! 😆&lt;/p&gt;




&lt;h3&gt;
  
  
  Making a Little Extension to Confirm My Suspicions
&lt;/h3&gt;

&lt;p&gt;I want to know the reason why the better comments extensions works well in an actual extension. Specifically, I want to know whether the &lt;code&gt;vscode.extensions.all&lt;/code&gt; variables could actually pick up all extensions in an actual vscode instance.&lt;/p&gt;

&lt;p&gt;But vscode doesn't allow me to &lt;strong&gt;directly&lt;/strong&gt; inspect the &lt;code&gt;vscode.extension.all&lt;/code&gt; variable in a vscode instance:&lt;/p&gt;

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

&lt;p&gt;With the help of Copilot, I created a little extension called &lt;code&gt;inspect-all-extensions&lt;/code&gt; to inspect the &lt;code&gt;vscode.extensions.all&lt;/code&gt; variable of a vscode instance. The &lt;code&gt;activate()&lt;/code&gt; functin of &lt;code&gt;extension.ts&lt;/code&gt; looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;activate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;vscode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ExtensionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Extension "inspect-all-extensions" is now active!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;disposable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;vscode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;commands&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inspect-all-extensions.inspect&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Variables for formatted printing&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;publisherWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nameWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;versionWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="c1"&gt;// Create and show an output channel&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;outputChannel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;vscode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createOutputChannel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AllExtensions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;outputChannel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="c1"&gt;// Get all extensions&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;extensions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;vscode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;extensionsInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;extensions&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
            &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;packageJSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publisher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="nx"&gt;publisherWidth&lt;/span&gt;
            &lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;\t&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;packageJSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="nx"&gt;nameWidth&lt;/span&gt;
            &lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;\t&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;packageJSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;padEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;versionWidth&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="c1"&gt;// Print all extensions in the output channel and console&lt;/span&gt;
      &lt;span class="nx"&gt;outputChannel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;extensionsInfo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;outputChannel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Extensions count: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;extensionsInfo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Extensions count:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscriptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;disposable&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After packing, installing this helper extension and running its command, here is the output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vscode                  configuration-editing           1.0.0
vscode                  css-language-features           1.0.0
vscode                  debug-auto-launch               1.0.0
vscode                  debug-server-ready              1.0.0
vscode                  emmet                           1.0.0
vscode                  extension-editing               1.0.0
vscode                  git                             1.0.0
vscode                  git-base                        1.0.0
vscode                  github                          0.0.1
vscode                  grunt                           1.0.0
vscode                  gulp                            1.0.0
vscode                  html-language-features          1.0.0
vscode                  ipynb                           1.0.0
vscode                  jake                            1.0.0
vscode                  json-language-features          1.0.0
vscode                  markdown-language-features      1.0.0
vscode                  markdown-math                   1.0.0
vscode                  merge-conflict                  1.0.0
ms-vscode               js-debug                        1.90.0
ms-vscode               vscode-js-profile-table         1.0.9
vscode                  npm                             1.0.1
vscode                  php-language-features           1.0.0
vscode                  references-view                 1.0.0
vscode                  search-result                   1.0.0
vscode                  tunnel-forwarding               1.0.0
vscode                  typescript-language-features    1.0.0
42Crunch                vscode-openapi                  4.26.3
bierner                 github-markdown-preview         0.3.0
bierner                 markdown-checkbox               0.4.0
bierner                 markdown-emoji                  0.3.0
bierner                 markdown-footnotes              0.1.1
bierner                 markdown-mermaid                1.23.1
bierner                 markdown-preview-github-styles  2.0.4
bierner                 markdown-yaml-preamble          0.1.0
dbaeumer                vscode-eslint                   3.0.10
eamodio                 gitlens                         15.1.0
esbenp                  prettier-vscode                 10.4.0
GitHub                  copilot                         1.206.0
GitHub                  copilot-chat                    0.16.1
golang                  go                              0.41.4
golang                  go-nightly                      2024.5.3021
mhutchie                git-graph                       1.30.0
ms-python               debugpy                         2024.6.0
ms-python               python                          2024.8.1
ms-python               vscode-pylance                  2024.6.1
ms-vscode               extension-test-runner           0.0.9
ms-vscode               live-server                     0.4.13
oderwat                 indent-rainbow                  8.3.1
redhat                  java                            1.31.0
redhat                  vscode-yaml                     1.15.0
undefined_publisher     inspect-all-extensions          0.0.1
VisualStudioExptTeam    intellicode-api-usage-examples  0.2.8
VisualStudioExptTeam    vscodeintellicode               1.3.1
vscjava                 vscode-java-debug               0.57.0
vscjava                 vscode-java-dependency          0.23.6
vscjava                 vscode-java-pack                0.27.0
vscjava                 vscode-java-test                0.41.1
vscjava                 vscode-maven                    0.44.0
Vue                     volar                           2.0.21
waderyan                gitblame                        11.0.1
Extensions count: 60
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it shows all extensions properly, including vscode built-in extensions that are not overriden by third party extensions and third party extensions.&lt;/p&gt;

&lt;h2&gt;
  
  
  😭 What I Could Had Done Better &amp;amp; 🚀 Future Improvements
&lt;/h2&gt;

&lt;p&gt;Somehow I am not able to reproduce the problem of "only partial extensions detected in EDH". This is a &lt;strong&gt;VERY VERY BIG&lt;/strong&gt; mistake because now I can't reproduce the problem anymore, which means I couldn't raise an issue or question about this online anymore and everybody would think that I was hallucinating 😭. Next time I would document the outputs (screenshots may better) somewhere else. Maybe I have just overturned the conclusion of this entire blog...&lt;/p&gt;

&lt;p&gt;Since now the &lt;code&gt;vscode.extensions.all&lt;/code&gt; variable seems to be working properly in EDH (showing 61 extensions), the real problem may lie somewhere else, such as the &lt;code&gt;UpdateLanguagesDefinitions()&lt;/code&gt; function, where its result &lt;code&gt;languageConfigFiles&lt;/code&gt; only picked up 15 of the extensions...&lt;/p&gt;

</description>
      <category>vscode</category>
    </item>
    <item>
      <title>Mobilizing Others: Some Reflections</title>
      <dc:creator>Ross-Li</dc:creator>
      <pubDate>Sun, 02 Jun 2024 04:02:35 +0000</pubDate>
      <link>https://forem.com/rossli/mobilizing-others-some-reflections-eic</link>
      <guid>https://forem.com/rossli/mobilizing-others-some-reflections-eic</guid>
      <description>&lt;p&gt;I just realized that I am not good at managing. Here are some reflections:&lt;/p&gt;

&lt;p&gt;I expected teammates to work at a certain standard and in a certain way that I hadn't specify or encourage. I feel a lack of vocabulary and awareness of praising others or saying positive things in general. &lt;/p&gt;

&lt;p&gt;Although I was the team leader, I didn't feel like leading because I associate leadership with manipulation and coercion, which obviously I don't like therefore I don't want to project these influences towards my teammates.&lt;/p&gt;

&lt;p&gt;I don't feel like repeating things (sticking to a certain format when writing the API document) because I thought words of team leader should be executed if no objection was raised. But that is not true.&lt;/p&gt;

&lt;p&gt;I wanted to be a software developer partially because of the possibility of creating something great just by myself learning and developing. But that is not true for software developers. SDEs work with other SDEs with different skill levels and technical background, and staff from other departments such as design and product management with less tech-literacy. I can develop by myself and make cool stuff, but that is only for side-projects. For the "day job" (so to speak), working with others is a absolute necessity.&lt;/p&gt;

&lt;p&gt;When I watch short videos (which I shouldn't) on platforms such as YouTube, one of the video types I watch is powerful figures commanding the team and getting things done. I guess it's me wanting to do the same thing but lacking the courage to do it.&lt;/p&gt;

&lt;p&gt;So today is my first day of correcting these mistakes. I asked one of my roommates whether he was using my tools because I noticed the tools was misplaced. I have been putting this conversation off for a few days. My roommate said no and he didn't blame me at all for bringing up this issue. I felt a bit reassured. It's could be the most trivial thing to mention in a blog like this, but I want to start to do something to correct my habits no matter how small it is.&lt;/p&gt;

</description>
      <category>management</category>
    </item>
    <item>
      <title>Cloud Newbie Fixing Newbie Problems: Snap</title>
      <dc:creator>Ross-Li</dc:creator>
      <pubDate>Sat, 18 May 2024 20:18:45 +0000</pubDate>
      <link>https://forem.com/rossli/cloud-newbie-fixing-newbie-problems-snap-4b63</link>
      <guid>https://forem.com/rossli/cloud-newbie-fixing-newbie-problems-snap-4b63</guid>
      <description>&lt;p&gt;Initial problem: can't connect to a Google Cloud VM instance created through vscode.&lt;/p&gt;

&lt;p&gt;Try to get SSH connection to the instance through Google Cloud Console:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8v78muc617cyn62i7a85.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8v78muc617cyn62i7a85.png" alt="Image description" width="763" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Checked firewall rules. There already exists a predefined rule that applies to all instances allowing port 22 for SSH communication.&lt;/p&gt;

&lt;p&gt;Enable the serial console, get into the serial console:&lt;br&gt;
The serial console only outputs information and I can't input any command. The outputted information suggests some sort of &lt;code&gt;snapd&lt;/code&gt; problem.&lt;/p&gt;

&lt;p&gt;Taking a look at CPU usage:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc67nbwr6snp3wlmmwfkh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc67nbwr6snp3wlmmwfkh.png" alt="Image description" width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I continued to work until around 01:00 AM this morning, then I disconnected from the SSH in vscode. But somehow the CPU kept running. Let's check the log around that time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;May 18 00:49:29 appstore snapd[532]: storehelpers.go:923: cannot refresh: snap has no updates available: "code", "core20", "google-cloud-cli", "lxd", "snapd"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well I forgot the technique of "just fxxking restart it". My concern is that if I stopped and restarted the VM instance, its external IP would be changed (it happened last time), causing a lot of config issues for testing. So I searched for methods to keep the IP not changed during restart. After a little bit of researching I promoted the ephemeral IP to static IP (well for more charges I guess). Now I can restart the instance without worries.&lt;/p&gt;

&lt;p&gt;After restarting the instance, everything worked. I was curious what does Snap do other than being a newer fancier package manager than &lt;code&gt;apt&lt;/code&gt; (e.g. what do these &lt;code&gt;/dev/loop&lt;/code&gt; directories have to deal with my installed applications?), and a brief search online shows me a decent amount of other users ranting about this issue. So I guess the problem could be that my VM instance isn't powerful enough to handle the Snap automatic update (Copilot told me I can't completely turn off the automatic update, WTF?), or some restrictions of my VM instance (e.g. size or number of loopback devices) was reached during the Snap automatic update of some applications that I (vscode specifically, following the instruction of Bash output) or the system installed (google-cloud-cli). I am considering removing Snap altogether but I can't just do it because something important (i.e. google-cloud-cli) was installed by the system default via Snap.&lt;/p&gt;

&lt;p&gt;Well Snap (and the version of Ubuntu that started to use Snap), you just got yourself another unsatisfied customer!&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>cloudskills</category>
    </item>
    <item>
      <title>Opinion: CS Education Should Include More Code Reading</title>
      <dc:creator>Ross-Li</dc:creator>
      <pubDate>Fri, 12 Apr 2024 05:31:18 +0000</pubDate>
      <link>https://forem.com/rossli/opinion-cs-education-should-include-more-code-reading-76l</link>
      <guid>https://forem.com/rossli/opinion-cs-education-should-include-more-code-reading-76l</guid>
      <description>&lt;p&gt;I was reading through the code for an amazing open source project called &lt;a href="https://github.com/BFBAN/bfban-website"&gt;BFBAN&lt;/a&gt; today. Specifically, I was reading the SQL scripts. There I encountered many familiar SQL stuff, but also many SQL stuff that I didn't know: &lt;code&gt;json&lt;/code&gt; data type, &lt;code&gt;ENGINE=InnoDB&lt;/code&gt;, &lt;code&gt;COLLATE=utf8mb4_0900_ai_ci&lt;/code&gt;, &lt;code&gt;COMMENT&lt;/code&gt;, &lt;code&gt;PRIMARY KEY (&lt;/code&gt;id&lt;code&gt;) USING BTREE&lt;/code&gt;...... As I understood these concepts with the help of Copilot and documentation, I developed a better understanding of MySQL and starting thinking this blog's topic.&lt;/p&gt;

&lt;p&gt;My (could be arbitrary) point is: I don't think in today's CS education (in some universities at least), students are reading (or instructors are not assisting students to read) enough good quality code for students to produce good quality code. &lt;/p&gt;

&lt;p&gt;If you want to write good articles or essays, you should first read and "digest" quite a few classical books or essays (e.g. Plato's work, Shakespeare's work) to understand word-by-word, sentence-by-sentence, paragraph-to-paragraph how good essays should be written usually with the help from teachers to build up the "vocabularies".  &lt;/p&gt;

&lt;p&gt;Then how comes when it comes to CS education (especially the software engineering part), students are expected to know how to program properly after only a few semesters' equivalent of "learning the ABCs" without much exposure and understanding of good quality code? &lt;/p&gt;

&lt;p&gt;Maybe the instructors could do some live coding sessions just like what software developers would do when they pair-program? Maybe the instructors could pick some entry-level but good quality open source code bases to let the students to write "summary and response" with? Maybe instead of asking "who knows answer to this question", instructors could ask a student to the front and present his/her idea to improve existing sample code? Those are just some random thoughts, but maybe we can draw experiences from how writing was taught (or should I say, "should be taught") in school.&lt;/p&gt;

&lt;p&gt;I remember listening to this video &lt;a href="https://www.youtube.com/watch?v=LtRWu9DErgU&amp;amp;list=PLLxJFnTawO9oMFpcWAfWh8o79Jhhf2AGj&amp;amp;index=6&amp;amp;t=3376s&amp;amp;pp=gAQBiAQB"&gt;Can Great Programmers Be Taught&lt;/a&gt; discussing the software engineer education. I remember that one of the argument the present made was that programming can be taught properly by reducing the class capacity, increasing in-class interaction, essentially "tailoring" the education to the audience, subsequently increasing the cost of education (or should I call it individual tutoring at this point) by a large amount. (Just think about how much you are paying for your CS education, then multiply that by a few times). &lt;/p&gt;

&lt;p&gt;I do agree that the greatest programmers are self-taught, because programming is a field that just isn't possible to be 100% taught, a field where the practitioner must be willing to "chew through the book like a worm" to build up their programming knowledge. But I still think that good introductory CS education will guide beginners towards the right direction and speed up their progress.&lt;/p&gt;

</description>
      <category>learning</category>
    </item>
    <item>
      <title>Database Education Needs Moderization</title>
      <dc:creator>Ross-Li</dc:creator>
      <pubDate>Fri, 12 Apr 2024 04:52:42 +0000</pubDate>
      <link>https://forem.com/rossli/database-education-needs-moderization-4p6l</link>
      <guid>https://forem.com/rossli/database-education-needs-moderization-4p6l</guid>
      <description>&lt;p&gt;I just bombed my database course exam today. I am not gonna blame anyone else. It's was because I didn't properly study how to join multiple tables.&lt;/p&gt;

&lt;p&gt;But it made me think during the exam: I really wish I could had the assistance to write SQL code from AI. It is certainly not allowed during exams, but I should had used it when I was learning it. Actually, it should be made available during the learning process. Combined with the fact that this class is taught using MAMP with MySQL version of 5.x.x while the textbook published in 2014 whose SQL examples are mostly of Oracle dialect......, I think the database education really needs some modernization. (Kinda a arbitrary opinion though, considering I haven't researched how other colleges / universities teach database courses.)&lt;/p&gt;

&lt;p&gt;Just raising the problem is not enough. I don't want to be just another complainer. I will think about some ways (also existing ways) to modernize database education in my free time. Specifically I want the teaching to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Be in line with latest popular SQL syntax &lt;/li&gt;
&lt;li&gt;Have user-friendly way to install tools with AI assistant equipped with knowledge of the database&lt;/li&gt;
&lt;li&gt;Maybe integrate sample projects and exercises from popular textbooks to "standardize" them all?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://github.com/vanna-ai/vanna"&gt;vanna-ai&lt;/a&gt; is a pretty cool project that combines AI with database knowledge. &lt;a href="https://www.sqlai.ai/about"&gt;SQLAI&lt;/a&gt; seems to be a small German company which specializes in this area. I will start exploring these in my free time.&lt;/p&gt;

</description>
      <category>database</category>
      <category>learning</category>
    </item>
    <item>
      <title>Don't "Trust" GitHub Code Just Because It's Got Lots Of Stars</title>
      <dc:creator>Ross-Li</dc:creator>
      <pubDate>Wed, 10 Apr 2024 23:13:00 +0000</pubDate>
      <link>https://forem.com/rossli/dont-trust-github-code-just-because-its-got-lots-of-stars-533b</link>
      <guid>https://forem.com/rossli/dont-trust-github-code-just-because-its-got-lots-of-stars-533b</guid>
      <description>&lt;p&gt;I was reviewing data structures and algorithms for interview prep. So I went on GitHub and find this organization &lt;a href="https://github.com/TheAlgorithms"&gt;TheAlgorithms&lt;/a&gt; and its repo collecting data structures and algorithms in many different languages. It was a treasure for sure, but I also find some code that looks really terrible to even a amateur like me: bad function naming, confusing class organization and some other heavy code smells. Although it was some good material for a foundation to modify with and it could be regarded as some OK refactoring practices, it was a bit annoying to refactor the code that was kinda supposed to be polished.&lt;/p&gt;

&lt;p&gt;The message of this story is that you should not take code from GitHub as good, finished, polished code, especially when the code is from (below are my hypothesis):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;"Hot" repos that got a lot of stars, not necessarily because it is widely used but because it is a "resource collection" and people just "wishlist" it by starring (e.g. the "awesome" series of repos).&lt;/li&gt;
&lt;li&gt;Non-production code base or code base for educational purposes&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>beginners</category>
      <category>learning</category>
      <category>github</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>Way to BETTER explain Python lambda in for loop.</title>
      <dc:creator>Ross-Li</dc:creator>
      <pubDate>Mon, 06 Nov 2023 04:35:23 +0000</pubDate>
      <link>https://forem.com/rossli/way-to-better-explain-python-lambda-in-for-loop-1mp8</link>
      <guid>https://forem.com/rossli/way-to-better-explain-python-lambda-in-for-loop-1mp8</guid>
      <description>&lt;p&gt;This &lt;a href="https://docs.python.org/3.11/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result"&gt;Python FAQ&lt;/a&gt;, addresses a problem new Python programmers always run into: lambda in list comprehension (in essence, in a &lt;code&gt;for&lt;/code&gt; loop). However, it is poorly explained.&lt;/p&gt;

&lt;p&gt;I tried to figure out a way to explain it by breaking down and refactoring the code just like what you would do in a math proof problem. Tell me whether this "proof" makes sense or whether "proof" makes better explanation.&lt;/p&gt;

&lt;p&gt;Credit: Thanks to YouTube channel &lt;code&gt;mCoding&lt;/code&gt; for showing the internals of Python list comprehensions!&lt;/p&gt;




&lt;p&gt;&lt;code&gt;increment_by_i = [lambda x: x + i for i in range(5)]&lt;/code&gt; is equalivent to:&lt;br&gt;&lt;br&gt;
&lt;code&gt;increment_by_i = list(lambda x: x + i for i in range(5))&lt;/code&gt;, where&lt;br&gt;&lt;br&gt;
&lt;code&gt;lambda(x: x + i for i in range(10))&lt;/code&gt; is a generator expression, which is equalivent to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_generator&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;         &lt;span class="c1"&gt;# Define a generator function
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="n"&gt;generator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lambda_generator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# Then call it
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By the property of &lt;code&gt;lambda&lt;/code&gt; in Python, this is eqivalent to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_generator&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;lambda_function&lt;/span&gt;
&lt;span class="n"&gt;generator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lambda_generator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you run this code with the &lt;code&gt;inspcect.getclosurevars&lt;/code&gt; function, you can already see from the printed output that during the definition of &lt;code&gt;lambda_generator()&lt;/code&gt;, the &lt;code&gt;i&lt;/code&gt; variable have already been iterated from 0 to 4. So &lt;code&gt;lambda_generator()&lt;/code&gt; function becomes a function that adds 4 to its inputs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;inspect&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;getclosurevars&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_generator&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;lambda_function&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getclosurevars&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lambda_function&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;generator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lambda_generator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Output:
# ClosureVars(nonlocals={'i': 0}, globals={}, builtins={}, unbound=set())
# ClosureVars(nonlocals={'i': 1}, globals={}, builtins={}, unbound=set())
# ClosureVars(nonlocals={'i': 2}, globals={}, builtins={}, unbound=set())
# ClosureVars(nonlocals={'i': 3}, globals={}, builtins={}, unbound=set())
# ClosureVars(nonlocals={'i': 4}, globals={}, builtins={}, unbound=set())
# 8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Lemma: A small example demonstrating the underlying mechanism of &lt;code&gt;for&lt;/code&gt; loops in Python)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="s"&gt;"""
for i in range(5):
    print(i)
is equivalent to
"""&lt;/span&gt;

&lt;span class="n"&gt;itr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;    &lt;span class="c1"&gt;# Apply `iter()` to range object to get iterator `itr`
&lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;itr&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;StopIteration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By the underlying mechanism of &lt;code&gt;for&lt;/code&gt; loops (create an iterator with &lt;code&gt;iter()&lt;/code&gt; function, then repeatedly apply &lt;code&gt;next()&lt;/code&gt; to the iterator until &lt;code&gt;StopIteration&lt;/code&gt;) in Python, &lt;code&gt;lambda_generator()&lt;/code&gt; is equalivent to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_generator&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;itr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;    &lt;span class="c1"&gt;# Apply `iter()` to range object to get iterator `itr`
&lt;/span&gt;    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;itr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;# `next(iter)` is the `i`
&lt;/span&gt;            &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lambda_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;   &lt;span class="c1"&gt;# Set `x` to be 0, so that the printed result = next(itr)
&lt;/span&gt;        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;StopIteration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;lambda_function&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;                       &lt;span class="c1"&gt;# This break may not be necessary though
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;In every &lt;code&gt;while&lt;/code&gt; loop (before &lt;code&gt;StopIteration&lt;/code&gt;), &lt;code&gt;next(itr)&lt;/code&gt; is called, modifying the &lt;code&gt;itr&lt;/code&gt; iterator outside the &lt;code&gt;while&lt;/code&gt; loop (inside the &lt;code&gt;lambda_generator()&lt;/code&gt; function). Therefore, it is OK to refactor the &lt;code&gt;itr&lt;/code&gt; iterator inside the &lt;code&gt;while&lt;/code&gt; loop:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_generator&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;itr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;itr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;StopIteration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;lambda_function&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can easily see that by the time &lt;code&gt;lambda_function()&lt;/code&gt; is yielded to &lt;code&gt;lambda_generator()&lt;/code&gt;, &lt;code&gt;lambda_function()&lt;/code&gt; have already become a function that adds 4 to its input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;itr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;itr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;StopIteration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lambda_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;   &lt;span class="c1"&gt;# Set x = 0, so that the printed result = the final next(iter) value
&lt;/span&gt;
&lt;span class="c1"&gt;# Output: 4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Self learning is so important...</title>
      <dc:creator>Ross-Li</dc:creator>
      <pubDate>Mon, 13 Jun 2022 10:02:15 +0000</pubDate>
      <link>https://forem.com/rossli/self-learning-is-so-important-4bdf</link>
      <guid>https://forem.com/rossli/self-learning-is-so-important-4bdf</guid>
      <description>&lt;p&gt;The lesson I learnt from watching Python tutorial videos on YouTube ,reading PEP documents and some full-semester computer courses is that in terms of computer science stuff, self learning is just much more effective and fun, especially if (1) your all that your instructor do in lectures is reading through PowerPoints and (2) not showing the mechanism with LIVE CODING or (3) just have a strong English accent.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>python</category>
    </item>
    <item>
      <title>First GitHub Pull Request</title>
      <dc:creator>Ross-Li</dc:creator>
      <pubDate>Tue, 07 Jun 2022 16:03:25 +0000</pubDate>
      <link>https://forem.com/rossli/first-github-pull-request-1728</link>
      <guid>https://forem.com/rossli/first-github-pull-request-1728</guid>
      <description>&lt;p&gt;Just created my first GitHub pull request today, it was about correcting an error in a simple sudoku game solver. Although it was simple, it sure felt good!&lt;/p&gt;

</description>
      <category>beginners</category>
    </item>
  </channel>
</rss>
