<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Techie Kho</title>
    <description>The latest articles on DEV Community by Techie Kho (@rechie_kho).</description>
    <link>https://dev.to/rechie_kho</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F660076%2F31b4bf16-dee7-499f-bc60-c7fd42f6952b.png</url>
      <title>DEV Community: Techie Kho</title>
      <link>https://dev.to/rechie_kho</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rechie_kho"/>
    <language>en</language>
    <item>
      <title>Bag: A header-only, simplistic, C++20, zipping &amp; unzipping library.</title>
      <dc:creator>Techie Kho</dc:creator>
      <pubDate>Fri, 10 Jan 2025 06:13:39 +0000</pubDate>
      <link>https://dev.to/rechie_kho/bag-a-header-only-simplistic-c20-zipping-unzipping-library-1a6d</link>
      <guid>https://dev.to/rechie_kho/bag-a-header-only-simplistic-c20-zipping-unzipping-library-1a6d</guid>
      <description>&lt;p&gt;Hello! It has been a while since the last time I did something for entertainment and learning purposes. So I take up a fairly simple C++ project that hopefully could be useful for other fellow C++ devs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem Statement
&lt;/h2&gt;

&lt;p&gt;As I play around with &lt;a href="https://www.raylib.com" rel="noopener noreferrer"&gt;raylib&lt;/a&gt;, the small, easy, and exceptionally cool game library, I met a small issue. There is no elegant way of packing files together. When I use a texture or audio, or any external resources, I either need to convert it into a C++ header that declares a byte array filled with that resource, or making sure the the user having the resource at the particular place.  The first approach is no good when comes to loading new resource after compilation, while the latter approach is kind of awkward and too easy to break.&lt;/p&gt;

&lt;p&gt;I'm quite fond of the embedded zip approach. Zip files having a quirky file structure in which the header and metadata is at the end of the file in contrast with other file structure, such as executables, which is at the beginning of the file. This quirk gives a possibility, which is appending the zip file at the end of the executable. This makes the file behave like an executable, and a zip file at the same time.&lt;/p&gt;

&lt;p&gt;I believe there is definitely other zip library that did what I requested. But I would like to have some fun in C++20. So let's get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of bag
&lt;/h2&gt;

&lt;p&gt;With the aforementioned reasoning in mind, I wrote &lt;a href="https://github.com/RechieKho/libbag" rel="noopener noreferrer"&gt;&lt;code&gt;libbag&lt;/code&gt;&lt;/a&gt;, a header-only library for simple zipping and unzipping. It also includes the zipping (&lt;code&gt;bag&lt;/code&gt;) and unzipping (&lt;code&gt;unbag&lt;/code&gt;) utilities. &lt;/p&gt;

&lt;p&gt;By itself, it is sort of like a serialiser and deserialiser for key-value pairs, with key being a simple C-style string and value as byte array. The bag file structure is fairly simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|------------------------|
| key 0 (C-style string) |
|------------------------|
| Content 0 (Byte array) |
|------------------------|
|       ......           |
|------------------------|
| key N (C-style string) |
|------------------------|
| Content N (Byte array) |
|------------------------|
| indices                |
|------------------------|
| metadata               |
|------------------------|
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the key-value pairs are tightly packed together, and some data is appended at the end of the pack. Metadata specifies the whole bag's byte count (to ignore any excess byte in front), position and length of indices, and lastly some magic bytes to indicate it is a bag.&lt;/p&gt;

&lt;p&gt;From the length and position of indices specified in metadata, we can query the memory to get the indices slice in bag. There it resides a list of position and length for each of the key-value pairs saved.&lt;/p&gt;

&lt;p&gt;To get the keys, just treat each key-value pairs as a C-style string since there is a null-terminator that marks the end of the key string. To query the content, just skip 'till the first null-terminator (basically the whole key), and then you get the content begin position, with some pointer arithmetic using the position and length from the indices, the end position of the content can be calculated.&lt;/p&gt;

&lt;p&gt;Here is some example usage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;libbag.hpp&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;sstring&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;libbag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;key_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;libbag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;input_map&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;/// Add items into `input_map`.&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;basic_ostreamstring&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;libbag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;unit_type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;packed_stream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Can be replace with std::basic_ofstream to output to file.&lt;/span&gt;
    &lt;span class="n"&gt;libbag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;pack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_map&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;packed_stream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Pack.&lt;/span&gt;

    &lt;span class="n"&gt;libbag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;unit_string_type&lt;/span&gt; &lt;span class="n"&gt;packed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;packed_stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;libbag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;key_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;libbag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;libbag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;unpack_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;libbag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;bag_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;packed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;inserter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt; &lt;span class="c1"&gt;// Unpack.&lt;/span&gt;
    &lt;span class="c1"&gt;/// Do something about the unpacked data.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API depends on iterators, stream and inserters to reduce allocations.&lt;/p&gt;

