<rss version="2.0">
  <channel>
    <title>Meet Gor - Type: til</title>
    <link>https://www.meetgor.com</link>
    <description>Posts of type til</description>
    <language>en-us</language>
    <pubDate>Sat, 09 May 2026 05:38:52 UTC</pubDate>
    <item>
      <title>Tmux scroll mode select and copy</title>
      <link>https://www.meetgor.com/til/tmux-scroll-mode-select-and-copy</link>
      <description>I have found scrolling in tmux is a bit unconventional. Maybe its just me, but sometimes, the terminal interfaces are different, sometimes they are a bit wired,</description>
      <pubDate>Wed, 30 Jul 2025 00:00:00 UTC</pubDate>
      <content>I have found scrolling in tmux is a bit unconventional. Maybe its just me, but sometimes, the terminal interfaces are different, sometimes they are a bit wired, I use Ghostty right now, so selection without tmux works a charm, but the moment I am in tmux, ahmm, it kind of breaks.&#xA;&#xA;The selection of text doesn&#39;t work with the mouse atleast, so I thought, I need a keyboard centric selection and copying mechanism, and dug in this rabit hole. Turns out, tmux is way better in selection then zellij, the multiplexer I had been using due to scroll and selection issues in terminal interfaces.&#xA;&#xA;It&#39;s simple as `Prefix + [` to enter the scroll mode, `Shift+V` or `Ctrl+space` or `Ctrl+v` to start the selection in different ways, and finally, `Enter` or `Ctrl+j` to copy to clipboard. There is a dedicated mode for vi users, to feel at home. Tmux + Vim again a deadly combo.&#xA;&#xA;## Entering Scroll Mode&#xA;&#xA;To enter scroll mode, I had this config setup in my `.tmux.conf` file:&#xA;&#xA;```&#xA;set -g mouse on&#xA;```&#xA;&#xA;However if you want to enter without mouse on, you can use:&#xA;&#xA;```&#xA;Ctrl + b + [&#xA;```&#xA;&#xA;Here the `Ctrl + b` is for the prefix key, and `[` is the key for enterring into the  `Scroll Mode`&#xA;&#xA;From here on you can use `hjkl` or arrow keys to scroll up or down.&#xA;&#xA;To quit, you can press `q` or hit escape.&#xA;&#xA;## Selecting &#xA;&#xA;Right now in scrolling mode, you can only navigate to the next or previous line. &#xA;&#xA;But you can use `Ctrl + &lt;Space&gt;` to select any arbitrary sections of the terminal output.&#xA;There are two modes in tmux for this the `copy-mode` i.e. the default, and the `copy-mode-vi`.&#xA;&#xA;Without any config, this is be set to the default `copy-mode`, so we can use `Ctrl + Space` to begin selection in the scroll mode.&#xA;&#xA;To get more keybindings for the copy-mode and copy-mode-vi, use &#xA;&#xA;For copy-mode&#xA;```&#xA;tmux list-keys -T copy-mode&#xA;```&#xA;&#xA;For copy-mode-vi&#xA;```&#xA;tmux list-keys -T copy-mode-vi&#xA;```&#xA;&#xA;This is a default and can be over-written by using the following config:&#xA;&#xA;```&#xA;setw -g mode-keys vi&#xA;unbind-key -T copy-mode-vi Space&#xA;&#xA;# replace &lt;your-key&gt; with the key combination you want&#xA;bind-key -T copy-mode-vi &lt;your-key&gt; send-keys -X begin-selection&#xA;&#xA;# Example: using ctrl + b + v as the key to start selection&#xA;# bind-key -T copy-mode-vi v send-keys -X begin-selection&#xA;```&#xA;&#xA;This all would be applied to copy-mode if you are not changing the keybindings for copy-mode-vi.&#xA;&#xA;## Copying&#xA;&#xA;Once, you have the selected region or piece of text, you can copy that to the clipboard (that is what you do, while logs-driven debugging :).&#xA;&#xA;By default, you can use:&#xA;&#xA;For copy-mode&#xA;- `Ctrl + w` &#xA;&#xA;or &#xA;&#xA;For copy-mode-vi&#xA;- `Ctrl + j` or `Enter` to copy the selected text to the clipboard.&#xA;&#xA;This is default, and again can be over-written by using the following config:&#xA;&#xA;```&#xA;setw -g mode-keys vi&#xA;&#xA;bind-key -T copy-mode-vi &lt;your-key&gt; send-keys -X copy-pipe-and-cancel&#xA;&#xA;# Example: Remap &#39;y&#39; in copy-mode-vi to copy selection and exit&#xA;# bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel&#xA;```&#xA;&#xA;This all would be applied to copy-mode if you are not changing the keybindings for copy-mode-vi.&#xA;&#xA;That&#39;s it this should be more than enough for most of the log-driven or printf debugging tasks.</content>
      <type>til</type>
    </item>
    <item>
      <title>Getting Python version in a UV project</title>
      <link>https://www.meetgor.com/til/getting-python-version-in-a-uv-project</link>
      <description>I was live streaming, creating a AI Coding Agent from scratch in Python. I was excited to create the agent. You can watch the here. Anyways, the thing is the uv</description>
      <pubDate>Sun, 01 Jun 2025 00:00:00 UTC</pubDate>
      <content>I was live streaming, creating a AI Coding Agent from scratch in Python. I was excited to create the agent. You can watch the [livestream](https://youtube.com/clip/Ugkx2AcRqaYcMgAqZgtA2k48iYb8sJf9VL6F?si=XTtC2zFs2Kloia0L) here. &#xA;&#xA;Anyways, the thing is the uv python project has a `. python_version` file that will store the python version.&#xA;&#xA;I thought, it might be used from `pyproject.toml`, or other setup files. But that is really neat from uv.</content>
      <type>til</type>
    </item>
    <item>
      <title>Add hunks: only line specific changes with git add -p</title>
      <link>https://www.meetgor.com/til/add-hunks-only-line-specific-changes-with-git-add--p</link>
      <description>I had made the changes for a future release, next set of changes so to speak in git terms. Then, I encountered a bug while testing the previous changes. Now, I</description>
      <pubDate>Fri, 11 Apr 2025 00:00:00 UTC</pubDate>
      <content>I had made the changes for a future release, next set of changes so to speak in git terms. Then, I encountered a bug while testing the previous changes. Now, I could have &#xA;1. Open VS Code and add that little `+` icon in the gutter to fix the bug&#xA;2. Create a separate branch with stashed changes for this new feature&#xA;3. Use GitSigns in NeoVim&#xA;4. Use `git add -p` to stage [hunks](https://git-scm.com/book/en/v2/Git-Tools-Interactive-Staging)&#xA;&#xA;The last one was a gem given by ChatGPT, and then I went a bit rabbit hole for reading about it and it turns out it&#39;s real! &#xA;&#xA;It&#39;s called staging patches, and it has an interactive mode to select or reject each hunk (patch, line of changes) at a time. So by entering the command `git add -p` this will let you go through each file and individual change (patch/hunk) and take action interactively. You can use the below commands for moving one hunk or patch at a time: &#xA;- `y` for adding (staging) the current hunk (patch)&#xA;- `n` for not staging the current hunk&#xA;&#xA;Or you can even use the below commands for moving one file at once:&#xA;- `a` for adding (staging) all the patches in the file (just like `git add file.txt`)&#xA;- `d` for not staging the file at all, just skip the file for patching&#xA;&#xA;If there are multiple hunks (patches) in the file, the prompt will show the other options like `[y,n,q,a,d,j,J,g,/,e,?]` &#xA;&#xA;```&#xA;(1/7) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? g&#xA;1: -33,6 +33,7 +from app.utils.utils import get_additional_param&#xA;2: -345,6 +346,7 + strict_check = str_to_bool(get_additional_param(&#34;stri&#xA;....&#xA;....&#xA;7: -875,7 +878,7 - if strict_check:&#xA;```&#xA;&#xA;This shows the `g`, `j`, `J`, `/`, and `e` which are quite helpful for navigating across multiple patches (hunks) in the file. I haven&#39;t explored all of them, but the 4, I showed earlier, are the ones that I think I will be using extensively now, within the terminal. No need of fancy editor shenanigans and redundant branching tricks. &#xA;&#xA;Git Good!</content>
      <type>til</type>
    </item>
    <item>
      <title>Add hunks: only line specific changes with git add -p</title>
      <link>https://www.meetgor.com/til/add-hunks-only-line-specific-changes-with-git-add-p</link>
      <description>I had made the changes for a future release, next set of changes so to speak in git terms. Then, I encountered a bug while testing the previous changes. Now, I</description>
      <pubDate>Fri, 11 Apr 2025 00:00:00 UTC</pubDate>
      <content>I had made the changes for a future release, next set of changes so to speak in git terms. Then, I encountered a bug while testing the previous changes. Now, I could have &#xA;1. Open VS Code and add that little `+` icon in the gutter to fix the bug&#xA;2. Create a separate branch with stashed changes for this new feature&#xA;3. Use GitSigns in NeoVim&#xA;4. Use `git add -p` to stage [hunks](https://git-scm.com/book/en/v2/Git-Tools-Interactive-Staging)&#xA;&#xA;The last one was a gem given by ChatGPT, and then I went a bit rabbit hole for reading about it and it turns out it&#39;s real! &#xA;&#xA;It&#39;s called staging patches, and it has an interactive mode to select or reject each hunk (patch, line of changes) at a time. So by entering the command `git add -p` this will let you go through each file and individual change (patch/hunk) and take action interactively. You can use the below commands for moving one hunk or patch at a time: &#xA;- `y` for adding (staging) the current hunk (patch)&#xA;- `n` for not staging the current hunk&#xA;&#xA;Or you can even use the below commands for moving one file at once:&#xA;- `a` for adding (staging) all the patches in the file (just like `git add file.txt`)&#xA;- `d` for not staging the file at all, just skip the file for patching&#xA;&#xA;If there are multiple hunks (patches) in the file, the prompt will show the other options like `[y,n,q,a,d,j,J,g,/,e,?]` &#xA;&#xA;```&#xA;(1/7) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? g&#xA;1: -33,6 +33,7 +from app.utils.utils import get_additional_param&#xA;2: -345,6 +346,7 + strict_check = str_to_bool(get_additional_param(&#34;stri&#xA;....&#xA;....&#xA;7: -875,7 +878,7 - if strict_check:&#xA;```&#xA;&#xA;This shows the `g`, `j`, `J`, `/`, and `e` which are quite helpful for navigating across multiple patches (hunks) in the file. I haven&#39;t explored all of them, but the 4, I showed earlier, are the ones that I think I will be using extensively now, within the terminal. No need of fancy editor shenanigans and redundant branching tricks. &#xA;&#xA;Git Good!</content>
      <type>til</type>
    </item>
    <item>
      <title>Format JSON in Vim with JQ</title>
      <link>https://www.meetgor.com/til/format-json-in-vim-with-jq</link>
      <description>We can use :%!jq . To instantly format a json file opened in vim/neovim. I relied on online foramtter and opening vscode for formatting. But this quick tool jus</description>
      <pubDate>Sat, 05 Apr 2025 00:00:00 UTC</pubDate>
      <content>&lt;p&gt;We can use&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;:%!jq .&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;To instantly format a json file opened in vim/neovim.&#xA;I relied on online foramtter and opening vscode for formatting.&#xA;But this quick tool just saves a lot of hassle. Opening VS Co** == shutting down the laptop, it clogs the memory badly, so I avoid opening VS Co** as much as possible.&lt;/p&gt;&#xA;&lt;p&gt;Yes, to use this, you need to have &lt;a href=&#34;https://jqlang.org/&#34;&gt;jq&lt;/a&gt; installed on your system.&lt;/p&gt;&#xA;&lt;p&gt;If you are elsewhere and want to format json file using jq, you can quickly do this:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;jq . input.json | sponge input.json&#xA;&#xA;# OR&#xA;&#xA;jq . input.json &amp;gt; tmp.json &amp;amp;&amp;amp; mv tmp.json input.json&#xA;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;If you are in Vim and want to format other file, just add &lt;code&gt;!&lt;/code&gt; at the start of the command and that will run in the shell for you, so you don&#39;t have to exit vim.&lt;/p&gt;&#xA;</content>
      <type>til</type>
    </item>
    <item>
      <title>Zellij Open Scrollback Edit mode</title>
      <link>https://www.meetgor.com/til/zellij-open-scrollback-edit-mode</link>
      <description>I was looking at a long list of logs, (debugging of course). I had a list of transactions Two list of transactions, one as ground truth and other as predicted.</description>
      <pubDate>Thu, 20 Mar 2025 00:00:00 UTC</pubDate>
      <content>I was looking at a long list of logs, (debugging of course). &#xA;&#xA;I had a list of transactions&#xA;- Two list of transactions, one as ground truth and other as predicted.  Transactions is a list of object(dictionary or map), each object has fields like date, amount, description, etc.&#xA;- Those objects in a list need not necessarily be in order, however I do want to compare them, how to do that?&#xA;- I decided to sort them based on date(one field in that object).&#xA;&#xA;Then for each date, I group the transactions and this would narrow down the search space for comparison of one-one transaction, since now I can compare which of the ones are closely matching, the date will be a exact match the amount should also be, the description can be fuzzily matched.&#xA;&#xA;However, for amount, I guess I was wrong, there could be a value like `10` and the other could have `10.01` and those python doesn&#39;t count equal atleast when compared as a string. I converted to float and compared rounded off numbers.&#xA;&#xA;Now the problem kicked in and print statements flooded, dates everywhere.&#xA;&#xA;Now I was using ghostty terminal, and there was definitely some scroll limit so I couldn&#39;t scroll all the way to start. So I opened up zellij.&#xA;&#xA;I had a log with *MATCHED* text where I logged the date and amount where both transaction matched.&#xA;&#xA;Now, I wanted a count of these matches. I could use search but it was not giving the count of occurrences, I can&#39;t keep counting with my mouth(that idea flew by though)&#xA;&#xA;Now, that&#39;s where I accidentally hit `&lt;ctrl&gt;S` and `E`&#xA;And I was in a editor, woah!&#xA;&#xA;I was excited, I could finally copy and throw that in vim and get everything I want.&#xA;hehe&#xA;I tried +&#34;y but it didn&#39;t copy to the clipboard, it yanked yes, but not in the system clipboard. That frustrated me and took my hope down, but I googled it and also gpted it (is that a word, I think we can say llmed it).&#xA;&#xA;And yes we can set the `export $EDITOR` to the editor executable path and it would open that thing in that editor.&#xA;&#xA;I did and it did work.&#xA;&#xA;That mode is called [scrollback-edit](https://zellij.dev/news/edit-scrollback-compact/) mode. I should say a life saver mode, a log viewer and really cool.&#xA;&#xA;I am probably too dumb and I know this exists in tmux, but I felt good and helped me solve my problem. So thank you whoever made that mode, its really helpful to debug with logs (debloging) Yes I am bad at naming things, but I like this more than vibe coding ;)</content>
      <type>til</type>
    </item>
    <item>
      <title>Sample TIL</title>
      <link>https://www.meetgor.com/til/sample-til</link>
      <description>What I learned This is the content of the TIL Conclusion Happy Coding :)</description>
      <pubDate>Sat, 30 Nov 2024 00:00:00 UTC</pubDate>
      <content>## What I learned&#xA;&#xA;This is the content of the TIL&#xA;&#xA;## Conclusion&#xA;&#xA;Happy Coding :)</content>
      <type>til</type>
    </item>
    <item>
      <title>Gotcha with Chained Assignment in Python</title>
      <link>https://www.meetgor.com/til/python-chain-assignment-gotcha</link>
      <description>A lesson learned about Python&#39;s chained assignment with mutable objects, where all variables store references to the same object, leading to unexpected behaviour when one is modified.</description>
      <pubDate>Wed, 27 Nov 2024 00:00:00 UTC</pubDate>
      <content>I was writing some Python code and wanted to initialize a few variables to an empty list. Instead of creating separate lists for each variable, I decided to use chained assignments like this:&#xA;&#xA;```python&#xA;a = b = c = [1,2,3]&#xA;```&#xA;&#xA;It seems okay, nothing new, we are just assigning a, b, and c as an empty list. But notice the problem if you can.&#xA;&#xA;If we try to change the value of b, what do you think is going to happen?&#xA;&#xA;```python&#xA;b.append(4)&#xA;```&#xA;&#xA;If you didn’t know about how Python handles assignments, you might expect the variables to behave like this:&#xA;&#xA;* `a` should still be `[1, 2, 3]`&#xA;    &#xA;* `b` should be `[1, 2, 3, 4]` (since I modified b)&#xA;    &#xA;* `c` should remain `[1, 2, 3]`&#xA;    &#xA;&#xA;```python&#xA;# You might think it will be this&#xA;# a = [1,2,3]&#xA;# b = [1,2,3,4]&#xA;# c = [1,2,3]&#xA;```&#xA;&#xA;But, hello python, it hides the pointer magic behind this statement&#xA;&#xA;The actual and expected state of the variables is:&#xA;&#xA;```python&#xA;# But it is actually this&#xA;# a = [1,2,3,4]&#xA;# b = [1,2,3,4]&#xA;# c = [1,2,3,4]&#xA;```&#xA;&#xA;When you chain the assignment like this, all three variables refer to the same list object in memory. This means, that all the variables will hold the same object, this means that if you change any of the variables assigned that reference it will change the object, and that will result in changing all the variables since they are referring to the same variable.&#xA;&#xA;You are not creating three independent lists. Instead, all three variables (a, b, and c) are referencing the same list object in memory. They don’t hold copies of the list, they all point to the same object. In Python, this is called **reference assignment**.&#xA;&#xA;When you modify one of the variables (like appending to b), you’re not modifying just b, you’re modifying the single list object that all three variables are referencing. Since all three variables point to the same list, any change you make to the list will be reflected in all three variables.&#xA;&#xA;On the other hand, if I do the same thing with strings, like this:&#xA;&#xA;```python&#xA;a = b = c = &#34;hello&#34;&#xA;b = &#34;world&#34;&#xA;&#xA;# a = &#34;hello&#34;&#xA;# b = &#34;world&#34;&#xA;# c = &#34;hello&#34;&#xA;```&#xA;&#xA;This only mutates the b variable and not the a and c, since string is not a mutable object in Python.&#xA;&#xA;In Python, the objects are either [mutable or immutable](https://realpython.com/python-mutable-vs-immutable-types/)&#xA;&#xA;Some of the primitive data types are:&#xA;&#xA;Mutable Types:&#xA;&#xA;* List&#xA;    &#xA;* Dictionaries&#xA;    &#xA;* Set&#xA;    &#xA;* Byte Array&#xA;    &#xA;&#xA;Immutable Types:&#xA;&#xA;* Integer, Float, Complex&#xA;    &#xA;* String&#xA;    &#xA;* Tuple&#xA;    &#xA;* Bytes&#xA;    &#xA;* Boolean&#xA;    &#xA;* Frozenset&#xA;    &#xA;&#xA;So, suppose you assign multiple variables with the same value of a mutable type. In that case, the change in one variable will mutate the other variables as well since the underlying object in memory is the same.&#xA;&#xA;So, this is what I learned from the mistake, avoid the chining assignment when dealing with mutable objects&#xA;&#xA;Instead do the following:&#xA;&#xA;```python&#xA;a, b, c = [], [], []&#xA;b.append(256)&#xA;&#xA;# a = []&#xA;# b = [256]&#xA;# c = []&#xA;```&#xA;&#xA;This is safe and the right way to assign variables to individual values instead of the same value being referred to by all the variables.&#xA;&#xA;Happy Coding :)</content>
      <type>til</type>
    </item>
    <item>
      <title>Building Golang from Source v1.23 and Above</title>
      <link>https://www.meetgor.com/til/golang-build-from-source-1-24-above</link>
      <description>Exploring one of the way to install and build golang from source for version 1.23 and above.</description>
      <pubDate>Tue, 19 Nov 2024 00:00:00 UTC</pubDate>
      <content>## Introduction&#xA;&#xA;Are you excited to try out the latest golang version, or test out your changes (cooking some serious stuff?), or install some random golang version? Then let’s explore one of the easiest ways to install golang on your system (Linux).&#xA;&#xA;## Building Go from source 1.23+&#xA;&#xA;The process for installing and building golang from source is quite simple.&#xA;&#xA;* Clone the repo&#xA;    &#xA;* Build the binary&#xA;    &#xA;* Set Environment Variables&#xA;    &#xA;* Export the binary to the system path&#xA;    &#xA;&#xA;For detailed other steps, you can follow [this guide](https://go.dev/doc/install/source).&#xA;&#xA;### Clone the repo&#xA;&#xA;Just clone the repo from GitHub or Google Git repo.&#xA;&#xA;```bash&#xA;git clone https://github.com/golang/go&#xA;&#xA;OR&#xA;&#xA;git clone https://go.googlesource.com/go&#xA;```&#xA;&#xA;This will install the golang source code required to build the golang binary and the ecosystem (gofmt + standard library + test suite).&#xA;&#xA;Then let’s navigate to the cloned repo and we can build the golang from the source.&#xA;&#xA;### Build it&#xA;&#xA;We need to run the bash script in the folder to build the binary. They `all.bash` can be run to build the binary which will be stored in the `go/bin` folder `go/bin/go` and `go/bin/gofmt` files. These two binaries will be generated and are required in the Golang ecosystem.&#xA;&#xA;```bash&#xA;cd src&#xA;&#xA;./all.bash&#xA;```&#xA;&#xA;Once we have the binaries in the specified folder, we can move ahead to make the environment understand where the actual binary is located.&#xA;&#xA;### Environment Variables&#xA;&#xA;The `GOROOT` and `GOPATH` variables are required for the golang ecosystem to work as expected. The `GOROOT` is set as the path to the actual golang source repository, the cloned repository from which we built the binary. This `GOPATH` is the path where Golang stores the external repositories or modules for use anywhere in the system.&#xA;&#xA;```bash&#xA;export GOROOT=path_to_clone_repo&#xA;&#xA;export GOPATH=$(HOME)/go&#xA;&#xA;export PATH=$PATH:$GOROOT/bin:$GOPATH/bin&#xA;```&#xA;&#xA;The `PATH` environment needs to be updated with the `GOROOT` and `GOPATH` to make the binaries in those paths visible and accessible to the system.&#xA;&#xA;&gt; NOTE: If you are installing the golang from source when you have already a version of golang installed on your system, then you need to make sure you do not mess up the `GOROOT` and `GOPATH`.&#xA;&gt; &#xA;&gt; Those could be juse set with the current shell session, as you do not want this golang version permantely on the system, if you do requrie the newly installed golang version as your default, then you can set this environment variables in your shell config.&#xA;&#xA;Finally, we can now set the binary as something different because we do not want it to clash with the default golang version.&#xA;&#xA;### Run the binary&#xA;&#xA;The binary can be stored in the `/usr/local/bin/` to make any binary available in the system from anywhere. This is not necessary but handy if you are going to use it commonly but don’t need it as the default golang version.&#xA;&#xA;```bash&#xA;# The binary is stored in the &#xA;# path_to_cloned_repo/bin&#xA;# Whatever you want to name the binary&#xA;&#xA;cp bin/go /usr/local/bin/go-dev&#xA;&#xA;OR&#xA;&#xA;cp bin/go /usr/local/bin/go1.24&#xA;```&#xA;&#xA;Once this is done. we can check the installed golang version&#xA;&#xA;```bash&#xA;go1.24 version&#xA;```&#xA;&#xA;With this, you can use it as go1.24 or go-dev as the binary name.&#xA;&#xA;So, that is how we install and build from source any golang version above 1.23.&#xA;&#xA;## Conclusion&#xA;&#xA;For context, I wanted to check out the latest changes in 1.24, so I cloned the repo and after some trial and error of some commands to build the golang version, I was able to do it correctly. So just decided to share it here, hope you found it helpful.&#xA;&#xA;Thank you for reading.&#xA;&#xA;Happy Coding :)</content>
      <type>til</type>
    </item>
    <item>
      <title>Adding SSH Keys for Multiple Accounts in Git</title>
      <link>https://www.meetgor.com/til/git-ssh-multiple-accounts</link>
      <description>Setting up SSH config for using multiple accounts for Git repositories.</description>
      <pubDate>Fri, 22 Mar 2024 00:00:00 UTC</pubDate>
      <content>Let&#39;s  say you have multiple github accounts. One for your personal projects, one for your company that you work at, and one other remote repository account (let&#39;s say gitlab).&#xA;&#xA;You are juggling with multiple accounts, you should not waste much time and pick a SSH from those remote repository and pull it in your local machine, that makes the process just smooth and saves a ton of time.&#xA;&#xA;### Create a SSH Key&#xA;&#xA;To create a SSH key, in linux you can use `ssh-keygen` command.&#xA;&#xA;```bash&#xA;ssh-keygen -t ed25519 -C &#34;alice@example.com&#34;&#xA;```&#xA;&#xA;The above command will prompt you for two things&#xA;&#xA;1. The location where you want to store the key&#xA;2. The passphrase for accessing the key&#xA;&#xA;&#xA;### Add SSH Key to Github&#xA;&#xA;Locate to the `ssh` folder and copy the generated `.pub` file to your `github` account.&#xA;&#xA;For example, if you have created the key at `~/.ssh/your_name` then copy the contents of the file `~/.ssh/your_name.pub` to your clipbaord.&#xA;&#xA;Navigate to your `github` account and in the settings, `SSH and GPG keys` tab, click on `Add SSH key` and copy the contents of your clipboard to the `Key` field.&#xA;&#xA;&#xA;### Configuring the SSH keys for multiple accounts&#xA;&#xA;```config&#xA;Host your_company&#xA;  HostName github.com&#xA;  User git&#xA;  IdentityFile ~/.ssh/your_company&#xA;&#xA;Host your_name&#xA;  HostName github.com&#xA;  User git&#xA;  IdentityFile ~/.ssh/your_name&#xA;&#xA;Host some_name&#xA;  HostName gitlab.com&#xA;  User git&#xA;  IdentityFile ~/.ssh/some_name&#xA;```&#xA;&#xA;You can change the `Host` config tag values in the `~/.ssh/conFig`&#xA;&#xA;The next time you clone/create a repository on those remote git providers, you need to specify the ssh key for that account.&#xA;&#xA;For example, if you have a repository `github.com/StartUp_company/some_wired_project` then you can specify the remote as `git@your_company.com:StartUp_company/some_wired_project`. Here, the `git@your_company` is the `Host` value tag from the `~/.ssh/config`. If that repository is from your `your_company` organisation/user scope, you need to add the `git@your_company` tag, if that&#39;s your project, simply add `git@your_name` before the repository url i.e. `your_name/repo_name` which would set the origin as `git@your_name:your_name/repo_name`, here the 1st `your_name` is the tag from the `Host` config and the 2nd `your_name` is the github username.&#xA;&#xA;So, in summary if you wanted to use multiple accounts in the same machine, you can understand in the following example:&#xA;&#xA;```bash&#xA;ssh -T git@your_name&#xA;&#xA;git clone https://github.com/your_name/repo_name&#xA;```&#xA;&#xA;However, you will need to authenticate with the ssh keys in this way everytime you push/pull a repository. So for that, you can set the origin with the `git@your_name` tag as the host for automatically authenticating the ssh keys on every push/pull or other activities.&#xA;&#xA;Thanks for reading, Happy Coding :)</content>
      <type>til</type>
    </item>
    <item>
      <title>Turn Python dictionary into a neat CSV table</title>
      <link>https://www.meetgor.com/til/python-dict-to-csv-table</link>
      <description>Exploring how to write python dict/key-value pairs and a table-like structure to a CSV file.</description>
      <pubDate>Wed, 20 Mar 2024 00:00:00 UTC</pubDate>
      <content>## Populating a Python dict having a table-like structure to a CSV&#xA;&#xA;Today, I want to share with you a neat trick I recently discovered for populating a CSV file with data in a table-like structure using Python.&#xA;&#xA;### Writing Key-Value Pairs to a CSV Row&#xA;&#xA;Firstly, let&#39;s discuss the `write_key_value` function. This function allows us to write key-value pairs to a CSV row. It&#39;s particularly useful when dealing with metrics or data that can be represented as simple pairs.&#xA;&#xA;```python&#xA;# Function to populate a CSV row with key-value pairs&#xA;def write_key_value(writer, dictionary):&#xA;    for key, value in dictionary.items():&#xA;        writer.writerow([key, value])&#xA;```&#xA;&#xA;### Writing a Table-Like Structure to a CSV File&#xA;&#xA;Now, let&#39;s dive into the `write_table` function, which handles more complex scenarios where the data follows a table-like structure. This function takes into account different types of metrics and adjusts the CSV table structure accordingly.&#xA;&#xA;Assuming you have a structure of the dictionary like:&#xA;&#xA;```python&#xA;data = {&#xA;    &#34;Students&#34;: {&#xA;        &#34;John Doe&#34;: {&#xA;            &#34;course&#34;: &#34;Mathematics&#34;,&#xA;            &#34;grade&#34;: &#34;A&#34;,&#xA;            &#34;attendance&#34;: 95,&#xA;            &#34;assignments_completed&#34;: 15,&#xA;            &#34;student_id&#34;: &#34;JD001&#34;&#xA;        },&#xA;        &#34;Alice Smith&#34;: {&#xA;            &#34;course&#34;: &#34;Physics&#34;,&#xA;            &#34;grade&#34;: &#34;B+&#34;,&#xA;            &#34;attendance&#34;: 85,&#xA;            &#34;assignments_completed&#34;: 12,&#xA;            &#34;student_id&#34;: &#34;AS002&#34;&#xA;        },&#xA;        &#34;Bob Johnson&#34;: {&#xA;            &#34;course&#34;: &#34;Computer Science&#34;,&#xA;            &#34;grade&#34;: &#34;A-&#34;,&#xA;            &#34;attendance&#34;: 90,&#xA;            &#34;assignments_completed&#34;: 14,&#xA;            &#34;student_id&#34;: &#34;BJ003&#34;&#xA;        }&#xA;    }&#xA;}&#xA;```&#xA;&#xA;And you want to write it to a CSV file, like this:&#xA;&#xA;```csv&#xA;student, course, grade, attendance, assignments_completed, student_id&#xA;John Doe, Mathematics, A, 95, 15, JD001&#xA;Alice Smith, Physics, B+, 85, 12, AS002&#xA;Bob Johnson, Computer Science, A-, 90, 14, BJ003&#xA;```&#xA;&#xA;We can create a function `write_table` that will take in the `dictionary` as the actual data. We want to store the keys of the inner dictionary to be the header/columns of the csv file. As we can see the keys of the inner dict i.e. the value for the key `John Doe` is a dict with the keys `course`, `grade`, `attendance`, etc. which remain the same for the all the keys in the dictionary.&#xA;&#xA;So, we can first create a `row_keys` variable to store the keys of the actual dictionary this will be the first column rows in the csv. &#xA;&#xA;Further we check if the `row_keys` is a dict and then we append it with the `index_key` which will be the first column in the csv. Since all the keys remain the same for the inner-dict, we can pick the first dict and create the `header` with the inner-dict keys.&#xA;&#xA;So, we can write the list `header` to the csv file.&#xA;&#xA;Then for each key in the `row_keys` we can create a list `row` with the key and the values of the inner-dict.&#xA;&#xA;&#xA;```python&#xA;# Function to populate a CSV with a table-like structure&#xA;def write_table(writer, dictionary, index_key):&#xA;&#xA;    row_keys = list(dictionary.keys())&#xA;&#xA;    if row_keys and data[row_keys[0]] is not None:&#xA;        headers = [index_key] + list(&#xA;            dictionary[row_keys[0]].keys()&#xA;        )&#xA;    else:&#xA;        return&#xA;    writer.writerow(headers)&#xA;    for key in row_keys:&#xA;        row = [key] + list(dictionary[key].values())&#xA;        writer.writerow(row)&#xA;&#xA;&#xA;with open(&#39;data.csv&#39;, &#39;w&#39;, newline=&#39;&#39;) as csvfile:&#xA;    writer = csv.writer(csvfile)&#xA;    for key in data:&#xA;        write_table(writer, data[key], key)&#xA;```&#xA;&#xA;### Example Usage&#xA;&#xA;To illustrate how these functions can be used, let&#39;s consider a scenario where we have various types of metrics to populate into a CSV file. We handle key-value paired metrics separately and then populate the CSV with table-like metrics.&#xA;&#xA;```python&#xA;import csv&#xA;&#xA;data = {&#xA;    &#34;Students&#34;: {&#xA;        &#34;John Doe&#34;: {&#xA;            &#34;course&#34;: &#34;Mathematics&#34;,&#xA;            &#34;grade&#34;: &#34;A&#34;,&#xA;            &#34;attendance&#34;: 95,&#xA;            &#34;assignments_completed&#34;: 15,&#xA;            &#34;student_id&#34;: &#34;JD001&#34;&#xA;        },&#xA;        &#34;Alice Smith&#34;: {&#xA;            &#34;course&#34;: &#34;Physics&#34;,&#xA;            &#34;grade&#34;: &#34;B+&#34;,&#xA;            &#34;attendance&#34;: 85,&#xA;            &#34;assignments_completed&#34;: 12,&#xA;            &#34;student_id&#34;: &#34;AS002&#34;&#xA;        },&#xA;        &#34;Bob Johnson&#34;: {&#xA;            &#34;course&#34;: &#34;Computer Science&#34;,&#xA;            &#34;grade&#34;: &#34;A-&#34;,&#xA;            &#34;attendance&#34;: 90,&#xA;            &#34;assignments_completed&#34;: 14,&#xA;            &#34;student_id&#34;: &#34;BJ003&#34;&#xA;        }&#xA;    },&#xA;    &#34;Countries&#34;: {&#xA;        &#34;USA&#34;: {&#xA;            &#34;capital&#34;: &#34;Washington, D.C.&#34;,&#xA;            &#34;population&#34;: 331000000,&#xA;            &#34;area_sq_km&#34;: 9833517,&#xA;            &#34;official_languages&#34;: [&#34;English&#34;, &#34;Spanish&#34;],&#xA;            &#34;currency&#34;: &#34;United States Dollar (USD)&#34;&#xA;        },&#xA;        &#34;India&#34;: {&#xA;            &#34;capital&#34;: &#34;New Delhi&#34;,&#xA;            &#34;population&#34;: 1380004385,&#xA;            &#34;area_sq_km&#34;: 3287263,&#xA;            &#34;official_languages&#34;: [&#34;Hindi&#34;, &#34;English&#34;],&#xA;            &#34;currency&#34;: &#34;Indian Rupee (INR)&#34;&#xA;        },&#xA;        &#34;Brazil&#34;: {&#xA;            &#34;capital&#34;: &#34;Brasília&#34;,&#xA;            &#34;population&#34;: 212559417,&#xA;            &#34;area_sq_km&#34;: 8515770,&#xA;            &#34;official_languages&#34;: [&#34;Portuguese&#34;],&#xA;            &#34;currency&#34;: &#34;Brazilian Real (BRL)&#34;&#xA;        }&#xA;    }&#xA;}&#xA;&#xA;def populate_table(writer, data, index_key):&#xA;    row_keys = list(data.keys())&#xA;    if row_keys and data[row_keys[0]] is not None:&#xA;        headers = [index_key] + list(data[row_keys[0]].keys())&#xA;    else:&#xA;        return&#xA;    writer.writerow(headers)&#xA;    for key in row_keys:&#xA;        row = [key] + list(data[key].values())&#xA;        writer.writerow(row)&#xA;&#xA;&#xA;with open(&#39;data.csv&#39;, &#39;w&#39;, newline=&#39;&#39;) as csvfile:&#xA;    writer = csv.writer(csvfile)&#xA;    for key in data:&#xA;        populate_table(writer, data[key], key)&#xA;        writer.writerow([])&#xA;```&#xA;&#xA;```csv&#xA;Students,course,grade,attendance,assignments_completed,student_id&#xA;John Doe,Mathematics,A,95,15,JD001&#xA;Alice Smith,Physics,B+,85,12,AS002&#xA;Bob Johnson,Computer Science,A-,90,14,BJ003&#xA;&#xA;Countries,capital,population,area_sq_km,official_languages,currency&#xA;USA,&#34;Washington, D.C.&#34;,331000000,9833517,&#34;[&#39;English&#39;, &#39;Spanish&#39;]&#34;,United States Dollar (USD)&#xA;India,New Delhi,1380004385,3287263,&#34;[&#39;Hindi&#39;, &#39;English&#39;]&#34;,Indian Rupee (INR)&#xA;Brazil,Brasília,212559417,8515770,[&#39;Portuguese&#39;],Brazilian Real (BRL)&#xA;```&#xA;&#xA;Thank you, Happy Coding :)</content>
      <type>til</type>
    </item>
    <item>
      <title>SQLite importing CSV with custom separator</title>
      <link>https://www.meetgor.com/til/sqlite-inline-custom-separator</link>
      <description>Explorng SQLite CLI with inline CSV import command with custom separator</description>
      <pubDate>Fri, 15 Mar 2024 00:00:00 UTC</pubDate>
      <content>explaination about how i learned how to write a command for importing a csv &#xA;into a sqlite3 db with cusotm Separator with a single command inline&#xA;&#xA;## Introduction&#xA;&#xA;I was exploring some Issues that I can solve given the context of the problem and the intution for the solution.&#xA;&#xA;I have some github repositories that I always look for to learn more. Some of them are:&#xA;&#xA;- [Steampipe](https://github.com/turbot/steampipe)&#xA;- [MindsDB](https://github.com/mindsdb/mindsdb)&#xA;- [Turso](https://github.com/tursodatabase)&#xA;&#xA;So, navigating around for a few minutes, I landed on this [issue](https://github.com/tursodatabase/turso-cli/issues/811).&#xA;&#xA;The issue is really well explained in terms of what the feature is to be added, how the usage should be, which for a contributor is half the job done.&#xA;&#xA;## What?&#xA;&#xA;The [turso-cli](https://github.com/tursodatabase/turso-cli) is a CLI for [Turso](https://github.com/tursodatabase/turso) that is used to manage libsql databases with the [turso](https://turso.tech) platform.&#xA;&#xA;This issue is about adding a flag to the `db create` command to allow the user to pass in a custom separator while imporing a csv file into a sqlite3 database.&#xA;&#xA;The only puzzle piece left is to answer the question `how`?&#xA;&#xA;## How?&#xA;&#xA;So, I went in to the Codebase and found where the `db create` command has been handled and landed on this [file](https://sourcegraph.com/github.com/tursodatabase/turso-cli/-/blob/internal/cmd/db_create.go)&#xA;&#xA;While controbuting to open source, I try to do the small steps and solve try to maintain the excitment with that progress. Because if you cannot find the solution, you try to procastinate and in the end nothing gets accomplished. So, breaking down the problem into small chunks is much helpful than solving the entire problem.&#xA;&#xA;In this case, I  tried to add the flag in the cli which is pretty straight forward. We just add one more entry in the list of flags in the `db create` command. This step is just to add a functional CLI for taking the input of csv-separator string, however, this won&#39;t do anything for the functionality part of things, just allow the user to specify the separator/delimitor to use for parsing the CSV file.&#xA;&#xA;Currently, the command that `turso db create` uses under the hood for creating a db from a csv file is:&#xA;&#xA;```bash&#xA;sqlite3 &#34;-csv&#34; &#34;dbName&#34; &#34;.import &lt;FileName&gt; &lt;TableName&gt;&#34;&#xA;```&#xA;&#xA;The above command is found in the [group flag](https://sourcegraph.com/github.com/tursodatabase/turso-cli/-/blob/internal/cmd/group_flag.go) file. To parse in the separator, we can use another string as `.separator &#34;;&#34;`, here the `;` is the character that should be used as the separator for the csv file into the db.&#xA;&#xA;```bash&#xA;sqlite3 &#34;-csv&#34; &#34;dbname&#34; &#34;.separator&#34; &#34;;&#34; &#34;.import &lt;FileName&gt; &lt;TableName&gt;&#34;&#xA;```&#xA;&#xA;Thank you, Happy Coding :)</content>
      <type>til</type>
    </item>
    <item>
      <title>Golang: Sort Package Introduction</title>
      <link>https://www.meetgor.com/til/golang-sort-package-basic</link>
      <description>Understanding the fundamentals of the sort package in Golang. Sorting integers, slices, struct values, maps</description>
      <pubDate>Mon, 15 Jan 2024 00:00:00 UTC</pubDate>
      <content>I have been learning Golang for around 2 years now, and I have never paid attention to the sort package, can you believe that! Where was this package hiding?&#xA;&#xA;The `sort` package provides convenient methods for sorting slices and user-defined collections in Go. Here&#39;s a quick overview of what it can do:&#xA;&#xA;## Sorting Slices&#xA;&#xA;To sort a slice of builtin types like ints, strings, etc, you can simply call `sort.Slice()`:&#xA;&#xA;```go&#xA;nums := []int{5, 2, 6, 3, 1}&#xA;&#xA;sort.Slice(nums, func(i, j int) bool {&#xA;    return nums[i] &lt; nums[j]&#xA;})&#xA;&#xA;// or &#xA;// sorts.Ints(nums)&#xA;&#xA;fmt.Println(nums)&#xA;```&#xA;&#xA;```bash&#xA;$ go run main.go&#xA;&#xA;[1, 2, 3, 5, 6]&#xA;```&#xA;The sort is in-place, mutating the original slice. You can customize the sort order by providing a less(i, j int) bool function.&#xA;&#xA;## Sorting Struct Slices&#xA;&#xA;To sort a slice of custom structs, add a Len(), Less(i, j int) bool, and Swap(i, j int) method:&#xA;&#xA;```go&#xA;type Person struct {&#xA;  Name string&#xA;  Age  int&#xA;}&#xA;&#xA;people := []Person{&#xA;  {&#34;Bob&#34;, 30},&#xA;  {&#34;John&#34;, 20},&#xA;  {&#34;Alice&#34;, 25},&#xA;}&#xA;&#xA;sort.Slice(people, func(i, j int) bool {&#xA;  return people[i].Age &lt; people[j].Age&#xA;}) &#xA;&#xA;fmt.Println(person)&#xA;```&#xA;&#xA;```bash&#xA;$ go run main.go&#xA;[{&#34;Name&#34;:&#34;Alice&#34;,&#34;Age&#34;:25},{&#34;Name&#34;:&#34;Bob&#34;,&#34;Age&#34;:30},{&#34;Name&#34;:&#34;John&#34;,&#34;Age&#34;:20}]&#xA;```&#xA;&#xA;This will sort people by age.&#xA;&#xA;## Sorting Maps&#xA;&#xA;Maps are inherently unordered in Go. We can&#39;t sort them, but we can iterate them in a sorted way. We need a separate slice of keys or values(whicher required), we will sort those keys/values and iterate over them in that order.:&#xA;&#xA;### Sort by Keys&#xA;&#xA;To sort a map by keys, we can use the `sort.Strings()` function or any other sort function as per the data structure, there are functions like [sort.Ints](https://pkg.go.dev/sort#Ints), [sort.Float64](https://pkg.go.dev/sort#Float64s), or [sort.Slice](https://pkg.go.dev/sort#Slice). We can create a new slice of keys from the map and then apply the sort on that newly created slice. After the slice of keys is created, we can iterate over it and access the map values in a order of sorted keys.&#xA;&#xA;```go&#xA;counts := map[string]int{&#xA;  &#34;hello&#34;: 5,&#xA;  &#34;world&#34;: 2,&#xA;  &#34;foo&#34;: 3,&#xA;}&#xA;&#xA;keys := make([]string, 0, len(counts))&#xA;// extract keys &#xA;for k := range counts {&#xA;  keys = append(keys, k)&#xA;} &#xA;&#xA;// sort keys&#xA;sort.Strings(keys) &#xA;&#xA;// iterate with the sorted keys slice&#xA;for _, k := range keys {&#xA;  fmt.Println(k, counts[k]) &#xA;}&#xA;```&#xA;&#xA;```bash&#xA;$ go run main.go&#xA;&#xA;foo 3&#xA;hello 5&#xA;world 2&#xA;```&#xA;&#xA;This prints the map ordered by key. You can sort by value too.&#xA;&#xA;### Sort by Value&#xA;&#xA;To iterate the map with sorting order of values, we can approach it in a similar way. We create a slice of keys. This time, we don&#39;t sort the keys, instead, we change the position of the slice of keys depending on the values. This changes the key order based on the sorted values in the map. By similarly iterating over the key slice, we iterate over the map in a sorted order of the values.&#xA;&#xA;```go&#xA;counts := map[string]int{&#xA;  &#34;hello&#34;: 5,&#xA;  &#34;world&#34;: 2,&#xA;  &#34;foo&#34;: 3,&#xA;}&#xA;&#xA;keys := make([]string, 0, len(counts))&#xA;// extract keys&#xA;for k := range counts {&#xA;  keys = append(keys, k)&#xA;}&#xA;&#xA;// sort by value&#xA;// i.e. change the order of key based on values sort order&#xA;sort.SliceStable(keys, func(i, j int) bool {&#xA;    return counts[keys[i]] &lt; counts[keys[j]]&#xA;})&#xA;&#xA;// iterate sorted&#xA;for _, k := range keys {&#xA;  fmt.Println(k, counts[k])&#xA;}&#xA;```&#xA;&#xA;```bash&#xA;$ go run main.go&#xA;&#xA;world 2&#xA;foo 3&#xA;hello 5&#xA;```&#xA;&#xA;The `sort.SliceStable` function is used to sort the slice in place. It takes in a slice and the less function which is the actual logic for comparison in the values. This function sorts the key elements based on the values in the map, and thereby the key slice is shuffled by the sorted order of the values in the map.&#xA;&#xA;The sort package is super useful for quickly organizing Go data structures.&#xA;There are [Find](https://pkg.go.dev/sort#Find) which tries to return a index of the first element that satisfies a comparison condition with a flag or found or not with a boolean. There is also a [Search](https://pkg.go.dev/sort#Search) which is used specifically for searching elements in a sorted array, it also gives a first index of the occuring element. But that is a topic for another day!&#xA;&#xA;Thank you, Happy Coding :)</content>
      <type>til</type>
    </item>
    <item>
      <title>Golang: Test Output JSON</title>
      <link>https://www.meetgor.com/til/golang-test-output-json</link>
      <description>Obtain JSON output of test results in Golang</description>
      <pubDate>Mon, 01 Jan 2024 00:00:00 UTC</pubDate>
      <content>I just discovered that we can generate a JSON output of test results in Golang. I found this [here](https://youtu.be/cf72gMBrsI0?t=80).&#xA;&#xA;Let&#39;s take a fresh simple example.&#xA;&#xA;```go&#xA;package jsontest&#xA;&#xA;func hello() string {&#xA;    return &#34;Hello, World!&#34;&#xA;}&#xA;```&#xA;```go&#xA;package jsontest&#xA;&#xA;import (&#xA;    &#34;testing&#34;&#xA;)&#xA;&#xA;func TestHello(t *testing.T) {&#xA;    want := &#34;Hello, World!&#34;&#xA;    got := hello()&#xA;    t.Logf(&#34;got: %q&#34;, got)&#xA;    if got != want {&#xA;        t.Errorf(&#34;got: %q, want: %q&#34;, got, want)&#xA;    }&#xA;}&#xA;```&#xA;&#xA;Here, we have a function `hello` that simply returns a string, the `TestHello` function in the `jsontest` package will check if the returned string is correctly returned or not.&#xA;&#xA;So, we can test this with `go test ./...` command, this will give out the output in a standard output/error in text format. However, if we add the `-json` flag, we can get the output in JSON format.&#xA;&#xA;&#xA;```bash&#xA;go test ./... -json&#xA;```&#xA;&#xA;```json&#xA;{&#34;Time&#34;:&#34;2024-01-01T20:52:45.861974085+05:30&#34;,&#34;Action&#34;:&#34;start&#34;,&#34;Package&#34;:&#34;json-test&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T20:52:45.863133332+05:30&#34;,&#34;Action&#34;:&#34;run&#34;,&#34;Package&#34;:&#34;json-test&#34;,&#34;Test&#34;:&#34;TestHello&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T20:52:45.863142397+05:30&#34;,&#34;Action&#34;:&#34;output&#34;,&#34;Package&#34;:&#34;json-test&#34;,&#34;Test&#34;:&#34;TestHello&#34;,&#34;Output&#34;:&#34;=== RUN   TestHello\n&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T20:52:45.863148346+05:30&#34;,&#34;Action&#34;:&#34;output&#34;,&#34;Package&#34;:&#34;json-test&#34;,&#34;Test&#34;:&#34;TestHello&#34;,&#34;Output&#34;:&#34;    main_test.go:10: got: \&#34;Hello, World\&#34;\n&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T20:52:45.863151351+05:30&#34;,&#34;Action&#34;:&#34;output&#34;,&#34;Package&#34;:&#34;json-test&#34;,&#34;Test&#34;:&#34;TestHello&#34;,&#34;Output&#34;:&#34;    main_test.go:12: got: \&#34;Hello, World\&#34;, want: \&#34;Hello, World!\&#34;\n&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T20:52:45.863157014+05:30&#34;,&#34;Action&#34;:&#34;output&#34;,&#34;Package&#34;:&#34;json-test&#34;,&#34;Test&#34;:&#34;TestHello&#34;,&#34;Output&#34;:&#34;--- FAIL: TestHello (0.00s)\n&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T20:52:45.863160418+05:30&#34;,&#34;Action&#34;:&#34;fail&#34;,&#34;Package&#34;:&#34;json-test&#34;,&#34;Test&#34;:&#34;TestHello&#34;,&#34;Elapsed&#34;:0}&#xA;{&#34;Time&#34;:&#34;2024-01-01T20:52:45.863411555+05:30&#34;,&#34;Action&#34;:&#34;output&#34;,&#34;Package&#34;:&#34;json-test&#34;,&#34;Output&#34;:&#34;FAIL\n&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T20:52:45.863438344+05:30&#34;,&#34;Action&#34;:&#34;output&#34;,&#34;Package&#34;:&#34;json-test&#34;,&#34;Output&#34;:&#34;FAIL\tjson-test\t0.001s\n&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T20:52:45.863443461+05:30&#34;,&#34;Action&#34;:&#34;fail&#34;,&#34;Package&#34;:&#34;json-test&#34;,&#34;Elapsed&#34;:0.001}&#xA;```&#xA;&#xA;Pretty cool right?&#xA;&#xA;This is really useful for programmatically taking the output and parsing it to get the metrics.&#xA;&#xA;&#xA;We can even combine with the coverage flag to get the coverage metrics as well.&#xA;&#xA;```bash&#xA;go test ./... -json -cover&#xA;```&#xA;&#xA;```json&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:13:30.771976961+05:30&#34;,&#34;Action&#34;:&#34;start&#34;,&#34;Package&#34;:&#34;jsontest&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:13:30.775118482+05:30&#34;,&#34;Action&#34;:&#34;run&#34;,&#34;Package&#34;:&#34;jsontest&#34;,&#34;Test&#34;:&#34;TestHello&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:13:30.775172535+05:30&#34;,&#34;Action&#34;:&#34;output&#34;,&#34;Package&#34;:&#34;jsontest&#34;,&#34;Test&#34;:&#34;TestHello&#34;,&#34;Output&#34;:&#34;=== RUN   TestHello\n&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:13:30.775201647+05:30&#34;,&#34;Action&#34;:&#34;output&#34;,&#34;Package&#34;:&#34;jsontest&#34;,&#34;Test&#34;:&#34;TestHello&#34;,&#34;Output&#34;:&#34;    main_test.go:10: got: \&#34;Hello, World!\&#34;\n&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:13:30.775231759+05:30&#34;,&#34;Action&#34;:&#34;output&#34;,&#34;Package&#34;:&#34;jsontest&#34;,&#34;Test&#34;:&#34;TestHello&#34;,&#34;Output&#34;:&#34;--- PASS: TestHello (0.00s)\n&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:13:30.775253928+05:30&#34;,&#34;Action&#34;:&#34;pass&#34;,&#34;Package&#34;:&#34;jsontest&#34;,&#34;Test&#34;:&#34;TestHello&#34;,&#34;Elapsed&#34;:0}&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:13:30.775269402+05:30&#34;,&#34;Action&#34;:&#34;output&#34;,&#34;Package&#34;:&#34;jsontest&#34;,&#34;Output&#34;:&#34;PASS\n&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:13:30.776153185+05:30&#34;,&#34;Action&#34;:&#34;output&#34;,&#34;Package&#34;:&#34;jsontest&#34;,&#34;Output&#34;:&#34;coverage: 100.0% of statements\n&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:13:30.776808599+05:30&#34;,&#34;Action&#34;:&#34;output&#34;,&#34;Package&#34;:&#34;jsontest&#34;,&#34;Output&#34;:&#34;ok  \tjsontest\t0.004s\tcoverage: 100.0% of statements\n&#34;&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:13:30.777814589+05:30&#34;,&#34;Action&#34;:&#34;pass&#34;,&#34;Package&#34;:&#34;jsontest&#34;,&#34;Elapsed&#34;:0.006}&#xA;```&#xA;&#xA;I am planning to use this in my workflow for integrating the output of the tests suite with specific tests.&#xA;&#xA;For running the specific tests, you can use `go test -run TestName` command, this will only run the provided test function.&#xA;&#xA;```go&#xA;// main.go&#xA;&#xA;package jsontest&#xA;&#xA;func hello() string {&#xA;    return &#34;Hello, World!&#34;&#xA;}&#xA;&#xA;func add(x, y int) int {&#xA;    return x + y&#xA;}&#xA;```&#xA;&#xA;```go&#xA;// main_test.go&#xA;package jsontest&#xA;&#xA;import (&#xA;&#x9;&#34;testing&#34;&#xA;)&#xA;&#xA;func TestHello(t *testing.T) {&#xA;    want := &#34;Hello, World!&#34;&#xA;    got := hello()&#xA;    t.Logf(&#34;got: %q&#34;, got)&#xA;    if got != want {&#xA;        t.Errorf(&#34;got: %q, want: %q&#34;, got, want)&#xA;    }&#xA;}&#xA;&#xA;func TestAdd(t *testing.T) {&#xA;    want := 2&#xA;    got := add(1, 1)&#xA;    t.Logf(&#34;got: %d&#34;, got)&#xA;    if got != want {&#xA;        t.Errorf(&#34;got: %d, want: %d&#34;, got, want)&#xA;    }&#xA;}&#xA;```&#xA;&#xA;So, we have two test in this go module, we can run a specific test using `go test -run TestName` command as so:&#xA;&#xA;```bash&#xA;go test -run TestAdd -json&#xA;```&#xA;&#xA;```json&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:33:44.19397581+05:30&#34;,&#34;Action&#34;:&#34;start&#34;,&#34;Package&#34;:&#34;jsontest&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:33:44.198067398+05:30&#34;,&#34;Action&#34;:&#34;run&#34;,&#34;Package&#34;:&#34;jsontest&#34;,&#34;Test&#34;:&#34;TestAdd&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:33:44.198150156+05:30&#34;,&#34;Action&#34;:&#34;output&#34;,&#34;Package&#34;:&#34;jsontest&#34;,&#34;Test&#34;:&#34;TestAdd&#34;,&#34;Output&#34;:&#34;=== RUN   TestAdd\n&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:33:44.198197444+05:30&#34;,&#34;Action&#34;:&#34;output&#34;,&#34;Package&#34;:&#34;jsontest&#34;,&#34;Test&#34;:&#34;TestAdd&#34;,&#34;Output&#34;:&#34;    main_test.go:19: got: 2\n&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:33:44.198217057+05:30&#34;,&#34;Action&#34;:&#34;output&#34;,&#34;Package&#34;:&#34;jsontest&#34;,&#34;Test&#34;:&#34;TestAdd&#34;,&#34;Output&#34;:&#34;--- PASS: TestAdd (0.00s)\n&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:33:44.198230965+05:30&#34;,&#34;Action&#34;:&#34;pass&#34;,&#34;Package&#34;:&#34;jsontest&#34;,&#34;Test&#34;:&#34;TestAdd&#34;,&#34;Elapsed&#34;:0}&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:33:44.198241628+05:30&#34;,&#34;Action&#34;:&#34;output&#34;,&#34;Package&#34;:&#34;jsontest&#34;,&#34;Output&#34;:&#34;PASS\n&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:33:44.19869148+05:30&#34;,&#34;Action&#34;:&#34;output&#34;,&#34;Package&#34;:&#34;jsontest&#34;,&#34;Output&#34;:&#34;ok  \tjsontest\t0.004s\n&#34;}&#xA;{&#34;Time&#34;:&#34;2024-01-01T21:33:44.198822637+05:30&#34;,&#34;Action&#34;:&#34;pass&#34;,&#34;Package&#34;:&#34;jsontest&#34;,&#34;Elapsed&#34;:0.005}&#xA;```&#xA;&#xA;As we can see, there is only one test being executed and the output of the test is in JSON format.&#xA;&#xA;These are really good flags and options to have as they make the output more portable. I will be planning to use this to improve my workflow in testing and developing open source projects and personal projects as well. I am really inspired by the Teej&#39;s video of executing anything in NeoVim.</content>
      <type>til</type>
    </item>
    <item>
      <title>LibSQL: Query a remote Turso database with cURL</title>
      <link>https://www.meetgor.com/til/libsql-query-remote-db</link>
      <description>Querying a libsql database hosted on turso with cURL. Using a remote sqlite-like db with turso api to query data.</description>
      <pubDate>Wed, 15 Nov 2023 00:00:00 UTC</pubDate>
      <content>If you are using a local [libsql](https://turso.tech/libsql) database, it is quite easy to query the database, but for a remote or a database on a hosted cloud platform like [turso](https://turso.tech/), we can use other clients or the api itself to query the data.&#xA;&#xA;We can use the turso cli to get the authentication token for the database and then query the database.&#xA;&#xA;## Turso CLI&#xA;&#xA;Using the [turso-cli](https://docs.turso.tech/reference/turso-cli) to access the turso platform. We will use turso cli to create a libsql database, create authentication tokens, and query the db.&#xA;&#xA;### Create a database (it&#39;s optional, you might already have a database)&#xA;&#xA;```bash&#xA;turso db create&#xA;```&#xA;&#xA;You will get a database on the turso cloud platform with some random interesting name like a passphrase.&#xA;&#xA;Use the command `turso db list` and copy the URL&#xA;&#xA;```graphql&#xA;DB_URL=dbname-orgname.turso.io&#xA;```&#xA;&#xA;### Create an authentication token for a particular database&#xA;&#xA;```bash&#xA;turso db tokens create db_name&#xA;```&#xA;&#xA;Copy the JWT token and this will be used as a authentication token when accessing the remote database in the turso cloud.&#xA;&#xA;```bash&#xA;TOKEN=abcdef.12345.wxyz&#xA;DB_URL=dbname-orgname.turso.io&#xA;```&#xA;&#xA;* Querying the database using curl or other [api clients](https://docs.turso.tech/libsql/client-access)&#xA;    &#xA;&#xA;```bash&#xA;curl -s -H &#34;Authorization: bearer $TOKEN&#34; \&#xA;     -d &#39;{&#34;statements&#34;: [&#34;SELECT name FROM sqlite_master WHERE type=\&#34;table\&#34;;&#34;]}&#39; \&#xA;     $DB_URL&#xA;```&#xA;&#xA;We can use `curl` or any api client tools to send queries to the database hosted on the turso platform. We need to provide the JWT token in the `Authorization` header to connect to that particular database. The request&#39;s body is a JSON string with a list of statements to query the database.&#xA;&#xA;```graphql&#xA;[&#xA;    {&#xA;        &#34;results&#34;:&#xA;            {&#xA;                &#34;columns&#34;: [&#34;name&#34;],&#xA;                &#34;rows&#34;:[&#xA;                    [&#34;libsql_wasm_func_table&#34;], [&#34;_litestream_seq&#34;], [&#34;_litestream_lock&#34;], [&#34;sqlite_sequence&#34;], [&#34;user&#34;]&#xA;                ]&#xA;            }&#xA;     }&#xA;]&#xA;```&#xA;&#xA;The result is a list of key-value pairs as `columns` and `rows` for each of the statements in the body. The columns are a list of column names requested in the query, and the rows are a list of rows where each row is a list of field values from the query.</content>
      <type>til</type>
    </item>
    <item>
      <title>Read a Rss Feed with a URL in Golang</title>
      <link>https://www.meetgor.com/til/golang-read-rss-feed</link>
      <description>Reading Rss Feed with a Rss XML Link/URL in golang using encoding package</description>
      <pubDate>Fri, 11 Nov 2022 00:00:00 UTC</pubDate>
      <content>## Reding Rss Feed&#xA;&#xA;We can use golang&#39;s [encoding/xml](https://pkg.go.dev/encoding/xml) package to read a Rss feed. Though we have to be speicific of what type of structure the Rss feed has, so it is not dynamic but it works really well with structs. I have covered a few nuances of reading XML file in the [config file reading](https://www.meetgor.com/golang-config-file-read/#reading-xml-file) post of the 100 days of golang series.&#xA;&#xA;### Get request to Rss feed&#xA;&#xA;We first need to send a `GET` request to the Rss feed, we can use the [http](https://pkg.go.dev/net/http) package to grab the response.&#xA;&#xA;```go&#xA;package main&#xA;&#xA;import (&#xA;&#x9;&#34;log&#34;&#xA;&#x9;&#34;net/http&#34;&#xA;)&#xA;&#xA;func main() {&#xA;&#xA;&#x9;url := &#34;https://meetgor.com/rss.xml&#34;&#xA;&#x9;response, err := http.Get(url)&#xA;&#xA;&#x9;if err != nil {&#xA;&#x9;&#x9;log.Fatal(err)&#xA;&#x9;}&#xA;&#xA;    log.Println(response.Body)&#xA;&#x9;defer response.Body.Close()&#xA;&#xA;}&#xA;```&#xA;&#xA;So, in the above example, we have used the `net/http` package to send a `GET` request with the [Get](https://pkg.go.dev/net/http#Get) funciton. The function takes in a string as a `URL` and returns either the object as response or an error. If there arose any error, we simply exit out of the program and log the error. If the error is `nil`, we return the response in the `response` variable. This builds up a good foundation for the next step to read the response body and fetching the actual bytes from the response.&#xA;&#xA;### Fetch the content from the Link&#xA;&#xA;Since we have the `response` object, we can use the [io.ReadAll](https://pkg.go.dev/io#ReadAll) function to read the bytes in the response body. The function takes in the [Reader](https://pkg.go.dev/io#Reader) object in this case it is [ReadCloser](https://pkg.go.dev/io#ReadCloser) object as a http object. The function then returns the slice of bytes/int8. The slice then can be interpreted as string or other form data that can be used for parsing the xml from the response.&#xA;&#xA;```go&#xA;package main&#xA;&#xA;import (&#xA;&#x9;&#34;log&#34;&#xA;&#x9;&#34;net/http&#34;&#xA;    &#34;io&#34;&#xA;)&#xA;&#xA;func main() {&#xA;&#xA;&#x9;url := &#34;https://meetgor.com/rss.xml&#34;&#xA;&#x9;response, err := http.Get(url)&#xA;&#xA;&#x9;if err != nil {&#xA;&#x9;&#x9;log.Fatal(err)&#xA;&#x9;}&#xA;&#xA;&#x9;data, err := io.ReadAll(response.Body)&#xA;&#xA;&#x9;if err != nil {&#xA;&#x9;&#x9;log.Fatal(err)&#xA;&#x9;}&#xA;&#xA;    log.Println(string(data))&#xA;    log.Printf(&#34;Type -&gt; %T&#34;, data)&#xA;}&#xA;```&#xA;&#xA;```&#xA;&lt;rss&gt;&#xA;    &lt;channel&gt;&#xA;        &lt;item&gt;&#xA;        ...&#xA;        ...&#xA;        ...&#xA;        &lt;/item&gt;&#xA;    &lt;/channel&gt;&#xA;&lt;/rss&gt;&#xA;&#xA;&#xA;Type -&gt; []uint8 &#xA;&#xA;```&#xA;&#xA;So, we can see that the parsed content is indeed xml, it is type casted to string from the slice of bytes. This can be further used for the parsing the text as Rss structure and fetch the required details.&#xA;&#xA;## Parsing Rss with a struct&#xA;&#xA;We can now move into creating a struct for individual tags required in the parsing.&#xA;&#xA;```go&#xA;package main&#xA;&#xA;import (&#xA;    &#34;encoding/xml&#34;&#xA;&#x9;&#34;io&#34;&#xA;&#x9;&#34;log&#34;&#xA;&#x9;&#34;net/http&#34;&#xA;)&#xA;&#xA;type Rss struct {&#xA;&#x9;XMLName xml.Name `xml:&#34;rss&#34;`&#xA;&#x9;Channel Channel  `xml:&#34;channel&#34;`&#xA;}&#xA;&#xA;type Channel struct {&#xA;&#x9;XMLName     xml.Name `xml:&#34;channel&#34;`&#xA;&#x9;Title       string   `xml:&#34;title&#34;`&#xA;&#x9;Description string   `xml:&#34;description&#34;`&#xA;&#x9;Item        []Item   `xml:&#34;item&#34;`&#xA;}&#xA;&#xA;type Item struct {&#xA;&#x9;XMLName xml.Name `xml:&#34;item&#34;`&#xA;&#x9;Title   string   `xml:&#34;title&#34;`&#xA;&#x9;Link    string   `xml:&#34;link&#34;`&#xA;}&#xA;&#xA;func main() {&#xA;&#xA;&#x9;url := &#34;https://meetgor.com/rss.xml&#34;&#xA;&#x9;response, err := http.Get(url)&#xA;&#xA;&#x9;if err != nil {&#xA;&#x9;&#x9;log.Fatal(err)&#xA;&#x9;}&#xA;&#xA;&#x9;data, err := io.ReadAll(response.Body)&#xA;&#xA;&#x9;if err != nil {&#xA;&#x9;&#x9;log.Fatal(err)&#xA;&#x9;}&#xA;&#xA;    log.Println(string(data))&#xA;}&#xA;```&#xA;&#xA;If you would look at the [rss feed](https://meetgor.com/rss.xml), you can see it has a structure of tags and elements. The `rss` tag is the root tag, followed by `channel` and other types of nested tags speicific for the type of information to be stored like `title` for the title in the feed, `link` for the link to the feed, etc. &#xA;&#xA;So, we create those as structure, the root structure is the `Rss` which we will create with a few attributes like `Channel` and the name of the current tag. In the `Rss` case the name of the tag/element is `rss`, so it is given the `xml.Name` as `xml:&#39;rss&#39;` in backticks indicating the type hint for the field. The next field is the `Channel` which is another type(custom type struct). We have defined `Channel` as a struct just after it that will hold information like the `title`, `description` of the website. We also have the `xml.Name` as `xml:&#34;channel&#34;` which indicates the current struct is representation of `channel` tag in the rss feed. Finally, we also have a custom type struct as `Item`. The `Item` struct has a few attributes like `Title`, `Link` and you can now start to see the pattern, you can customize it as per your requirements and speicifications.&#xA;&#xA;```go&#xA;package main&#xA;&#xA;import (&#xA;    &#34;encoding/xml&#34;&#xA;&#x9;&#34;io&#34;&#xA;&#x9;&#34;log&#34;&#xA;&#x9;&#34;net/http&#34;&#xA;)&#xA;&#xA;type Rss struct {&#xA;&#x9;XMLName xml.Name `xml:&#34;rss&#34;`&#xA;&#x9;Channel Channel  `xml:&#34;channel&#34;`&#xA;}&#xA;&#xA;type Channel struct {&#xA;&#x9;XMLName     xml.Name `xml:&#34;channel&#34;`&#xA;&#x9;Title       string   `xml:&#34;title&#34;`&#xA;&#x9;Description string   `xml:&#34;description&#34;`&#xA;&#x9;Item        []Item   `xml:&#34;item&#34;`&#xA;}&#xA;&#xA;type Item struct {&#xA;&#x9;XMLName xml.Name `xml:&#34;item&#34;`&#xA;&#x9;Title   string   `xml:&#34;title&#34;`&#xA;&#x9;Link    string   `xml:&#34;link&#34;`&#xA;}&#xA;&#xA;func main() {&#xA;&#xA;&#x9;url := &#34;https://meetgor.com/rss.xml&#34;&#xA;&#x9;response, err := http.Get(url)&#xA;&#xA;&#x9;if err != nil {&#xA;&#x9;&#x9;log.Fatal(err)&#xA;&#x9;}&#xA;&#xA;&#x9;data, err := io.ReadAll(response.Body)&#xA;&#xA;&#x9;if err != nil {&#xA;&#x9;&#x9;log.Fatal(err)&#xA;&#x9;}&#xA;&#xA;    // New Code&#xA;&#xA;&#x9;d := Rss{}&#xA;&#x9;err = xml.Unmarshal(data, &amp;d)&#xA;&#xA;&#x9;if err != nil {&#xA;&#x9;&#x9;log.Fatal(err)&#xA;&#x9;}&#xA;&#xA;&#x9;for _, item := range d.Channel.Item {&#xA;&#x9;&#x9;log.Println(item.Title)&#xA;&#x9;}&#xA;}&#xA;```&#xA;&#xA;```&#xA;$ go run main.go&#xA;&#xA;Why and How to make and use Vim as a text editor and customizable IDE&#xA;Setting up Vim for Python&#xA;Setting up Vim for BASH Scripting&#xA;Vim: Keymapping Guide&#xA;...&#xA;...&#xA;...&#xA;Django + HTMX CRUD application&#xA;PGCLI: Postgres from the terminal&#xA;Golang: Closures&#xA;Golang: Interfaces&#xA;Golang: Error Handling&#xA;Golang: Paths&#xA;Golang: File Reading&#xA;Golang: JSON YAML TOML (config) File Reading.&#xA;```&#xA;&#xA;So, here we have initialized the `Rss` struct as empty and then used the [Unmarshal](https://pkg.go.dev/encoding/xml#Unmarshal) method in the `xml` package. The Unmarshal method will parse the data as per the type of either int, float, bool or string, any other type of data will be discarded as interface or struct. We can usually parse any valid type of data into `Unmarshal` method and it generally gives a proper expected outcome.&#xA;&#xA;The Unmarshal method takes in the slice of byte and the second paramter as pointer to a struct or any variable that will store the parsed xml content from the slice of byte. The function just returns the error type, either `nil` in case of no errors, and returns the actual error obejct if there arise any type of error.&#xA;&#xA;So we parse the `data` which is a slice of byte to the funciton and the reference to the `d` object which is a empty `Rss` object. This will get us the data in the `d` object. We can then iterate over the object as per the struct and use the perform operations like type casting or converting types, etc to get your required data back.&#xA;&#xA;In the above example, we simply iterate over the `d.Channel.Item` which is a list of elements of tag `item` in the rss feed. Inside the for loop, we can access the object and simply print or perform any sort of operations. I have simply printed the list of articles with titles. &#xA;&#xA;Links for the code available on the [100 days of golang](https://github.com/Mr-Destructive/100-days-of-golang/blob/main/scripts/files/read/config_files/xml/rss.go) GitHub repository.&#xA;&#xA;So, that&#39;s how we parse an XML feed in golang. Just plug and play if you have a similar type of structure of the Rss XML feed. Happy Coding :)</content>
      <type>til</type>
    </item>
    <item>
      <title>Create a Non-Clustered Index in Django with Postgres as DB</title>
      <link>https://www.meetgor.com/til/django-non-clustered-index-pg</link>
      <description>Understanding how to add a non-clustered index in a postgres database in a django project.</description>
      <pubDate>Thu, 10 Nov 2022 00:00:00 UTC</pubDate>
      <content>## What is a non-clustered index?&#xA;&#xA;A non-clustered index is a seperate structure than an actual table in the database, it stores the non-clustered index key(the column which we want to sort in the table), and a pointer to the actual values based on the index key. So, non-clustered indexes do not change the physical order of the table records, instead it holds a structure that can provide a easier and distinct way to fetch objects based on a particular column as the primary key in the structure.&#xA;&#xA;## How to create a non-clustered index in django&#xA;&#xA;In django, we can use the [db_index](https://docs.djangoproject.com/en/4.1/ref/models/indexes/) property on a field(s) to create a index on the table/model. &#xA;&#xA;### Add the property to the field in the model&#xA;&#xA;Chose a field in which, you want to add a index. It can be a foreign key or any other normal field defined in your model.&#xA;&#xA;We have used the typical blog model, so used in the some of my [TILS](https://www.meetgor.com/tils/) in django, it is just convenient to explain and understand as well. We have a django project named `core` and it has a app `blog` with a model defined below. The model `Article` has a few attributes like `title`, `description`, `content` and `status`.&#xA;&#xA;```python&#xA;from django.db import models&#xA;&#xA;ARTICLE_STATUS = [&#xA;    (&#34;PUBLISHED&#34;, &#34;Published&#34;),&#xA;    (&#34;DRAFT&#34;, &#34;Draft&#34;),&#xA;]&#xA;&#xA;class Article(models.Model):&#xA;    title = models.CharField(max_length=128, db_index=True)&#xA;    description = models.CharField(max_length=512)&#xA;    content = models.TextField()&#xA;    status = models.CharField(max_length=16, choices=ARTICLE_STATUS, default=&#34;DRAFT&#34;)&#xA;&#xA;    def __str__(self):&#xA;        return self.title&#xA;```&#xA;&#xA;So, we have added a `db_index` to the title column in the model as a property. This will be equivalent to creating a index in `SQL` as follows:&#xA;&#xA;```&#xA;$ python manage.py makemigrations&#xA;&#xA;Migrations for &#39;blog&#39;:&#xA;  blog/migrations/0002_alter_article_title.py&#xA;    - Alter field title on article&#xA;```&#xA;&#xA;```&#xA;$ python manage.py migrate&#xA;&#xA;Operations to perform:&#xA;  Apply all migrations: admin, auth, blog, contenttypes, sessions&#xA;Running migrations:&#xA;  Applying blog.0002_alter_article_title... OK&#xA;&#xA;```&#xA;&#xA;Indexes are not standard as in SQL, but each vendor(sqlite, postgres, mysql) have their own flavour of syntax and naunces.&#xA;&#xA;```sql&#xA;CREATE INDEX &#34;blog_article_title_3c514952&#34; ON &#34;blog_article&#34; (&#34;title&#34;);&#xA;&#xA;CREATE INDEX &#34;blog_article_title_3c514952_like&#34; ON &#34;blog_article&#34; (&#34;title&#34; varchar_pattern_ops);&#xA;```&#xA;&#xA;The above index commands are specific to the field, as the title field is a varchar, it has two types of index, it can generate one with simple match and other for `LIKE` comparisons because of string comparison behaviour.&#xA;&#xA;So, we just created a simple index and now if we query the db for a particular `title` which now has its own index for the table `blog_article`. This means, we will be able to fetch queries quickly if we are specifically filtering for `title`.&#xA;&#xA;### Adding some data records&#xA;&#xA;We can add a few data records to test the query from the databse, you can ignore this part as it would be just setting up a django project and adding a few records to the databse. This part won&#39;t make sense for people reading to get the actual stuff done, move to the next part please.&#xA;&#xA;```&#xA;python manage.py createsuperuser&#xA;# Create a super user and run the server&#xA;&#xA;python manage.py runserver&#xA;# Locate to http://127.0.0.1:8000/admin&#xA;# Create some records in the artilce model&#xA;```&#xA;&#xA;So, after creating some records, you should have a simple database and a working django application.&#xA;&#xA;```sql&#xA;SELECT * FROM blog_article;&#xA;```&#xA;```&#xA;blog_test=# SELECT * FROM blog_article;&#xA;&#xA; id |  title   | description |          content          |  status   &#xA;----+----------+-------------+---------------------------+-----------&#xA;  1 | test     | test 1      | test content              | DRAFT&#xA;  2 | testpost | test 2      | test content more content | DRAFT&#xA;  3 | newpost  | test 3      | test nothing              | PUBLISHED&#xA;(3 rows)&#xA;```&#xA;&#xA;## Testing Queries&#xA;&#xA;We can now use SQL queries or django filters to check if we get results by a sequential or an index scan. If we have a filter of `title` we will get the results after performing an `Index Scan` which means, it will look up in the index columns rather than scanning the entire table of records. This is a way **we can test the indexes are working, efficiency is a differnet topic.** We can&#39;t get a idea of performance with this little data and just one connection. A real time database and having multiple conncurrent requests and connections is a good environment to test(don&#39;t do it in a production db :)&#xA;&#xA;&#xA;```sql&#xA;EXPLAIN SELECT * FROM blog_article WHERE description LIKE &#39;test 2&#39;;&#xA;```&#xA;&#xA;```&#xA;blog_test=# EXPLAIN ANALYSE SELECT * FROM blog_article WHERE description LIKE &#39;test&#39;;&#xA;---------------------------------------------------------------------------------------------------------&#xA;&#xA; Seq Scan on blog_article  (cost=0.00..11.00 rows=1 width=880) (actual time=0.180..0.181 rows=0 loops=1)&#xA;   Filter: ((description)::text ~~ &#39;test&#39;::text)&#xA;   Rows Removed by Filter: 3&#xA; Planning Time: 0.189 ms&#xA; Execution Time: 0.217 ms&#xA;(5 rows)&#xA;&#xA;```&#xA;&#xA;The above query selects the records whose `description` is like `test 2`, this performs a `Sequenitial Scan` in the database i.e. iterating over the records one by one of the order of the primary key / id of the records in the table. &#xA;&#xA;```sql&#xA;EXPLAIN SELECT * FROM blog_article WHERE title LIKE &#39;test 2&#39;;&#xA;```&#xA;&#xA;```&#xA;blog_test=# EXPLAIN ANALYSE SELECT * FROM blog_article WHERE title LIKE &#39;test&#39;;&#xA;---------------------------------------------------------------------------------------------------------&#xA;&#xA;Index Scan using blog_article_title_3c514952_like on blog_article  (cost=0.14..8.16 rows=1 width=880) (actual time=0.043..0.048 rows=1 loops=1)&#xA;   Index Cond: ((title)::text = &#39;test&#39;::text)&#xA;   Filter: ((title)::text ~~ &#39;test&#39;::text)&#xA; Planning Time: 0.208 ms&#xA; Execution Time: 0.093 ms&#xA;(5 rows)&#xA;```&#xA;&#xA;In the above query, the select statement has a filter with the title being like `test 2`, and since we have a index for looking for like of title column, the database performs a index scan on that table and fetches the result.&#xA;&#xA;Here are some tradeoffs, the planning is more and the execution time is less, this is quite logical as it would take time to make decision because the database has more options than before creating indexes.&#xA;&#xA;In the query where we filtered the description, the planning time was less as it makes sense there was just one option to go for sequential scan, but it took time to perform the operation as it would scan the entire table one by one.&#xA;&#xA;## Using Django to test queries&#xA;&#xA;We can even use django to filter out the objects in the table. We simply use the `filter` method to check with a particular value.&#xA;&#xA;We can use the shell, to perform some queries. You can use this in your views or viewsets as per your requirements and constraints.&#xA;&#xA;We can even use `explain` to see what the underlying `sql` got executed out from the ORM. The [explain](https://docs.djangoproject.com/en/3.1/ref/models/querysets/#explain) function is similar to the `EXPLAIN ANALYSE` command in the `sql` queries. It gives a bit of context on how the query was executed.&#xA;&#xA;```&#xA;$ python manage.py shell&#xA;```&#xA;&#xA;```python&#xA;&gt;&gt;&gt; from blog.models import Article                                                                &#xA;&gt;&gt;&gt; Article.objects.filter(description=&#39;test 1&#39;)                                                   &#xA;&#xA;&lt;QuerySet [&lt;Article: test&gt;]&gt;                                                                       &#xA;&#xA;&#xA;&gt;&gt;&gt; Article.objects.filter(description=&#39;test 1&#39;).explain()                                         &#xA;&#xA;&#34;Seq Scan on blog_article  (cost=0.00..11.00 rows=1 width=880)\n  Filter: ((description)::text = &#39;t&#xA;est 1&#39;::text)&#34;                                                                                     &#xA;&#xA;&#xA;&gt;&gt;&gt; Article.objects.filter(title=&#39;test&#39;)                                                           &#xA;&#xA;&lt;QuerySet [&lt;Article: test&gt;]&gt;                                                                       &#xA;&#xA;&#xA;&gt;&gt;&gt; Article.objects.filter(title=&#39;test&#39;).explain()                                                 &#xA;&#xA;&#34;Index Scan using blog_article_title_3c514952_like on blog_article  (cost=0.14..8.16 rows=1 width=8&#xA;80)\n  Index Cond: ((title)::text = &#39;test&#39;::text)&#34;                                                 &#xA;&#xA;```&#xA;&#xA;We can use `__contains` for replicating the behaviour of `LIKE` in python/django from SQL. The below example will check if the title has a word `test` in any records of the database.&#xA;&#xA;```&#xA;&gt;&gt;&gt; Article.objects.filter(title__contains=&#39;test&#39;)&#xA;&#xA;&lt;QuerySet [&lt;Article: test&gt;, &lt;Article: testpost&gt;]&gt; &#xA;```&#xA;&#xA;BONUS: We can even get the underlying SQL with the `.query.__str__()` method. &#xA;&#xA;```&#xA;articles = Article.objects.filter(title__contains=&#39;test&#39;)&#xA;&#xA;articles.query.__str__()&#xA;```&#xA;&#xA;```&#xA;&#39;SELECT &#34;blog_article&#34;.&#34;id&#34;, &#34;blog_article&#34;.&#34;title&#34;, &#34;blog_article&#34;.&#34;description&#34;, &#34;blog_article&#34;.&#34;&#xA;content&#34;, &#34;blog_article&#34;.&#34;status&#34; FROM &#34;blog_article&#34; WHERE &#34;blog_article&#34;.&#34;title&#34;::text LIKE %test&#xA;%&#39;&#xA;```&#xA;&#xA;Here, we are able to see that clearly, that the django orm used the `LIKE` clause for comparing the title.&#xA;&#xA;Further readings and references: &#xA;&#xA;- [Indexing in Postgres](https://medium.com/geekculture/indexing-in-postgres-db-4cf502ce1b4e)&#xA;- [Indexing refernece Django docs](https://docs.djangoproject.com/en/4.1/ref/models/indexes/)&#xA;- [Non-Clustered indexing](https://gudevsoc.com/what-is-non-clustered-index-in-sql-with-example/)</content>
      <type>til</type>
    </item>
    <item>
      <title>Django Bulk Update QuerySet objects</title>
      <link>https://www.meetgor.com/til/django-bulk-update-queryset</link>
      <description>Using bulk_update to update multiple objects in one go.</description>
      <pubDate>Mon, 31 Oct 2022 00:00:00 UTC</pubDate>
      <content>Let&#39;s say, I have a lots of objects which I want to update with a particular field or fields. We can use the [bulk_update](https://docs.djangoproject.com/en/4.1/ref/models/querysets/#bulk-update) method with the model name.&#xA;&#xA;```python&#xA;# blog/models.py&#xA;&#xA;from django.db import models&#xA;&#xA;ARTICLE_STATUS = [&#xA;    (&#34;PUBLISHED&#34;, &#34;Published&#34;),&#xA;    (&#34;DRAFT&#34;, &#34;Draft&#34;),&#xA;]&#xA;&#xA;class Article(models.Model):&#xA;    title = models.CharField(max_length=128)&#xA;    description = models.CharField(max_length=512)&#xA;    content = models.TextField()&#xA;    status = models.CharField(max_length=16, choices=ARTICLE_STATUS, default=&#34;DRAFT&#34;)&#xA;&#xA;    def __str__(self):&#xA;        return self.title&#xA;&#xA;```&#xA;&#xA;Let&#39;s say we have a simple model `Article` with a few typical attributes like `title`, `description`, `content`, and `status`. We have the status as a choice field from two options as `Draft` and `Published`. It could be a boolean field, but that looks too gross for a article status.&#xA;&#xA;&#xA;```python&#xA;&#xA;from blog.models import Article&#xA;&#xA;articles = Article.objects.filter(status=&#34;draft&#34;)&#xA;&#xA;for i in range(len(articles)):&#xA;    articles[i].status = &#34;published&#34;&#xA;&#xA;Article.objects.bulk_update(articles, [&#34;status&#34;,])&#xA;&#xA;```&#xA;&#xA;&#xA;In the above code, the `Articles` model is filtered by the status of `draft`. We iterate over the `QuerySet` which will contain the objects of the articles, by setting the object&#39;s properties to the value we want to set. We are jsut setting the value of the property of the object for each object.&#xA;&#xA;This just makes a changes to the `QuerySet`, by using the `bulk_update` method, the two parameters required are the `QuerySet` and the list of `fields` which are to be updated. The function returns the number of objects/records updated.&#xA;&#xA;```python&#xA;&gt;&gt;&gt; from blog.models import Article&#xA;&gt;&gt;&gt; articles = Article.objects.filter(status=&#34;DRAFT&#34;)&#xA;&gt;&gt;&gt; articles&#xA;&lt;QuerySet [&lt;Article: test 1&gt;, &lt;Article: test 3&gt;]&gt;&#xA;&#xA;&gt;&gt;&gt; for i in range(len(articles)):&#xA;...     articles[i].status = &#34;PUBLISHED&#34;&#xA;...&#xA;&gt;&gt;&gt; articles&#xA;&lt;QuerySet [&lt;Article: test 1&gt;, &lt;Article: test 3&gt;]&gt;&#xA;&gt;&gt;&gt;&#xA;&#xA;&gt;&gt;&gt; Article.objects.bulk_update(articles, [&#39;status&#39;,])&#xA;2&#xA;&#xA;&gt;&gt;&gt; Article.obejcts.get(title=&#34;test 1&#34;).status&#xA;&#39;PUBLISHED&#39;&#xA;&#xA;&gt;&gt;&gt; Article.objects.filter(status=&#34;DRAFT&#34;)&#xA;&lt;QuerySet []&gt;&#xA;&gt;&gt;&gt;&#xA;```&#xA;&#xA;As, we can see here there were two obejcts `test 1` and `test 2` objects with the status as `Draft`. By iterating over the queryset and assigning the status of the object to published, the query set was changed and modified locally.&#xA;By using the `bulk_update` method, we parsed the queryset and the list of attributes to be updated into the function. This gives us the number of objects which were updated, in this case `2`. We then look into the article actual record in the database and it has indeed updated to the value we set in this operation.</content>
      <type>til</type>
    </item>
    <item>
      <title>Python Pipreqs: Generate requirements file from the imported packages</title>
      <link>https://www.meetgor.com/til/python-pipreqs</link>
      <description>Exploring the pipreqs package that allows to list all the dependencies or packages which are imported in a python project</description>
      <pubDate>Wed, 14 Sep 2022 00:00:00 UTC</pubDate>
      <content>## Introduction&#xA;&#xA;[Pipreqs](https://pypi.org/project/pipreqs/) is a python package that allows us to list all the pacakges which are imported in a python project. This is a great package for reducing the amount of redundant packages for a project. &#xA;&#xA;## Install pipreqs&#xA;&#xA;You can install pipreqs with one of the many ways with pip, pipx, or any other pacakge management tool. I personally use pipreqs with `pipx` as it remains isolated from the rest of my project dependencies.&#xA;&#xA;### Using simple pip install&#xA;&#xA;We can install with pip by creating a virtual environment or in a existing virtual environment.&#xA;&#xA;```&#xA;pip install virtualenv venv&#xA;source venv/bin/activate&#xA;&#xA;pip install pipreqs&#xA;```&#xA;&#xA;### Using pipx&#xA;&#xA;We can install pipreqs with pipx. [Pipx](https://pypi.org/project/pipx/) is also a python package but used as a tool to install any cli specific tool with the isolated environment.&#xA;&#xA;```&#xA;pipx install pipreqs&#xA;pipx run pipreqs&#xA;```&#xA;&#xA;## Using pipreqs&#xA;&#xA;We need to specify the encoding, which is used for reading the files while capturing the imports from the project.&#xA;&#xA;```&#xA;pipx run pipreqs --encoding=utf-8 .&#xA;```&#xA;&#xA;Additionaly, we can specify the `path` or filename where it will be used to save the imported packages. The `--savepath` option takes in the path to the file where you want to generate the list of the packages to be installed.&#xA;&#xA;```&#xA;pipx run pipreqs --encoding=utf-8 --savepath reqs.txt . &#xA;```&#xA;&#xA;Though this doesn&#39;t guarentee all the requirements for a file, it is really helpful for explicitly used packages in the python project.</content>
      <type>til</type>
    </item>
    <item>
      <title>Django: Get list of all models and associated fields in a django project</title>
      <link>https://www.meetgor.com/til/django-list-models</link>
      <description>Get the list of all the models and associated fields/attributes in a django project or an application</description>
      <pubDate>Tue, 02 Aug 2022 00:00:00 UTC</pubDate>
      <content>## Context&#xA;&#xA;Let&#39;s say we want the list of all the models and associated attributes in all the applications of a django project, we can do that using the [django.apps](https://docs.djangoproject.com/en/4.0/ref/applications/) with apps method. &#xA;&#xA;## Get all the models in a project&#xA;&#xA;To fetch all the models, we can use the [get_models](https://docs.djangoproject.com/en/4.0/ref/applications/#django.apps.AppConfig.get_models) methods, it will return a list of model classes in all the entire project(all applications). We can import all the models in the django project with the command:&#xA; &#xA;```python&#xA;from django.apps import apps&#xA;models = apps.get_models()&#xA;```&#xA;&#xA;```&#xA;[&lt;class &#39;django.contrib.admin.models.LogEntry&#39;&gt;, &lt;class &#39;django.contrib.auth.models.Permission&#39;&gt;, &#xA;&lt;class &#39;django.contrib.auth.models.Group&#39;&gt;, &lt;class &#39;django.contrib.contenttypes.models.ContentType&#39;&gt;,&#xA; &lt;class &#39;django.contrib.sessions.models.Session&#39;&gt;, &lt;class &#39;allauth.account.models.EmailAddress&#39;&gt;, &#xA;&lt;class &#39;allauth.account.models.EmailConfirmation&#39;&gt;, &lt;class &#39;allauth.socialaccount.models.SocialApp&#39;&gt;, &#xA;&lt;class &#39;allauth.socialaccount.models.SocialAccount&#39;&gt;, &lt;class &#39;allauth.socialaccount.models.SocialToken&#39;&gt;, &#xA;&lt;class &#39;user.models.TimeStampedModel&#39;&gt;, &lt;class &#39;user.models.User&#39;&gt;, &lt;class &#39;articles.models.Tags&#39;&gt;,&#xA; &lt;class &#39;articles.models.Series&#39;&gt;, &lt;class &#39;articles.models.Article&#39;&gt;, &lt;class &#39;blog.models.Blog&#39;&gt;]&#xA;```&#xA;&#xA;We are importing the apps and creating a list of the models in our django project. The Django app command will load all the applications in the project, and the [get_models]() method will fetch the associated models. This has resulted in a list of model class objects, we can iterate over them and fetch the required details, we want.&#xA;&#xA;For instance, If I am interested in the name of these models, I can use the `__name__` property to fetch the model&#39;s name. &#xA;&#xA;```python&#xA;from django.apps import apps&#xA;model_list = apps.get_models()&#xA;&#xA;for model in model_list:&#xA;    print(model.__name__)&#xA;```&#xA;&#xA;```&#xA;LogEntry&#xA;Permission&#xA;Group&#xA;ContentType&#xA;Session&#xA;EmailAddress&#xA;EmailConfirmation&#xA;SocialApp&#xA;SocialAccount&#xA;SocialToken&#xA;TimeStampedModel&#xA;User&#xA;Tags&#xA;Series&#xA;Article&#xA;Blog&#xA;&#xA;```&#xA;&#xA;So, from the above example, we can see we have accessed all the model names in our entire django project. &#xA;&#xA;## Access Application name associated with a model&#xA;&#xA;For accessing the name of the application from the model class, we can use the `_meta` attribute followed by the `app_label` property to get the `app_name` associated with the model.&#xA;&#xA;```python&#xA;from django.apps import apps&#xA;model_list = apps.get_models()&#xA;&#xA;for model in model_list:&#xA;    print(f&#34;{model._meta.app_label}  -&gt; {model.__name__}&#34;)&#xA;```&#xA;&#xA;```&#xA;admin  -&gt; LogEntry&#xA;auth  -&gt; Permission&#xA;auth  -&gt; Group&#xA;contenttypes  -&gt; ContentType&#xA;sessions  -&gt; Session&#xA;account  -&gt; EmailAddress&#xA;account  -&gt; EmailConfirmation&#xA;socialaccount  -&gt; SocialApp&#xA;socialaccount  -&gt; SocialAccount&#xA;socialaccount  -&gt; SocialToken&#xA;user  -&gt; TimeStampedModel&#xA;user  -&gt; User&#xA;articles  -&gt; Tags&#xA;articles  -&gt; Series&#xA;articles  -&gt; Article&#xA;blog  -&gt; Blog&#xA;```&#xA;&#xA;In the above example, we can see we have printed all the models with their associated application names. &#xA;&#xA;## Accessing all the attributes associated with a model&#xA; &#xA;To access all the fields/property/attributes associated with a model, we can again use the `_meta` attribute followed by the `get_fields` method.  This method will return a list of field objects. For accessing the name of those attributes/fields, we have to iterate over the list and then further use `name` property.&#xA;&#xA;```python&#xA;from django.apps import apps&#xA;model_list = apps.get_models()&#xA;for model in model_list:&#xA;    print(model.__name__)&#xA;    field_list = model._meta.get_fields()&#xA;    for field in field_list:&#xA;        print(field.name)&#xA;```&#xA;&#xA;```&#xA;LogEntry&#xA;id&#xA;action_time&#xA;user&#xA;content_type&#xA;object_id&#xA;object_repr&#xA;action_flag&#xA;change_message&#xA;Permission&#xA;group&#xA;user&#xA;id&#xA;...&#xA;...&#xA;Blog&#xA;article&#xA;id&#xA;name&#xA;description&#xA;authors&#xA;```&#xA;So, that is how we get all the associated field names in the associated models in our django projects. Also, there are a lot of attributes, we can access with the apps property. The `__dict__.keys()` can be used to get the list of all associated properties or other methods in a class instance.&#xA;&#xA;```&#xA;&gt;&gt;&gt; m[14]._meta.get_fields()[4].__dict__.keys()&#xA;&#xA;dict_keys([&#39;name&#39;, &#39;verbose_name&#39;, &#39;_verbose_name&#39;, &#39;primary_key&#39;, &#39;max_length&#39;, &#39;_unique&#39;, &#39;blank&#39;, &#39;null&#39;, &#39;remote_field&#39;,&#xA; &#39;is_relation&#39;, &#39;default&#39;, &#39;editable&#39;, &#39;serialize&#39;, &#39;unique_for_date&#39;, &#39;unique_for_month&#39;, &#39;unique_for_year&#39;, &#39;choices&#39;, &#xA;&#39;help_text&#39;, &#39;db_index&#39;, &#39;db_column&#39;, &#39;_db_tablespace&#39;, &#39;auto_created&#39;, &#39;creation_counter&#39;, &#39;_validators&#39;, &#39;_error_messages&#39;, &#xA;&#39;error_messages&#39;, &#39;db_collation&#39;, &#39;validators&#39;, &#39;attname&#39;, &#39;column&#39;, &#39;concrete&#39;, &#39;model&#39;])&#xA;```&#xA;In the above example, I am using a list of models and getting the list of all the attributes associated with a field of a model. This can be applied and other properties can be accessed. &#xA;&#xA;## Get Models with a specific app&#xA;&#xA;Let&#39;s say we want all the models associated with a particular application in the project, we can do that by specifying the name of the application.&#xA;&#xA;```python&#xA;from django.apps import apps&#xA;&#xA;app_info = apps.get_app_config(&#39;articles&#39;)&#xA;&#xA;print(app_info.__dict__.keys()&#xA;&#xA;print(app_info.verbose_name)&#xA;&#xA;print(app_info.models)&#xA;&#xA;print(app_info.models[&#39;article&#39;].__dict__.keys())&#xA;```&#xA;&#xA;```&#xA;dict_keys([&#39;name&#39;, &#39;module&#39;, &#39;apps&#39;, &#39;label&#39;, &#39;verbose_name&#39;, &#39;path&#39;, &#39;models_module&#39;, &#39;models&#39;])&#xA;&#xA;&#39;Article&#39;&#xA;&#xA;{&#39;tags&#39;: &lt;class &#39;articles.models.Tags&#39;&gt;, &#39;series&#39;: &lt;class &#39;articles.models.Series&#39;&gt;, &#39;article&#39;: &lt;class &#39;articles.models.Article&#39;&gt;}&#xA;&#xA;dict_keys([&#39;__module__&#39;, &#39;Article_Status&#39;, &#39;__str__&#39;, &#39;get_absolute_url&#39;, &#39;__doc__&#39;, &#39;_meta&#39;, &#39;DoesNotExist&#39;, &#39;MultipleObjectsReturned&#39;, &#39;title&#39;, &#39;description&#39;, &#39;content&#39;, &#39;status&#39;, &#39;get_status_display&#39;, &#39;blog_id&#39;, &#39;blog&#39;, &#39;author_id&#39;, &#39;author&#39;, &#39;timestampedmodel_ptr_id&#39;, &#39;timestampedmodel_ptr&#39;])&#xA;```&#xA;&#xA;So, we can see that we have got the information about the app `articles` in the proejct where we can get the `verbose_name` property to fetch the human-readable format of the article model. Further, we can get all the models associated with the `articles` application. We get back a dict with the model name as the key and the class reference as the value.&#xA;&#xA;We have accessed the `article` model in the `articles` application and fetched all the associated properties or methods in the model.&#xA;&#xA;For further references, you can visit the [django apps documentation](https://docs.djangoproject.com/en/4.0/ref/applications/) to get more relevant methods and properties.</content>
      <type>til</type>
    </item>
    <item>
      <title>Django Blog DevLog: Load Frontmatter data into Template/Model Form Fields</title>
      <link>https://www.meetgor.com/til/django-form-load-frontmatter</link>
      <description>Rendering frontatter from content field into the Template Form field using HTMX and frontmatter libraries</description>
      <pubDate>Mon, 01 Aug 2022 00:00:00 UTC</pubDate>
      <content>## Introduction&#xA;&#xA;I have an Article Form where I load my post into it directly, it might have frontmatter. So what I wish to achieve is when I paste in the content, the frontmatter should be picked up and it should render the form fields like `title`, `description`, and then also remove the frontmatter from the content.&#xA;&#xA;To do that, we will require a model to work with and a form based on that model. We will exclude a few fields from that model so as to process these attributes on the server side. I am working on my Blog project which is a simple Django application.  You can get the source code for the project on the [GitHub repository](https://github.com/mr-destructive/techstructive-blog/).&#xA;&#xA;## Django Project Context&#xA;&#xA;The techstructive-blog is a django project, which has a couple of applications currently, not in a good situation. There are apps like `article`, `blog`, and `user`. This project has templates and static folder in the base directory. The project is deployed on [railway](https://www.railway.app) this is an always under development project, you can check out the [techstructive-blog](https://django-blog.up.railway.app). We can get the bits and pieces of the project details required for understanding what I want to do with the following sections.&#xA;&#xA;### Article Model&#xA;&#xA;We have an `Article` model with attributes like `title`, `description`,  `author` as a Foreign Key to the user model, and a few other attributes which is not related to what we are trying to achieve right now or at least don&#39;t require an explanation. We have a model method called `get_absolute_url` for getting a URL in order to redirect the client when the model instance is created or updated from the backend. You can definitely check out the details of these small components or templates in the project repository. &#xA;&#xA;```python&#xA;# articles/models.py&#xA;&#xA;&#xA;class Article(TimeStampedModel):&#xA;    class Article_Status(models.TextChoices):&#xA;        DRAFT = (&#xA;            &#34;DRAFT&#34;,&#xA;            _(&#34;Draft&#34;),&#xA;        )&#xA;        PUBLISHED = (&#xA;            &#34;PUBLISHED&#34;,&#xA;            _(&#34;Published&#34;),&#xA;        )&#xA;&#xA;    title = models.CharField(max_length=128)&#xA;    description = models.CharField(max_length=256)&#xA;    content = models.TextField(default=&#34;&#34;, null=False, blank=False)&#xA;    status = models.CharField(&#xA;        max_length=16,&#xA;        choices=Article_Status.choices,&#xA;        default=Article_Status.DRAFT,&#xA;    )&#xA;    blog = models.ForeignKey(Blog, on_delete=models.CASCADE, null=True, blank=True)&#xA;    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name=&#34;author&#34;)&#xA;&#xA;    def __str__(self):&#xA;        return self.title&#xA;&#xA;    def get_absolute_url(self):      &#xA;        return reverse(&#39;articles:article-detail&#39;, args=[str(self.id)])&#xA;```&#xA;&#xA;In the below snippet, we have the forms defined in the article application for creating or updating of article instance.  We will be using model forms as our form data should contain fields related to a model in this case the `Article` model. So when we inherit the `forms.ModelForm` in our custom `ArticleForm` we simply need to specify the model and it will take in all the attributes of that model by default, but if we specify the `fields` or `exclude` tuples, it will include only or exclude only the provided list of attributes from the model. &#xA;&#xA;We have also added the widgets for the form fields which will allow us to customize the way the fields in the template/form will render. We can specify the HTML attributes like `width`, `height`, `style`, etc.  &#xA;&#xA;### Article Form&#xA;&#xA;```python&#xA;# article/forms.py&#xA;&#xA;&#xA;from django import forms&#xA;from .models import Article&#xA;&#xA;&#xA;class ArticleForm(forms.ModelForm):&#xA;    class Meta:&#xA;        model = Article&#xA;        exclude = (&#xA;            &#34;created&#34;,&#xA;            &#34;updated&#34;,&#xA;            &#34;author&#34;,&#xA;        )&#xA;        widgets = {&#xA;            &#34;title&#34;: forms.TextInput(&#xA;                attrs={&#xA;                    &#34;class&#34;: &#34;form-control&#34;,&#xA;                    &#34;style&#34;: &#34;max-width: 450px; align: center;&#34;,&#xA;                    &#34;placeholder&#34;: &#34;Title&#34;,&#xA;                }&#xA;            ),&#xA;            &#34;description&#34;: forms.TextInput(&#xA;                attrs={&#xA;                    &#34;class&#34;: &#34;form-control&#34;,&#xA;                    &#34;style&#34;: &#34;max-width: 900px; &#34;,&#xA;                    &#34;placeholder&#34;: &#34;Description&#34;,&#xA;                }&#xA;            ),&#xA;            &#34;content&#34;: forms.Textarea(&#xA;                attrs={&#xA;                    &#34;class&#34;: &#34;form-control post-body&#34;,&#xA;                    &#34;id&#34;: &#34;text-content&#34;,&#xA;                    &#34;style&#34;: &#34;max-width:900px;&#34;,&#xA;                    &#34;hx-post&#34;: &#34;/article/meta/&#34;,&#xA;                    &#34;placeholder&#34;: &#34;Content&#34;,&#xA;                }&#xA;            ),&#xA;            &#34;blog&#34;: forms.Select(&#xA;                attrs={&#xA;                    &#34;class&#34;: &#34;form-control&#34;,&#xA;                    &#34;placeholder&#34;: &#34;Blog Publication&#34;,&#xA;                }&#xA;            ),&#xA;        }&#xA;&#xA;```&#xA;&#xA;So, these are my models and form files in the article app. Using htmx and without any javascript I want to update the form so that it picks up the front matter in the content field which is a text area and fills the title, description other attributes automatically for me. &#xA;&#xA;This can be done in a lot of ways, but I will be sharing one of the ways that I recently used in my blog project. This process involves creating a class-based view and adding a `POST` method that won&#39;t post any data to the backend but will send necessary data to the view.&#xA;&#xA;&#xA;Let&#39;s see the process before diving into any of the code:&#xA;&#xA;## Gist of the Process&#xA;&#xA;- Attach a `hx-post` attribute to the form field for sending the request to a view&#xA;- When the request is sent, the data is loaded with `request.POST`, it is cleaned and converted in python-readable format with json.&#xA;- Once we have the data, we try to use the `frontmatter.loads` function that will load the content and if we have a frontmatter in the text, it will load it as a `frontmatter.POST` object.&#xA;- We will extract `title`, `description`, and other data fields from the object.&#xA;- We will initialize a Form instance of Article, with the initial data values as the extracted data from the frontmatter.&#xA;- Now we have two options:&#xA;    - If the article instance already exists i.e. we are updating the article&#xA;   - Else we are creating a new article&#xA;&#xA;Accordingly, we will load the form in the respective templates i.e. `update.html` for updating the existing articles and `article-form.html` for a new article.&#xA;&#xA;## Adding HTMX Magic&#xA;&#xA;If you&#39;d have seen we have a `hx-post` attribute in the `article/forms.py` file, the `content` widget has a `hx-post` attribute which sends a post request to the `article/meta/` URL route. This route we will bind to the `ArticleMetaView` which we will define in a few moments. This is usually sent once we change a certain text in the content field, so we can modify it as per your requirement with `hx-trigger` that can enable us to specify the trigger event or the type of trigger we want. Further, you can read from the [htmx docs](https://htmx.org/docs/#trigger-modifiers) about these triggers and other attributes. &#xA;&#xA;```python&#xA;# article/urls.py&#xA;&#xA;from django.urls import path&#xA;from . import views&#xA;&#xA;app_name = &#34;articles&#34;&#xA;&#xA;urlpatterns = [&#xA;    path(&#34;&#34;, views.ArticleCreateView.as_view(), name=&#34;article-create&#34;),&#xA;    path(&#34;&lt;int:pk&gt;/&#34;, views.ArticleDetailView.as_view(), name=&#34;article-detail&#34;),&#xA;    path(&#34;delete/&lt;int:pk&gt;/&#34;, views.ArticleDetailView.as_view(), name=&#34;article-delete&#34;),&#xA;    path(&#34;edit/&lt;int:pk&gt;&#34;, views.ArticleDetailView.as_view(), name=&#34;article-update&#34;),&#xA;&#xA;    # the new view that we will create&#xA;    path(&#34;meta/&#34;, views.ArticleMetaView.as_view(), name=&#34;article-meta&#34;),&#xA;]&#xA;```&#xA;&#xA;## Capture Frontmatter Meta-data View &#xA;&#xA;Along with the Create, Detail/List, Update, Delete View, I will create a separate class called `ArticleMetaView` that will fetch the form fields and render the templates again but this time it will fill in the frontmatter meta-data in the fields if the content is parsed with the relvant frontmatter.&#xA;&#xA;```python&#xA;# articles/view.py&#xA;&#xA;class ArticleMetaView(View):&#xA;    model = Article&#xA;&#xA;    def post(self, request, *args, **kwargs):&#xA;        &#xA;        data = json.loads(json.dumps(dict(request.POST)))&#xA;        loaded_frontmatter = frontmatter.loads(data[&#39;content&#39;][0])&#xA;&#xA;       # frontmatter has keys i.e. attributes like title, description, etc.&#xA;        if dict(loaded_frontmatter):&#xA;            article_title = loaded_frontmatter[&#39;title&#39;]&#xA;            article_description = loaded_frontmatter[&#39;description&#39;]&#xA;            form = ArticleForm(initial={&#39;title&#39;: article_title, &#xA;            &#39;description&#39;: article_description, &#39;content&#39;: loaded_frontmatter.content})&#xA;            context = {&#39;form&#39;: form}&#xA;            article_list = Article.objects.filter(title=article_title)&#xA;            if article_list:&#xA;                article = article_list.last()&#xA;                context[&#39;article&#39;] = article&#xA;                return render(request, &#39;articles/edit_article.html&#39;, context)&#xA;            return render(request, &#39;articles/article_form.html&#39;, context)&#xA;&#xA;        article_list = Article.objects.filter(title=data[&#39;title&#39;][0])&#xA;       &#xA;       # if the article title has been already taken i.e. we are updating an article&#xA;&#xA;        if article_list:&#xA;            article = article_list.last()&#xA;            form = ArticleForm(data=request.POST)&#xA;            context = {&#39;form&#39;: form}&#xA;            context[&#39;article&#39;] = article&#xA;            return render(request, &#39;articles/edit_article.html&#39;, context)&#xA;&#xA;        form = ArticleForm(data=request.POST)&#xA;        context = {&#39;form&#39;: form}&#xA;        return render(request, &#39;articles/article_form.html&#39;, context)&#xA;&#xA;```&#xA;&#xA;In the above `ArticleMetaView` we have created a `post` method as we want to get hold of the content from the form. So, we start by extracting and converting the `request.body` data into an appropriate type for easily working with python. So, the `request.body` will contain the data like `csrf_token`, `form_data`, etc. received from the frontend template. We store the received data as `data` and now from this data, we can load the content field which will have the content information.&#xA;&#xA;Firstly we will extract the `request.body` which will contain the data from the form as we have made a `POST` request to this endpoint. For doing that we need to parse the content in a apropriate format such that it is python friendly. So we wrap the `request.body` into json format and then decode it back into the json string. This will give us the dict of the request data.&#xA;&#xA;```python&#xA;data = json.loads(json.dumps(dict(request.POST)))&#xA;```&#xA;&#xA;```&#xA;{&#39;csrfmiddlewaretoken&#39;: [&#39;bSYJxD39XH509tD1tZGd0WU21PUaKaLeqjjGbyzRvLXF4P8iIxb5l0fmTWVFjELQ&#39;], &#39;title&#39;: [&#39;test2&#39;], &#39;description&#39;: [&#39;test&#39;], &#39;content&#39;: [&#39;test something&#39;], &#39;status&#39;: [&#39;DRAFT&#39;], &#39;blog&#39;: [&#39;&#39;]}&#xA;```&#xA;&#xA;So, this will grab the request data as a dict, we can then extract the data from this as it has data from the Form fields. We are interested in the content field in the Form, so we can get it by specifying the key `content` from the extracted data. But as we can see the data doesn&#39;t contain the actual data instead it is wrapped in a list i.e. `[&#39;test something&#39;]`, so we will have to index it and then fetch it.&#xA;&#xA;```python&#xA;content_string = data[&#39;content&#39;][0]&#xA;```&#xA;&#xA;This will give us the exact content field as a string. So, we can now move into extracting the frontmatter from the fields. &#xA;&#xA;Now, we can use the [frontmatter](https://python-frontmatter.readthedocs.io/en/latest/index.html) library to parse the content into the [loads](https://python-frontmatter.readthedocs.io/en/latest/api.html#frontmatter.loads) funciton and extract the frontmatter if it is present in the content field. The frontmatter library has a `loads` function which takes in a string and can give out a [frontmatter.Post](https://python-frontmatter.readthedocs.io/en/latest/api.html#post-objects) object. The loads function is differnet from the [load](https://python-frontmatter.readthedocs.io/en/latest/api.html#frontmatter.load) function as the load frunciton is for reading data from a stream of bytes i.e. a file or othe related byte object. The differnece is subtle but it took a read at the [documentation](https://python-frontmatter.readthedocs.io/en/latest/api.html#module-frontmatter).&#xA;&#xA;```python&#xA;post = data[&#39;content&#39;][0]&#xA;loaded_frontmatter = frontmatter.loads(post)&#xA;```&#xA;&#xA;This wil load the content and give us a `frontmatter.Post` as said earlier. This will contain a dict with all the frontmatter if it has any and will by default parse the non-frontmatter data i.e. the remaining text into the `content` key. We need a chack if the Form field had any fronmatter this can be checked by the `dict(loaded_frontmatter)` which will return None if it cannot load the frontmatter.&#xA;&#xA;```python&#xA;loaded_frontmatter = frontmatter.loads(data[&#39;content&#39;][0])&#xA;if dict(loaded_frontmatter):&#xA;  print(loaded_frontmatter.keys())&#xA;```&#xA;&#xA;```&#xA;dict_keys([&#39;templateKey&#39;, &#39;title&#39;, &#39;description&#39;, &#39;date&#39;, &#39;status&#39;])&#xA;```&#xA;&#xA;So once we have the frontmatter loaded we can get specific keys from it and initialize the form vaues to them. But we have made clear distictions that we want to perform a specific task if we have frontmatter keys in the content field of the Form else we can do something else.&#xA;&#xA;First let&#39;s handle the loading of the frontmatter into the form. For doing that we will get all the required attributes from the frontmatter like `title`, `description`, `content`, etc which can be accessed normally as we extract the value from a key in a dict.&#xA;&#xA;Once we have got those keys, we can start filling in the Form data with initial values. The [Django Model form](https://docs.djangoproject.com/en/4.0/topics/forms/modelforms/) takes in a parameter like [initial](https://docs.djangoproject.com/en/4.0/topics/forms/modelforms/#providing-initial-values) which can be a dict of the fiields along with the value that can be used for rendering the form initially when we load the template.&#xA;&#xA;```python&#xA;article_title = loaded_frontmatter[&#39;title&#39;]&#xA;article_description = loaded_frontmatter[&#39;description&#39;]&#xA;&#xA;form = ArticleForm(initial={&#39;title&#39;: article_title, &#39;description&#39;: article_description, &#39;content&#39;: loaded_frontmatter.content})&#xA;```&#xA;&#xA;This will take in a `ArticleForm` and fill the initial values like `title`, `description`, etc which we have provided in the dict with the values. Now, we need to parse this form in the current template or re-render the template. But before that, we need to parse this context into the template. We will create a dict with `form` as the key which can be used to render in the template.&#xA;&#xA;Also, we have a two ways here, either the user is creating a new article or it is updating a existing article. We need to make sure that we preserve the initial fields in the form as we are updating the existing article. So, we can filter the article objects as per the title of the current title and then if we find a article with that title, we will parse the context with that article object.&#xA;&#xA;```python&#xA;article_list = Article.objects.filter(title=article_title)&#xA;if article_list:&#xA;    article = article_list.last()&#xA;    context{&#xA;      &#39;form&#39;: form,&#xA;      &#39;article&#39;: article&#xA;    }&#xA;    return render(request, &#39;articles/edit_article.html&#39;, context)&#xA;context = {&#39;form&#39;: form}&#xA;return render(request, &#39;articles/article_form.html&#39;, context)&#xA;```&#xA;&#xA;Now, we have form data along with the article instance used for rendering the form with appropriate content. So, this will work for editing an already existing article. For a new article, we have to simply parse the form to the template and it will render the title picked from the fotnmatter or leave it empty.&#xA;&#xA;Similarly, for the article with no frontmatter we will iterate over the article and if the article&#39;s title already exist, we will render the article data with the form else render the form with the parsed title and other meta-data in the form.&#xA;&#xA;&#xA;&lt;video width=&#34;800&#34; height=&#34;450&#34; controls&gt;&#xA;  &lt;source src=&#34;https://res.cloudinary.com/techstructive-blog/video/upload/v1659370006/blog-media/frontmatter-load-htmx.mp4&#34; type=&#34;video/mp4&#34;&gt;&#xA;&lt;/video&gt;&#xA;&#xA;So that is how we render the form data with frontmatter into appropriate meta-data in the form. We have used Django forms and make use of HTMX for the dynamic updation of form.</content>
      <type>til</type>
    </item>
    <item>
      <title>Map Vimscript Keymaps to Lua with a single function</title>
      <link>https://www.meetgor.com/til/vimscript-to-lua-keymapper</link>
      <description>Takeout the vimscript keymaps into lua with a single function call in Neovim</description>
      <pubDate>Mon, 11 Jul 2022 00:00:00 UTC</pubDate>
      <content>## Introduction&#xA;&#xA;Are you bored of writing all the keymaps from vimscript to lua? Try the below function to create all your keymaps to lua equivalent maps in Neovim.&#xA;&#xA;Take your vimscript keymaps and put them in lua don&#39;t write any lua for it ;)&#xA;&#xA;## The Lua Function&#xA;&#xA;The below-provided snippet is a lua function that takes in a table of strings(list of strings), the strings will be your keymaps. The function then maps these keymaps using lua functions. You don&#39;t have to type out all the keymaps by yourself. It can also print out the lua equivalent function calls required to map the existing keymaps from vimscript to lua runtime in Neovim. Though it won&#39;t handle all the options, we have passed in a default value to the keymap.&#xA;&#xA;```lua&#xA;function key_mapper(keymaps)&#xA;  for _, keymap in ipairs(keymaps) do&#xA;    local mode = keymap:sub(1,1)&#xA;    local delimiter = &#34; &#34;&#xA;    local lhs = &#39;&#39;&#xA;    local rhs_parts = {}&#xA;    local m = 0&#xA;    local options = {noremap = true}&#xA;    for matches in (keymap..delimiter):gmatch(&#34;(.-)&#34;..delimiter) do&#xA;      if m == 1 then&#xA;        lhs = matches&#xA;      end&#xA;      if m &gt;= 2 then&#xA;        table.insert(rhs_parts, matches)&#xA;      end&#xA;      m = m + 1&#xA;    end&#xA;    rhs = &#39;&#39;&#xA;    for _, p in ipairs(rhs_parts) do&#xA;      rhs = rhs .. &#34; &#34; .. p&#xA;    end&#xA;    --print(&#34;vim.keymap.set(&#34;..&#34;\&#39;&#34;..mode..&#34;\&#39;&#34;..&#34;, &#34;..&#34;\&#39;&#34;..lhs..&#34;\&#39;&#34;..&#34;, &#34;..&#34;\&#39;&#34;..rhs..&#34;\&#39;&#34;..&#34;, &#34;..vim.inspect(options)..&#34;)&#34;)&#xA;    vim.keymap.set(mode, lhs, rhs, options)&#xA;  end&#xA;end&#xA;```&#xA;&#xA;You can uncomment the print statement **once** to grab the keymaps and paste them into the config file. If you leave it uncommented, it might print every time you open up a new neovim instance. The function can be called like below:&#xA;&#xA;```lua&#xA;key_mapper({&#xA;  &#39;nnoremap cpp :!c++ % -o %:r &amp;&amp; %:r&lt;CR&gt;i&#39;,&#xA;  &#39;nnoremap c, :!gcc % -o %:r &amp;&amp; %:r&lt;CR&gt;&#39;,&#xA;  &#39;nnoremap py :!python %&lt;cr&gt;&#39;,&#xA;  &#39;nnoremap go :!go run %&lt;cr&gt;&#39;,&#xA;  &#39;nnoremap sh :!bash %&lt;CR&gt;&#39;&#xA;})&#xA;```&#xA;&#xA;![Keymapper demonstration](https://res.cloudinary.com/techstructive-blog/image/upload/v1657559501/blog-media/neovim-lua-keymapper.gif)&#xA;&#xA;We pass in a table of strings, these strings are just the vimscript keymaps. This function call will then map the keymaps into equivalent lua maps. You can customize it as per your needs.&#xA;&#xA;For further references, you can check out my [dotfiles](https://github.com/Mr-Destructive/dotfiles) on GitHub.&#xA;&#xA;## How the function works&#xA;&#xA;The function is simply a text scrapping from lua strings. We extract the first character in the string for the mode, grab the strings which are space-separated and finally sort out which are lhs and rhs sides of the maps.&#xA;&#xA;We iterate over the table in lua with the help of ipairs function which allows us to iterate over an ordered list of items in a table. Using the gmatch function, we find a pattern to split the string with the space as the delimiter. Thereby, we can have separate sets of strings identified as rhs and lhs. We can store them in variables as strings as the lua functions require them as strings.&#xA;&#xA;We simply add those variables into the [vim.keymap.set](https://neovim.io/doc/user/lua.html#:~:text=set(%7Bmode%7D%2C%20%7Blhs%7D%2C%20%7Brhs%7D%2C%20%7Bopts%7D)%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*vim.keymap.set()*) or [vim.api.nvim_set_keymap](https://neovim.io/doc/user/api.html#nvim_set_keymap():~:text=nvim_set_keymap(%7Bmode%7D%2C%20%7Blhs%7D%2C%20%7Brhs%7D%2C%20%7B*opts%7D)%20%20%20%20%20%20%20%20%20%20%20%20%20*nvim_set_keymap()*) functions. We by default set the value of `{noremap: True}` to avoid teh recursive mapping of the keys. These option parameter is the one which needs to be a bit more dynamic in terms of wide variety of keymaps.&#xA;&#xA;So, this is how we can convert the vimscript keymaps to lua in Neovim. Hope you found this useful. Thanks for reading. Happy Viming :)</content>
      <type>til</type>
    </item>
    <item>
      <title>Django App from Scratch Using Docker with Debian Base Image</title>
      <link>https://www.meetgor.com/til/django-app-from-scratch</link>
      <description>Creating a django basic application with configuration for static files, templates and user authentication using docker and debian base image.</description>
      <pubDate>Tue, 24 May 2022 00:00:00 UTC</pubDate>
      <content>## Pull a Fresh Debian Image&#xA;&#xA;Create a docker container from a Debian image, the following command can be used to pull a debain 11-slim image and create a container of it, also enter into the container in a interactive environment `-it` mode. &#xA;&#xA;```&#xA;docker run -v $(pwd):/var/www --rm -it -p 8001:80 debian:11-slim&#xA;```&#xA;&#xA;## Create a Django App from Shell script&#xA;&#xA;Now, since we are inside a Debian container, we can enter a few commands, you can refer to the Mark Gibney&#39;s [GitHub repository](https://github.com/no-gravity/web_app_from_scratch) for the script.&#xA;&#xA;```&#xA;apt update&#xA;&#xA;apt install wget&#xA;&#xA;wget https://raw.githubusercontent.com/no-gravity/web_app_from_scratch/main/django.sh&#xA;```&#xA;&#xA;Also, if you want to do a few adjustments, you can install an editor, get used to vim or use nano.&#xA;&#xA;```&#xA;apt install vim &#xA;&#xA;OR&#xA;&#xA;apt install nano&#xA;```&#xA;&#xA;```&#xA;chmod +x django.sh&#xA;bash django.sh&#xA;```&#xA;&#xA;I also have a few adjustment of the original script, that accepts a project name and creates a django project based on the positional parameter given to it. You can get it from the [quick-setup-script repository](https://github.com/Mr-Destructive/quick-setup-scripts/blob/main/django_docker.sh) or directly the [script](https://raw.githubusercontent.com/Mr-Destructive/quick-setup-scripts/main/django_docker.sh).&#xA;&#xA;To use the above file, you need to execute the command as :&#xA;&#xA;```&#xA;chmod +x django_docker.sh&#xA;bash django_docker.sh &lt;project_name&gt;&#xA;```&#xA;&#xA;This will generate the project in the `/var/www/` folder with the name of the project. The script will prompt you with a few things for setting up at some iterations like basic application setup , `static file` configuration, `basic tempalte` setup and the `user authentication` setup.&#xA;&#xA;## Copy the contents from the docker container&#xA;&#xA;You can copy the contents of the folder into your local machine by entering the [cp](https://docs.docker.com/engine/reference/commandline/cp/) command in docker. &#xA;&#xA;```&#xA;docker cp &lt;container_id&gt;:/var/www/&lt;project_name&gt; /path/in_local_machine/&#xA;```&#xA;&#xA;This will copy the project in the docker container into the local machine for you to extend and tweak it as per your needs.&#xA;&#xA;That&#39;s a basic Django Project Setup by using Docker with a Debian Image.</content>
      <type>til</type>
    </item>
    <item>
      <title>Autoformat Python file with Black after saving in Vim</title>
      <link>https://www.meetgor.com/til/vim-python-black-autoformat</link>
      <description>Automatically format python code in the current file after saving the file in Vim.</description>
      <pubDate>Tue, 29 Mar 2022 00:00:00 UTC</pubDate>
      <content>If you are like me who writes Python very badly, it has empty lines with whitespaces, no proper format in assigning variables, not formatted according to [PEP 8](https://peps.python.org/pep-0008/) standards, and you use Vim as your text editor then my friend you need a autocmd badly for it.&#xA;&#xA;## Install Black in Python&#xA;&#xA;Install the [black](https://pypi.org/project/black/) package in python globally or locally as per your preferences.&#xA;&#xA;```&#xA;pip install black&#xA;```&#xA;&#xA;OR with pipx&#xA;&#xA;```&#xA;pipx install black&#xA;```&#xA;&#xA;For a detailed guide about running packages with pipx head toward my article on [pipx](https://mr-destructive.github.io/techstructive-blog/pipx-intro/).&#xA;&#xA;## Set up Autocmd in Vim&#xA;&#xA;We can set up a autocmd. What is a autocmd? It is about running commands when certain events occur like running a command when a file is saved, a buffer is opened or closed, and so on. What we want is to run the black command from the shell when the current file is saved. &#xA;&#xA;So, we can create a autocmd as follows:&#xA;&#xA;```vimscript&#xA;autocmd BufWritePost * !black %&#xA;```&#xA;&#xA;Now, this will run when any type of file is saved, so we will make it specific to python by adding a `*.py` to add in the autocmd.&#xA;&#xA;```vimscript&#xA;autocmd BufWritePost *.py !black %&#xA;```&#xA;&#xA;This works, but it gives a prompt after the command has been executed, to run the command silently we can simply add the silent keyword before the execution of the command from the shell.&#xA;&#xA;```vimscript&#xA;autocmd BufWritePost *.py silent !black %&#xA;```&#xA;&#xA;This looks perfect! &#xA;&#xA;But still, we need to add a auto-group(`augroup`) that groups the autocmds and by adding `autocmd!` it will clear all the commands from the group. &#xA;&#xA;```vimscript&#xA;augroup python_format&#xA;    autocmd!&#xA;    autocmd BufWritePost *.py silent !black %&#xA;augroup end&#xA;```&#xA;We can now add it to the vimrc to work all the time.&#xA;&#xA;## Using pipx &#xA;&#xA;If you have used pipx to install black, you need to setup the autocmd a bit differently. &#xA;&#xA;```vimscript&#xA;autocmd BufWritePost *.py silent !pipx run black %&#xA;```&#xA;&#xA;It might be a bit slower than running with global installation, but it is a neat way to run python package. &#xA;&#xA;So, that&#39;s it we can now write clean and safe python code without breaking a sweat in Vim. Happy Coding :)</content>
      <type>til</type>
    </item>
    <item>
      <title>Python: Search and Replace in File</title>
      <link>https://www.meetgor.com/til/python-search-replace-file</link>
      <description>Searching and Replacing the text in a File Using simple python semantics, we can perform search and replace in a file. Firstly, we will define the file name, al</description>
      <pubDate>Mon, 28 Mar 2022 00:00:00 UTC</pubDate>
      <content>## Searching and Replacing the text in a File&#xA;&#xA;Using simple python semantics, we can perform search and replace in a file. Firstly, we will define the file name, along with the words to search and replace. After defining the sets of variables, we will open the file in `r+` mode i.e. we can perform read as well as write operations in the file.&#xA;&#xA;We will store the entire file contents using the [read](https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files) function, the contents of file are now stored in the form of a string. We further can set the position of the cursor or the current position in the file using the [seek](https://python-reference.readthedocs.io/en/latest/docs/file/seek.html) function. The seek function takes in a optional parameter as the position to set for reading/writing of file. Using the [truncate](https://python-reference.readthedocs.io/en/latest/docs/file/truncate.html) function, we can clear all the contents of the file.&#xA;&#xA;Finally, we generate the content by replacing the words i.e. the old word with the new word from the string which we store the contents. After replacing the content in the string, we write the string variable into the file and hence the substitution was performed in the text file.&#xA;&#xA;```python&#xA;file_name = &#39;temp.txt&#39;&#xA;old_text = &#39;foo&#39;&#xA;new_text = &#39;python&#39;&#xA;&#xA;with open(file_name, &#34;r+&#34;) as fname:&#xA;    lines = fname.read()&#xA;    fname.seek(0)&#xA;    fname.truncate(0)&#xA;    subs = lines.replace(old_text, new_text)&#xA;    fname.write(subs)&#xA;```&#xA;&#xA;![Python Search Replace in File](https://res.cloudinary.com/techstructive-blog/image/upload/v1648479344/blog-media/cstvfdlazyfriwvnilju.png)</content>
      <type>til</type>
    </item>
    <item>
      <title>Vim: Get the Text from Visual Selection</title>
      <link>https://www.meetgor.com/til/vim-get-visual-text</link>
      <description>Using Registers We can get the selected text in a variable in Vim Script using registers. Lets break down the command Here, we are entering normal mode and sele</description>
      <pubDate>Sat, 05 Mar 2022 00:00:00 UTC</pubDate>
      <content>## Using Registers &#xA;&#xA;We can get the selected text in a variable in Vim Script using registers. &#xA;&#xA;```vimscript&#xA;normal gv&#34;xy&#xA;let context = getreg(&#34;x&#34;)&#xA;```&#xA;&#xA;Lets break down the command&#xA;&#xA;```&#xA;normal mode -&gt; gv -&gt; (y)ank text -&gt; to the &#34;x&#34; register&#xA;               |                  |&#xA;               |               Copy the contents into x register(or any register you like)    &#xA;               |                  &#xA;            Select the previously selected text   &#xA;```&#xA;&#xA;Here, we are entering normal mode and selecting text which was previously selected and yank the contents into a register in this case we are using (x) register, it can be any register. &#xA;Now to get the contents of that register we can use the function `getreg(&#34;register_name&#34;)` or use `&#34;xp&#34;` to paste the contents of the `x` register or more generally for any register(`&#34;&lt;register-name&gt;p`). &#xA;&#xA;Hence we can store the contents of the selected text in a variable for further processing or manipulation.&#xA;&#xA;To quickly test this snippet from command mode, you can try the following steps:&#xA;&#xA;Select a text and press Escape, we just want the `gv` command to refresh and get it&#39;s contents to the latest visual selection.&#xA;&#xA;```vimscript&#xA;:normal! gv&#34;xy&#xA;```&#xA;&#xA;```vimscript&#xA;:let foo = getreg(&#34;x&#34;)&#xA;```&#xA;&#xA;```vimscript&#xA;:echo foo&#xA;```&#xA;&#xA;The echo command will simply print the text which we have selected in the file. &#xA;&#xA;![Visual Select Text](https://res.cloudinary.com/techstructive-blog/image/upload/v1646483173/blog-media/wlrxgtmegtycilyhvyiz.gif)</content>
      <type>til</type>
    </item>
    <item>
      <title>Dockerize a Django project</title>
      <link>https://www.meetgor.com/til/dockerize-django-prj</link>
      <description>Dockerize a Django project We can run our Django projects in a Docker Container by creating a Docker image for our project. It is really easy and intuitive to c</description>
      <pubDate>Wed, 02 Mar 2022 00:00:00 UTC</pubDate>
      <content>## Dockerize a Django project&#xA;&#xA;We can run our Django projects in a Docker Container by creating a Docker image for our project. It is really easy and intuitive to create a Dockerfile for any given application as it really is a matter of writing commands in a file and basically running it is a isolated environment. To create a Docker image, we first need a Dockerfile. A Dockerfile is simply a Blueprint to create a image in Docker. In this file we specify the instructions/commands/environment variables to create a image for our app to run. &#xA;&#xA;### Create a Docker File&#xA;&#xA;To create a dockerfile, simply create a file named as `Dockerfile` without any extension(not a .txt file). We need to then add the following code into the file. &#xA;&#xA;```dockerfile&#xA;FROM python:3.9-buster&#xA;&#xA;ENV PYTHONUNBUFFERED=1&#xA;&#xA;WORKDIR /code&#xA;&#xA;COPY requirements.txt .&#xA;&#xA;RUN pip install -r requirements.txt&#xA;&#xA;COPY . .&#xA;&#xA;EXPOSE 8000&#xA;&#xA;CMD [&#34;python&#34;,&#34;manage.py&#34;,&#34;runserver&#34;,&#34;0.0.0.0:8000&#34;]&#xA;```&#xA;&#xA;- Let&#39;s see what are we doing here, first we are pulling a base image of Python in this case it is [3.9-buster](https://github.com/docker-library/python/blob/a4b368154b7e3c33c76385f1be7a998fcf3123eb/3.9/buster/Dockerfile), but it can be any of the [Official Python images](https://hub.docker.com/_/python) from [dockerhub](https://hub.docker.com). It is simply a environment for our Django project to run. You can even use linux environments like ubuntu, debian or alpine. &#xA;&#xA;- Next we add a `PYTHONUNBUFFERED` as a environment variable and initialize it to `1`, which basically allows to parse python output straight into the terminal without actually buffering first. &#xA;&#xA;- We set the `WORKDIR` as the `code` directory, this sets the provided directory as the base to run any command or instructions in the Dockerfile. &#xA;&#xA;- We then `COPY` the `requirements.txt` file in the current(`.`) directory which is `code` as mentioned earlier. We simply want the `requirements.txt` file in the current directory so we can proceed with the next step which is to install the dependencies for the Django project&#xA;&#xA;- After copying the `requirements.txt` file, we simply install the packages mentioned int the file with `pip` we use the `RUN` command to execute any shell commands in the environment. &#xA;&#xA;- Next step is to `COPY` all the files from the current folder(local machine) into the docker environment image. So, we have the source code files in the Container. &#xA;&#xA;- Expose the port `8000`(default) or any other port you would want to run Django in the image. We use the expose command in complement to the `-p` argument when we want to create the container. I have explained the [port-forwarding](https://mr-destructive.github.io/techstructive-blog/docker-port-forward) concept in the previous TIL. &#xA;&#xA;- Finally we can run the server. We need to parse every command as a comma separated string in the list to the `CMD` which the container actually executes the command when the image is build. So, all the commands previously were to build an image for the django project, the `CMD` will actually run the server in a container after building the image of the django project.  &#xA;&#xA;### Build the image&#xA;&#xA;Using the Dockerfile, we can create the image for the Django project by a simple command.&#xA;&#xA;```&#xA;docker build . -t django-app&#xA;```&#xA;&#xA;Assuming the Dockerfile is in the same folder from which you are running this command.&#xA;&#xA;![Build the django-app image](https://res.cloudinary.com/techstructive-blog/image/upload/v1646230907/blog-media/jj04subyvkuvfb5obytu.png)&#xA;&#xA;![Build Complete Success](https://res.cloudinary.com/techstructive-blog/image/upload/v1646230988/blog-media/ugjoakqgyhiwelqkyaat.png)&#xA;&#xA;### Run the Image and Create a Container&#xA;&#xA;```&#xA;docker run -p 8000:8000 django-app&#xA;```&#xA;&#xA;![Create Container](https://res.cloudinary.com/techstructive-blog/image/upload/v1646231023/blog-media/yneuz46burorz4b5vzp4.png)&#xA;&#xA;You can use any port like `3000` or `4000` on your local system by changing the first port number as `3000:8000` and so on. So, the first port number is the local system&#39;s port number and the port number followed by a `:` is the port number for the environment inside the container of the django project. The container port is the same which we have `exposed` while creating the image. You can now go to [127.0.0.1:8000](http://127.0.0.1:8000) or your chosen port in your local environment and see the django app running. &#xA;&#xA;If you are using a Docker as a Virtual Machine, you need to find the IP-address of that Virtual-Machine(`docker-machine ip`) and use that instead of `localhost` or `127.0.0.1`. &#xA;&#xA;&#xA;### Cleaning the Container for iterations&#xA;&#xA;We need to stop the container to run it again after making a few changes in the app if any. Simply pressing the `CTRL + D` option wont stop the container here. We need to stop the container by executing: &#xA;&#xA;```&#xA;docker ps&#xA;&#xA;docker stop &lt;container-id&gt;&#xA;```&#xA;&#xA;This will stop the container. Also if you want to remove the images you built, you can run the command:&#xA;&#xA;```&#xA;docker image ls&#xA;&#xA;docker rmi -f &lt;image-id&gt;&#xA;```&#xA;&#xA;  So, we now have a image of our Django project, this image can be used by anyone inside a docker environment and thus creating much more easier to test/work on a given project irrespective of the system is being used.&#xA;</content>
      <type>til</type>
    </item>
    <item>
      <title>Docker Port Forwarding</title>
      <link>https://www.meetgor.com/til/docker-port-forward</link>
      <description>Docker Port Forwarding Port forwarding is a process to redirect the communication of one address to other. It is also known as Port Binding. We can use command</description>
      <pubDate>Tue, 01 Mar 2022 00:00:00 UTC</pubDate>
      <content>## Docker Port Forwarding&#xA;&#xA;Port forwarding is a process to redirect the communication of one address to other. &#xA;It is also known as Port Binding. &#xA;We can use `-p` command to use port forwarding in our local Docker environment.&#xA;&#xA;```&#xA;docker run -p 8000:8000 django-app&#xA;```&#xA;&#xA;The first port number is the local machine port and followed by a `:` is the container port number.&#xA;SO, the request from the container port are forwarded to the local/outside world in the docker environment.&#xA;&#xA;Additionally, we need to expose the container port first. We can do that in the Dockerfile or by adding a `-e` argument followed by the port to expose. This will open the port on container to forward the requests to the specified port in the `-p` option.&#xA;&#xA;In the Dockerfile, we can expose the port by adding the command `EXPOSE 8000`, or any other port number.</content>
      <type>til</type>
    </item>
  </channel>
</rss>