&lt;p&gt;I also wrote a simple CLI to zip and unzip files, which is great for referencing as well:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/RechieKho/libbag/blob/main/code/bag.cpp" rel="noopener noreferrer"&gt;bag&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/RechieKho/libbag/blob/main/code/unbag.cpp" rel="noopener noreferrer"&gt;unbag&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cpp</category>
      <category>programming</category>
      <category>gamedev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>React website sample for portfolio</title>
      <dc:creator>Techie Kho</dc:creator>
      <pubDate>Thu, 11 Apr 2024 15:18:51 +0000</pubDate>
      <link>https://dev.to/rechie_kho/react-website-sample-for-portfolio-1opi</link>
      <guid>https://dev.to/rechie_kho/react-website-sample-for-portfolio-1opi</guid>
      <description>&lt;p&gt;TL;DR: I make a &lt;a href="https://richie-cativation.pgs.sh/index.html"&gt;website about kitties&lt;/a&gt; for portfolio, and here is the &lt;a href="https://github.com/RechieKho/cativation"&gt;source code&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hello people! So I have been trying to do a little freelance as a front-end web developer. Programming is my passion, but it has yet to feed me. I always heard that front-end web developer is the most common job in the market; many start-ups need a website, right(?). I've realised that I don't really have a web project to show off my web-making skill. My &lt;a href="https://rechiekho.github.io/RechieKho/"&gt;portfolio website&lt;/a&gt; doesn't count as it is made using vanilla javascript. So I guess it is time to make a random website using modern and popular framework like React.&lt;/p&gt;

&lt;p&gt;The tech stack is very simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vite for project setup and bundling.&lt;/li&gt;
&lt;li&gt;React (of course)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I was about to use &lt;a href="https://mui.com/material-ui/"&gt;Material UI&lt;/a&gt; as they give a bunch of cool reusable components that is already stylised. But, it feels too "Google" and I am a C programmer (having an obsession over reinvent the wheel). &lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up the project
&lt;/h3&gt;

&lt;p&gt;Vite projects are &lt;strong&gt;VERY&lt;/strong&gt; easy to setup to the point that I feel like it is too good to be true. The last time I play around with web, vite is yet to exist and configuring webpack took me 30 minutes of scanning through the docs only to be forgotten once the setup is completed. &lt;/p&gt;

&lt;p&gt;For vite, it really just these magic word:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm create vite@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do some command line inputs and it is done, amazing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Working the design
&lt;/h3&gt;

&lt;p&gt;Alright, I'll going to be honest here: I kind of want to finish this ASAP in the weekend so I made things up along the way instead of planning it in Figma. &lt;/p&gt;

&lt;p&gt;I first checking out any good fonts on &lt;a href="https://fonts.google.com"&gt;Google font&lt;/a&gt; that fits the theme of the website. I select the Nunito as I could feel the playful vibe behind it. &lt;/p&gt;

&lt;p&gt;Then, I get some color palette from this &lt;a href="https://coolors.co"&gt;color palette generator&lt;/a&gt;. I have been using it since the very beginning of web dev journey, a good color palette could better describe the theme of the website. &lt;/p&gt;

&lt;h3&gt;
  
  
  CSS
&lt;/h3&gt;

&lt;p&gt;Writing CSS is much a creative process here since I don't have a mockup, thus it is kind of describe it in detail. But I will still share things that I usually do in CSS.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;reset.css&lt;br&gt;
I will &lt;em&gt;always&lt;/em&gt; use the &lt;a href="https://meyerweb.com/eric/tools/css/reset/"&gt;reset stylesheet&lt;/a&gt;. It is because different web browser has its own default stylesheet that could mess up my code. So I just copy the code and put it in the project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CSS variables&lt;br&gt;
I love CSS variables, I use it to for the color palette.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f5f5f5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--grey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#796c9f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--dark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#392f5a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#2ea9c4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--primary-light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#a1d8eb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--secondary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ff9f1c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--secondary-light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffbf69&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It avoids hardcoding colors. Then, I only need to change the value of the variable instead of searching through the codebase for that particular color code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Javascript
&lt;/h3&gt;

&lt;p&gt;Since it is React, I need to do something special here. &lt;br&gt;
I decided to use the &lt;a href="https://cataas.com"&gt;Cataas&lt;/a&gt; API to fetch cat pictures in my code to display the random cats.&lt;/p&gt;

&lt;p&gt;But behind the scene, it is just &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useEffect&lt;/code&gt; hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;catImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCatImage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialCatImage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updateCatImage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="s2"&gt;`https://cataas.com/cat?width=250&amp;amp;height=250`&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;setCatImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;
      &lt;span class="p"&gt;})();&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;updateCatImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that is all the special stuff in the website...&lt;/p&gt;

&lt;h3&gt;
  
  
  Deployment
&lt;/h3&gt;

&lt;p&gt;I'm using &lt;a href="https://pgs.sh"&gt;pgs.sh&lt;/a&gt; to host my static site. It uses &lt;code&gt;ssh&lt;/code&gt; (secure shell) and &lt;code&gt;rsync&lt;/code&gt; (a file transfer protocol) to do all the stuff. It doesn't need to create account or whatsoever. Very quick to setup, very cool.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Well, I got a website to show-off and maybe get a freelance project. And, you get to see all my source code and learn something. It is beneficial to both of us. Thank you for reading this late night posting and have a nice day/night.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>portfolio</category>
    </item>
    <item>
      <title>Running pre-trained ML models in Godot</title>
      <dc:creator>Techie Kho</dc:creator>
      <pubDate>Thu, 18 Jan 2024 12:21:04 +0000</pubDate>
      <link>https://dev.to/rechie_kho/running-pre-trained-ml-models-in-godot-37da</link>
      <guid>https://dev.to/rechie_kho/running-pre-trained-ml-models-in-godot-37da</guid>
      <description>&lt;p&gt;So I have been developing this GDExtension called &lt;a href="https://github.com/RechieKho/iree.gd"&gt;iree.gd&lt;/a&gt;. It is mission to embed &lt;a href="https://github.com/openxla/iree"&gt;IREE&lt;/a&gt;, another cool project that compiles and runs ML models, into Godot. It took me quite a while, but finally It has reached &lt;a href="https://github.com/RechieKho/iree.gd/releases"&gt;alpha&lt;/a&gt;. &lt;br&gt;
Hope you guys could check it out the sample.&lt;/p&gt;

&lt;p&gt;I can't upload video to here, but you still can watch a small clips of &lt;a href="https://github.com/RechieKho/iree.gd/issues/37#issuecomment-1897703268"&gt;iree.gd doing its magic here&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Currently, it is still having a very thin abstraction layer, and some manual stuff need to be done in prior.&lt;/p&gt;
&lt;h3&gt;
  
  
  Preparing the ML model
&lt;/h3&gt;

&lt;p&gt;Before doing anything, you'll need to download your trained ML model from the internet. You could find some from &lt;a href="https://www.kaggle.com/models"&gt;Kaggle&lt;/a&gt;. Then, you'll need to preprocess them with python &lt;a href="https://iree.dev/guides/ml-frameworks/tflite/"&gt;via this detailed documentation&lt;/a&gt;. You'll need to set the HAL backend following &lt;a href="https://github.com/RechieKho/iree.gd#supported-platforms"&gt;this table depending on your targeted platform&lt;/a&gt;. As you generate the &lt;code&gt;.vmfb&lt;/code&gt; byte code, you are ready to proceed to the next step.&lt;/p&gt;
&lt;h3&gt;
  
  
  Use the ML model
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;.vmfb&lt;/code&gt; files are automatically imported into the project as you drag and drop 'em into it. You could then use them in your script by loading them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;model&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;IREEModule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;preload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"res://your_model.vmfb"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;@export&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;model_2&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;IREEModule&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="kt"&gt;Drag&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;drop&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;editor&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, you'll need to prepare your inputs with &lt;code&gt;IREETensor&lt;/code&gt;, then execute the ML model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;IREETensor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_data&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="kt"&gt;Remember&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;consider&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;outputs&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run_module&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"module.main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;pass&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="kt"&gt;Do&lt;/span&gt; &lt;span class="n"&gt;something&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="nv"&gt;output&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;input&lt;/code&gt; and function name vary models to models. You could inspect the &lt;code&gt;.vmfb&lt;/code&gt; file using &lt;code&gt;iree-dump-module&lt;/code&gt; from the IREE packages you installed during preparing the ML model. &lt;/p&gt;

&lt;p&gt;Here is one section of the dump of the ML model used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
Exported Functions:
  [  0] main(!vm.ref&amp;lt;?&amp;gt;) -&amp;gt; (!vm.ref&amp;lt;?&amp;gt;)
        iree.abi.declaration: sync func @main(%input0: tensor&amp;lt;1x50x50x3xf32&amp;gt; {ml_program.identifier = "input_0"}) -&amp;gt; (%output0: tensor&amp;lt;1x200x200x3xf32&amp;gt; {ml_program.identifier = "Identity"})
  [  1] __init() -&amp;gt; ()
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could kind of guess it, it has &lt;code&gt;main&lt;/code&gt; function that takes a tensor of &lt;code&gt;float32&lt;/code&gt; (&lt;code&gt;1x50x50x3xf32&lt;/code&gt;) and outputs another tensor of &lt;code&gt;float32&lt;/code&gt; (&lt;code&gt;1x200x200x3xf32&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample
&lt;/h2&gt;

&lt;p&gt;There is a readily available sample of esrgan for you to try in the &lt;a href="https://github.com/RechieKho/iree.gd/releases"&gt;release page&lt;/a&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The sample only work on windows and linux.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After download and open &lt;code&gt;iree-gd-sample-*.zip&lt;/code&gt; with Godot 4.2+, you will need to do these:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;set &lt;code&gt;res://scenes/main/main.tscn&lt;/code&gt; to be loaded on start.&lt;/li&gt;
&lt;li&gt;Drag and drop appropriate byte code in &lt;code&gt;res://bytecodes/esrgan/esrgan.*.vmfb&lt;/code&gt; into &lt;code&gt;UI/TextureRect&lt;/code&gt;'s module export.&lt;/li&gt;
&lt;li&gt;Run it.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Afterword
&lt;/h2&gt;

&lt;p&gt;Hopefully, in the future, Godot developer could utilise this piece of technology and create something extraordinary and magical. Thank you for reading this.&lt;/p&gt;

</description>
      <category>godot</category>
      <category>machinelearning</category>
      <category>gamedev</category>
      <category>ai</category>
    </item>
    <item>
      <title>Minky scripting language</title>
      <dc:creator>Techie Kho</dc:creator>
      <pubDate>Wed, 15 Nov 2023 12:38:29 +0000</pubDate>
      <link>https://dev.to/rechie_kho/minky-scripting-language-21pj</link>
      <guid>https://dev.to/rechie_kho/minky-scripting-language-21pj</guid>
      <description>&lt;p&gt;&lt;em&gt;Edit&lt;/em&gt;: It has been rebranded to Blinklet, here is the &lt;a href="https://github.com/RechieKho/blinklet"&gt;repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I have written a simple scripting language in Rust, the obscure language for a lot of devs. It is called "Minky".&lt;/p&gt;

&lt;p&gt;Here is the &lt;a href="https://github.com/RechieKho/minky"&gt;link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The whole idea of this language stems from this thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What if we remove parentheses from LISP?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Essentially, Minky is my version of WISP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Syntax
&lt;/h2&gt;

&lt;p&gt;Let's jump into the syntax:&lt;br&gt;
In a typical C-derived language, a function call usually look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function(arg1, arg2, arg3)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Minky, since we disdain parentheses, we replace all the separating symbols with whitespace&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function arg1 arg2 arg3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But... what if I want to inline a function call as an argument like this?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function(arg1, arg2, another_function())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, in Minky, you just indent it!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function arg1 arg2
    another_function # This will call
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don't indent it, &lt;code&gt;another_function&lt;/code&gt; will be passed as value. &lt;/p&gt;

&lt;p&gt;But! What if I want to pass value after some indents?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function arg1
    another_function 
    arg3 # I don't want this to get call!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, you just prefix it with &lt;code&gt;|&lt;/code&gt; to cancel out the call&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function arg1
    another_function
    | arg3 # Pass as value!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Some features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;String interpolation&lt;/li&gt;
&lt;li&gt;Closure&lt;/li&gt;
&lt;li&gt;Loose Object-Oriented Programming&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  String interpolation
&lt;/h3&gt;

&lt;p&gt;To do string interpolation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;some-command 'Text `identifier`'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;identifier&lt;/code&gt; is the variable name, it will substitute with the variable's string representation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Closure
&lt;/h3&gt;

&lt;p&gt;All the user-defined functions are closure. It has access to the lexically scoped variable. In simple term, the scope that the closure is declared in lives with the closure until the closure itself dies, and the closure can access the scope.&lt;/p&gt;

&lt;p&gt;Here is an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var make-counter
    closure
        var counter 0 # counter will live with the returned closure even after `make-counter` complete execution.
        return
            closure
                set counter # access parent counter.
                    add counter 1
                println 'counter: `counter`'

var counter
    make-counter

counter # 1
counter # 2
counter # 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Loose Object-Oriented Programming
&lt;/h3&gt;

&lt;p&gt;In normal class-based object-oriented programming, we have class and object, in which the object's structure is based on the class. In Minky, all of the classes and objects are table. Tables are &lt;em&gt;not&lt;/em&gt; linked together in anyway, but you can make a copy of a table (instancing) and extends on top of it (inheritance). Table is also act as scope, too!&lt;/p&gt;

&lt;p&gt;To make a person class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var Person
    table
        var name 'Bazinga'
        var age 25
        var say-hi
            closure # aka. function but has access to parent scope.
                println 'Hi! I am `name`. Nice to meet you!'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make an instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var peter
    Person
        set name 'Peterson'
        set age 90

# Call the method
peter
    say-hi

# Access values
var peter-age
    peter
        return age
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To extend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var Police
    Person
        set name 'Policeman'
        set age 15
        var gun 'AK15'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;It is my attempt on making a scripting language. There are more feature to be discussed, and to be added. You can fetch the code at &lt;a href="https://github.com/RechieKho/minky"&gt;my GitHub repo&lt;/a&gt;. Thank you for reading and have a nice day.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>rust</category>
      <category>coding</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Piko-piko OS. A homemade 16-bit x86 toy operating system for fun.</title>
      <dc:creator>Techie Kho</dc:creator>
      <pubDate>Wed, 07 Dec 2022 11:33:18 +0000</pubDate>
      <link>https://dev.to/rechie_kho/piko-piko-os-a-homemade-16-bit-x86-toy-operating-system-for-fun-52dm</link>
      <guid>https://dev.to/rechie_kho/piko-piko-os-a-homemade-16-bit-x86-toy-operating-system-for-fun-52dm</guid>
      <description>&lt;p&gt;So I made a &lt;a href="https://github.com/RechieKho/piko-piko"&gt;16-bit x86 toy OS in pure assembly&lt;/a&gt;. 3 months ago, I found a very fun &lt;a href="https://github.com/cfenollosa/os-tutorial"&gt;tutorial&lt;/a&gt; on github that is about Operating system development. I read the first few chapter and from there I made a very simple, extensible (?) toy operating system that could run on hardware (yes, it is madness). &lt;/p&gt;

&lt;h2&gt;
  
  
  Piko-piko OS overview
&lt;/h2&gt;

&lt;p&gt;As the title stated, it is a toy os so itself doesn't do much. Still, the language is still turing complete. Here is an example that prints Hello world 10 times.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;00000 &lt;span class="nb"&gt;set &lt;/span&gt;0 10
00001 say n &lt;span class="s2"&gt;"Hello world"&lt;/span&gt;
00002 sub 0 &lt;span class="nv"&gt;$0&lt;/span&gt; 1
00003 cmp &lt;span class="nv"&gt;$0&lt;/span&gt; 0
00004 june 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The language is more or less like an interpreted assembly language without label. It can read user input, print to output, basic arithmetic, save &amp;amp; load data and conditional jumps. &lt;a href="https://github.com/RechieKho/piko-piko/wiki/commands-reference"&gt;Here&lt;/a&gt; is all the commands included. I'll write a more user-friendly tutorial to kick start your Piko-piko OS coding journey, but right now you can only &lt;/p&gt;

&lt;p&gt;In Piko-piko OS, you can either enter the command to the prompt to run the command directly or using &lt;code&gt;=&lt;/code&gt; command to save lines of command to buffer and run it all together with &lt;code&gt;run&lt;/code&gt; command. By default, there is 3 buffer. Each buffer can only holds 2560 lines of text.&lt;/p&gt;

&lt;p&gt;Piko-piko OS is self-contained, which means that it does not rely on any other code and won't effect other files except itself. When saving &amp;amp; loading data, it does read and write to itself &lt;strong&gt;only&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practicality?
&lt;/h2&gt;

&lt;p&gt;Yes, it is not practical but it is a very educational resource to learn lower-level programming and really knowing how machine work. Still, you can use it to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Show off&lt;/li&gt;
&lt;li&gt;Stop your child from watch too much youtube by locking them up in Piko-piko OS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is a very cool experience to be able to make an operating from scratch. I might be able to share the experience of developing Piko-piko OS on the next blog post. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Don't write HTML page, I will tell you why.</title>
      <dc:creator>Techie Kho</dc:creator>
      <pubDate>Mon, 11 Oct 2021 10:07:03 +0000</pubDate>
      <link>https://dev.to/rechie_kho/don-t-write-html-page-i-will-tell-you-why-1pd4</link>
      <guid>https://dev.to/rechie_kho/don-t-write-html-page-i-will-tell-you-why-1pd4</guid>
      <description>&lt;p&gt;Instead of encourage people, I am here to discourage you a guy, who started / want to start web development. &lt;/p&gt;

&lt;h2&gt;
  
  
  The start
&lt;/h2&gt;

&lt;p&gt;At the start your journey, you install either sublime or vscode or notepad++, then you start to make a website using HTML and know that HTML is a HyperText Markup Language. You feel proud of yourself as your HTML page is displayed in google chrome. Then, you color your page with CSS and make your page interactive with alert() and document.write().&lt;/p&gt;

&lt;h2&gt;
  
  
  framework hell
&lt;/h2&gt;

&lt;p&gt;Slowly, you think you are very good, then you heard of React or Angular and you immediately jump into it. In the blink of an eye, you are overwhelmed. What the hell is Webpack? What is JSX? What is Nodejs? What is typescript? What is npm? What is Sass? Why a simple website need so much technology with weird names?&lt;/p&gt;

&lt;h2&gt;
  
  
  server-side programing
&lt;/h2&gt;

&lt;p&gt;At the verge of giving up, you heard of database and server. You install XAMPP or WAMPP and then start poking around with PHP. You also play around with expressjs. Then, you are once again overwhelmed. What is composer? What is a session? What is phpMyAdmin and MySQL? &lt;/p&gt;

&lt;h2&gt;
  
  
  game development
&lt;/h2&gt;

&lt;p&gt;After you learn one or two things, you think desktop application and game development is cool, so you install Unity. Oh my, Object-Oriented Programming in C# (pain in general). You think that ElectronJS is easier and want to give it a shot but because everyone critisize that it is less performant so you give up.&lt;/p&gt;

&lt;h2&gt;
  
  
  linux
&lt;/h2&gt;

&lt;p&gt;Then, you heard that people keep telling you "I use Arch, btw" and "Vim is the best editor". You watch a few shitpost from Mental Outlaw (on youtube) and decided to install gentoo linux. You are once again overwhelmed. Why so much command (cd, touch, ls, emerge, time, ifconfig, vim and etc.)? Systemd called as soystemd? OpenRC? Init system? GNU and Linux is different? Display server? X.org vs Wayland? dwm vs bloated Gnome?&lt;/p&gt;

&lt;h2&gt;
  
  
  lower-level programming
&lt;/h2&gt;

&lt;p&gt;Then as you get used to the tty and know how to edit some text in vim. You start to do some C and C++ programming. Although the OOP from C# or Java helps, you still feel overwhelmed. CMake, Ninja, gcc, tcc, clang, llvm and etc.&lt;br&gt;
Maybe you also step on some assembly language and suffers. &lt;/p&gt;

&lt;p&gt;Ok I will stop now. All these painful learning + failing + imposter syndrome + mental illness is all because of you decided to install sublime /  vscode to create a HTML page. &lt;/p&gt;

&lt;p&gt;In conclusion, don't create your first HTML page.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Here is my website without fancy stuff like React or Angular or Vue</title>
      <dc:creator>Techie Kho</dc:creator>
      <pubDate>Sat, 09 Oct 2021 01:47:46 +0000</pubDate>
      <link>https://dev.to/rechie_kho/here-is-my-website-without-fancy-stuff-like-react-or-angular-or-vue-37l5</link>
      <guid>https://dev.to/rechie_kho/here-is-my-website-without-fancy-stuff-like-react-or-angular-or-vue-37l5</guid>
      <description>&lt;p&gt;A website that I created using only HTML, CSS, and JS : &lt;a href="https://rechiekho.github.io/RechieKho/index.html"&gt;https://rechiekho.github.io/RechieKho/index.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yes, its content is really stupid because I can't come out a new one.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
