<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Tech Tim (@TechTim42)</title>
    <description>The latest articles on Forem by Tech Tim (@TechTim42) (@timhub).</description>
    <link>https://forem.com/timhub</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%2F289253%2F9decf38c-2192-4a7c-acbc-fd12f72bf94e.jpeg</url>
      <title>Forem: Tech Tim (@TechTim42)</title>
      <link>https://forem.com/timhub</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/timhub"/>
    <language>en</language>
    <item>
      <title>How to Proxy and Modify OpenAI Stream Responses for Enhanced User Experience</title>
      <dc:creator>Tech Tim (@TechTim42)</dc:creator>
      <pubDate>Sat, 20 Jan 2024 00:00:00 +0000</pubDate>
      <link>https://forem.com/timhub/how-to-proxy-and-modify-openai-stream-responses-for-enhanced-user-experience-16p1</link>
      <guid>https://forem.com/timhub/how-to-proxy-and-modify-openai-stream-responses-for-enhanced-user-experience-16p1</guid>
      <description>&lt;p&gt;Recently, we encountered a requirement to develop a feature that proxies and modifies a stream from OpenAI. Essentially, our goal is to receive the GPT-4 response in a stream, but instead of directly returning the stream to the front-end, we aim to modify the value within the stream and then return the modified value to the front-end application.&lt;/p&gt;

&lt;p&gt;Is this possible? The answer is yes. This article discusses how to pipe a stream in NodeJS/ExpressJS to achieve better FCP (First Contentful Paint). Simultaneously, it explains the process of modifying the stream content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why people want to use stream as Response?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Reason is Simple and Straightforward, to have better UX&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is similar to the concept we have in front end and UX, FCP (First Contentful Paint), streaming is a way to reduce the FCP time to let users to have a better UX.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Move from this&lt;/th&gt;
&lt;th&gt;To this&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ThI_zhti--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/mikeborozdin/http-streaming-request/raw/main/docs/no-streaming.gif" alt="no streaming" width="640" height="312"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fiJl-zrr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/mikeborozdin/http-streaming-request/raw/main/docs/streaming.gif" alt="streaming" width="640" height="272"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;This Table and Gifs are From &lt;a href="https://github.com/mikeborozdin"&gt;Mike Borozdin&lt;/a&gt;&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  How to achieve it in NodeJS?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;It is very simple and straightforward too.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If using Axios, it could be done in a few lines through a &lt;code&gt;pipe&lt;/code&gt;&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="nx"&gt;streamResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sourceApiUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;responseType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stream&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;  &lt;span class="c1"&gt;// this line was used to simulate OpenAI GPT4 Response&lt;/span&gt;
&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeHead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/plain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;  
&lt;span class="nx"&gt;streamResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What are the challenges here then?
&lt;/h2&gt;

&lt;p&gt;If it the requirement is just to proxy the stream,  &lt;code&gt;pipe&lt;/code&gt; is everything we need to do here, and the whole work is simply to build a proxy service for OpenAI API. Unluckily, the challenges here are the modification part.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Modification
&lt;/h3&gt;

&lt;p&gt;In NodeJs, &lt;code&gt;Transformer&lt;/code&gt; class is use to modify the streaming chunks, so we could update the codes to be like this&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="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="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sourceApiUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;responseType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stream&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;  
&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modifyStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Transform&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;  
  &lt;span class="nf"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;encoding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&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;modifiedChunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;   &lt;span class="c1"&gt;// modify the content to uppercase&lt;/span&gt;
    &lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;modifiedChunk&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
  &lt;span class="p"&gt;}&lt;/span&gt;  
&lt;span class="p"&gt;});&lt;/span&gt;  
&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;modifyStream&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before the pipe to express response, modifyStream transformer was added, to modify the content before return to consumers.&lt;/p&gt;

&lt;h3&gt;
  
  
  What if the stream response is not a chunk of text
&lt;/h3&gt;

&lt;p&gt;We have to consider about this case as well, now many people are using the &lt;code&gt;function&lt;/code&gt; and &lt;code&gt;json response&lt;/code&gt; in GPT4 now, which means a simple transformer will not work as expected for modifying the stream content. &lt;/p&gt;

&lt;p&gt;For example, to modify a chunk of unfinished JSON response in a stream, &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We need to make sure the content is a valid JSON&lt;/li&gt;
&lt;li&gt;At the same time, we need to make change on top of it, and return the modified content as early as possible to consumers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But JSON is a strongly structured data type, it will not be valid until it is closed with its curly bracket &lt;code&gt;}&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;This is Node package to parse partial JSON.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;parse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;best-effort-json-parser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`[1, 2, {"a": "apple`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// [1, 2, { a: 'apple' }]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On top of it, there is even simpler one, 'http-streaming-request'&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;makeStreamingJsonRequest&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/some-api&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await &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;data&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// if the API only returns [{"name": "Joe&lt;/span&gt;
  &lt;span class="c1"&gt;// the line below will print `[{ name: "Joe" }]`&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;In this case, we can update our codes to use it to make the modification for the streaming content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;makeStreamingJsonRequest&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;  
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sourceApiUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
&lt;span class="p"&gt;});&lt;/span&gt;  
&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await &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;data&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="nx"&gt;modifiedData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;modified&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// add more modify&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;modifiedData&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;Performance will not be as good as the original stream pipe, but it will meet all requirements for this case.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Please be noted when you used this library, you may need add some de-bouncing logic on top of it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Depends on your modification/transformation code, unless the modification logic is crazy, it will not affect the performance too much of the whole streaming process. The FCP will be reduced, comparing to waiting the whole JSON response being completed. &lt;/p&gt;

&lt;p&gt;The Github Repo of the Sample codes is attached below.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tim-hub/node-stream-sample"&gt;Github Repo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/api/stream.html"&gt;NodeJS Stream&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/best-effort-json-parser"&gt;Node package for partial JSON&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>openai</category>
      <category>express</category>
      <category>node</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Tips for Getting Started to Code and Teaching Coding</title>
      <dc:creator>Tech Tim (@TechTim42)</dc:creator>
      <pubDate>Thu, 14 Dec 2023 11:00:00 +0000</pubDate>
      <link>https://forem.com/timhub/tips-for-getting-started-to-code-and-teaching-coding-212k</link>
      <guid>https://forem.com/timhub/tips-for-getting-started-to-code-and-teaching-coding-212k</guid>
      <description>&lt;p&gt;I got a friend (Alice), Alice is an artist with a non-tech background in her career at all. I recently started to teach her coding online now. From this experience I would like to share some suggestion for the new coders.&lt;/p&gt;

&lt;h2&gt;
  
  
  For Myself
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Explain Tech Terms in Detail
&lt;/h3&gt;

&lt;p&gt;For individuals like Alice, who are navigating the technical landscape with some unfamiliar terms, breaking down these concepts can make a significant difference.&lt;/p&gt;

&lt;p&gt;For example,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def sum(a,b):
  return a+b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My explanation is like&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The whole function is to get sum of two numbers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sum&lt;/code&gt; is the function name&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;a, b&lt;/code&gt; are 2 &lt;strong&gt;parameters&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;return&lt;/code&gt; is to &lt;strong&gt;return&lt;/strong&gt; the output to the &lt;strong&gt;caller&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;parameter&lt;/code&gt;, &lt;code&gt;call&lt;/code&gt;, &lt;code&gt;return&lt;/code&gt; these words gave Alice a bit confusion in the beginning.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So these kind of technology terms need to be explained when teaching. &lt;/p&gt;

&lt;h2&gt;
  
  
  For Alice (the new coders)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Try, Fail but Keep Curiosity
&lt;/h3&gt;

&lt;p&gt;Curiosity is a good teacher, for an engineering work, there are a lot of pattern and best practices to follow. You need to be curious about why having the pattern or best practices. &lt;/p&gt;

&lt;p&gt;At the same time, you may need to try and fail, not directly asking why or Google.&lt;/p&gt;

&lt;p&gt;So my suggestion would be,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Try it, no matter it is in good or bad practice, after doing it a few times, you will have a better understanding of the &lt;code&gt;why&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Alone Time
&lt;/h3&gt;

&lt;p&gt;In a collaborative workspace, being a lone wolf isn't always ideal., but for practicing coding, sometimes you need to become a lone wolf. It's not about shunning collaboration, but acknowledging the value of tackling challenges independently. Struggling through problems solo often fosters a deeper understanding and skill development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Google It
&lt;/h3&gt;

&lt;p&gt;There are many resources online, to search, to get the answers. Today, resources like ChatGPT offer incredible support for coding queries. With LLM models adept at comprehending complex questions, accessing varied tones and formats becomes easier. Utilize these tools not just for answers but also to diversify your learning experience.&lt;/p&gt;

</description>
      <category>coding</category>
      <category>learning</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>Why you don't need Diversity in Work Place but Respect</title>
      <dc:creator>Tech Tim (@TechTim42)</dc:creator>
      <pubDate>Wed, 02 Aug 2023 08:00:00 +0000</pubDate>
      <link>https://forem.com/timhub/why-you-dont-need-diversity-in-work-place-but-respect-5974</link>
      <guid>https://forem.com/timhub/why-you-dont-need-diversity-in-work-place-but-respect-5974</guid>
      <description>&lt;p&gt;Recently I was re-fresh my knowledge about Agile and Scrum in practice, after gaining more experience in practice in IT, and after this learning, &lt;strong&gt;I just realised that in the little country I stayed in, none of the company, or the company I have heard of, they are doing Scrum properly&lt;/strong&gt;. (Maybe I can talk about that in the future, why none of the company I knew in this country doing a real Scrum.) Now I would like to talk about a very important value of Scrum.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Respect&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I wrote an article I wrote long ago as well, to talk about Diversity, it talks about why we should talk about more about Respect the difference in workplace, then Diversity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some Cases To Think
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S33AkREZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://media4.giphy.com/media/iFU36VwXUd2O43gdcr/giphy.gif%3Fcid%3Decf05e47vnze3db2bw5w8zc5w61pugx3dqfn864bs5mn4tfn%26ep%3Dv1_gifs_search%26rid%3Dgiphy.gif%26ct%3Dg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S33AkREZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://media4.giphy.com/media/iFU36VwXUd2O43gdcr/giphy.gif%3Fcid%3Decf05e47vnze3db2bw5w8zc5w61pugx3dqfn864bs5mn4tfn%26ep%3Dv1_gifs_search%26rid%3Dgiphy.gif%26ct%3Dg" alt="typing" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Colleague &lt;strong&gt;A&lt;/strong&gt; always &lt;strong&gt;types very slow&lt;/strong&gt;, and does not know many shortcuts to do things efficiently, &lt;br&gt;
     You: This guy seems like from stone age, I cannot believe he is qualified for doing software jobs&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Question&lt;/strong&gt;: Is is possible there are something you haven't noticed, is it possible he didn't use the OS before, maybe he is a Mac user, but you give him a windows. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is a difference of people's performance of hardware and setting&lt;/strong&gt;, it should be respected. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yzy7K6Cj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://media2.giphy.com/media/l4Ep6sIcT2T0wsJLa/giphy.gif%3Fcid%3Decf05e47ekvebyotbtflzk1s25hx0mhdn155gaj8b0530cp8%26ep%3Dv1_gifs_search%26rid%3Dgiphy.gif%26ct%3Dg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yzy7K6Cj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://media2.giphy.com/media/l4Ep6sIcT2T0wsJLa/giphy.gif%3Fcid%3Decf05e47ekvebyotbtflzk1s25hx0mhdn155gaj8b0530cp8%26ep%3Dv1_gifs_search%26rid%3Dgiphy.gif%26ct%3Dg" alt="lunch box" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Colleague &lt;strong&gt;B&lt;/strong&gt; he is always away during lunch time about 2 to 3 hours,&lt;br&gt;
   You: He is lazy, I will suggest boss to fire him.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Question&lt;/strong&gt;: &lt;strong&gt;different cultures have different way of lunch&lt;/strong&gt;, I knew a French colleague, he said in France, people always have one hour plus lunch, a proper meal, not a work day sandwich. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2UgwBfO0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://media4.giphy.com/media/HWl1atKEPAWcw/giphy.gif%3Fcid%3Decf05e47fctapacny8k136o8dduoz0hw3kkfo2w6a4qn5pei%26ep%3Dv1_gifs_search%26rid%3Dgiphy.gif%26ct%3Dg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2UgwBfO0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://media4.giphy.com/media/HWl1atKEPAWcw/giphy.gif%3Fcid%3Decf05e47fctapacny8k136o8dduoz0hw3kkfo2w6a4qn5pei%26ep%3Dv1_gifs_search%26rid%3Dgiphy.gif%26ct%3Dg" alt="mute" width="200" height="163"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Colleague &lt;strong&gt;C&lt;/strong&gt; he does not talk at all, his English is so hard to understand&lt;br&gt;
   You: He does not communicate, fire him&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Question, &lt;strong&gt;not everyone are native language is English&lt;/strong&gt;, maybe slow yourself down instead&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dXFQIfr6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://media1.giphy.com/media/Cyv99H3tH0y1PVYPB1/giphy.gif%3Fcid%3Decf05e47j19ndwgutm10m1m17a9bbq7z71tek7ptenjcrnhw%26ep%3Dv1_gifs_search%26rid%3Dgiphy.gif%26ct%3Dg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dXFQIfr6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://media1.giphy.com/media/Cyv99H3tH0y1PVYPB1/giphy.gif%3Fcid%3Decf05e47j19ndwgutm10m1m17a9bbq7z71tek7ptenjcrnhw%26ep%3Dv1_gifs_search%26rid%3Dgiphy.gif%26ct%3Dg" alt="late" width="480" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Colleague &lt;strong&gt;D&lt;/strong&gt;: He always start very late (in a flexible workplace), no one can catch him during day time to collaborate.&lt;br&gt;
You: he does not collaborate, fire him&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Question: &lt;strong&gt;If it is your colleague or your staff, what do you think of it? Do you think the person should be fired or not?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These are just very little of the differences in workplace, I am pretty sure you will see more. No matter your place is small or big, diversed or not. &lt;/p&gt;

&lt;p&gt;This is why I wanted to say, &lt;strong&gt;diversity is not the most important thing in your workplace, the respect of the difference is.&lt;/strong&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Many workplace focus too much on diversity, and ignore the difference (not includes in common diversity, gender, race, etc), &lt;strong&gt;it give people a wrong feeling, we have the diversity so we have the culture of respect, and our place can learn and grow together&lt;/strong&gt;. In most of time, &lt;strong&gt;it is not true&lt;/strong&gt;, it only give you a surface feeling of it, and make people blind about the real problem, we should respect each other's difference, not only on common diversity problems. &lt;/p&gt;

</description>
      <category>workplace</category>
      <category>culture</category>
      <category>agile</category>
      <category>scrum</category>
    </item>
    <item>
      <title>How to migrate from an old OpenWrt router to a new one, with the least downtime for your home network</title>
      <dc:creator>Tech Tim (@TechTim42)</dc:creator>
      <pubDate>Sat, 15 Jul 2023 09:00:00 +0000</pubDate>
      <link>https://forem.com/timhub/how-to-migrate-from-old-openwrt-router-to-a-new-one-with-the-least-downtime-for-your-home-network-k51</link>
      <guid>https://forem.com/timhub/how-to-migrate-from-old-openwrt-router-to-a-new-one-with-the-least-downtime-for-your-home-network-k51</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;As a fan of open source, self host, and privacy focus software, I always try to use transparent, open source, and free software as much as possible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Long ago I bought a new router, because of work, I didn't get much time to install my favorite router firmware &lt;code&gt;OpenWRT&lt;/code&gt; on it. To gain a better performance, I found a time slot to start to install it and migrate from the old one to the new one.&lt;/p&gt;

&lt;p&gt;For Apple ecosystem, no matter iPhone or MacBook, Apple offers you some close-source but seamless tool for migration, at macOS, you have &lt;a href="https://support.apple.com/guide/macbook-pro/transfer-your-data-apda75cd668e/mac"&gt;Apple Migration Assistant&lt;/a&gt;, at iOS you have &lt;a href="https://support.apple.com/en-nz/HT201269"&gt;Quick Start&lt;/a&gt; during set-up.&lt;/p&gt;

&lt;p&gt;For Android/Lineage OS, it does not have a built-in tool for this, but due to there is a big Android community, there are plenty of tools to do it. I used to use some powerful backup tools for this, there is a paid one &lt;a href="https://www.lifewire.com/how-to-use-titanium-backup-pro-on-android-4771843"&gt;Titanium Backup&lt;/a&gt;, and an open source one &lt;a href="https://f-droid.org/en/packages/com.machiav3lli.backup/"&gt;Neo Backup&lt;/a&gt;, I tried both of them, both work very well.&lt;/p&gt;

&lt;p&gt;But there is no such thing for OpenWrt. It means switching to the new router, users have to do some work to switch to new OpenWrt router, &lt;strong&gt;surely, everyone can just simply manually reconfigure the new router through UI to make it work&lt;/strong&gt;, but it could cause you a lot of time, especially when you have a complex firewall settings. (like me).&lt;/p&gt;

&lt;p&gt;In this article, I would like to share what I have found, what could be a good practice to archive it, to be as seamless as possible, to have as least downtime as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  1 Copy Software/Add-ons List and Reinstall
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_h7T_LfK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3cmm2e5tpvzgssi435q3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_h7T_LfK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3cmm2e5tpvzgssi435q3.png" alt="luci software list of openWrt" width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the original router, login to the router shell through SSH. Execute the following command to generate a list of installed packages and save it to a file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;opkg list-installed &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; installed_packages.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Copy the "installed_packages.txt" file to the new machine's file system, for example, using SCP:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp installed_packages.txt root@new_openwrt_ip:/tmp/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Execute the following command to install the packages listed in the "installed_packages.txt" file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;opkg update 
opkg &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /tmp/installed_packages.txt | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $1}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After all these, the new router should have all the software you have in the old one.&lt;/p&gt;

&lt;h2&gt;
  
  
  2 Configurations for Firewall, Network etc
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Powerful &lt;code&gt;/etc/config&lt;/code&gt; folder&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qxwFlXrd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cj21xxx6cnr5x7q813lo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qxwFlXrd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cj21xxx6cnr5x7q813lo.png" alt="etc/config of openWrt" width="800" height="27"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OpenWrt has a very simple and clean structure to manage the configuration, there is no fancy database or encrypted storage, nearly all configurations are in plain text, stored in this folder &lt;code&gt;/etc/config&lt;/code&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ideally, after copy and paste it will work directly, but due to some router models difference, it is better to have some manually step here to check the configurations whether match or not on a new router. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Pull the config folder from old router to the computer.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp &lt;span class="nt"&gt;-r&lt;/span&gt; root@old-router:/etc/config /tmp/router-config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should contain all these settings&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dhcp&lt;/li&gt;
&lt;li&gt;firewall&lt;/li&gt;
&lt;li&gt;wireless&lt;/li&gt;
&lt;li&gt;network&lt;/li&gt;
&lt;li&gt;software/add-ons settings&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;(Optional) backup new router default config
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp &lt;span class="nt"&gt;-r&lt;/span&gt; root@new-router:/etc/config /tmp/new-router-default-config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just in case any settings go wrong in next step.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Push the config to the new router at the same location&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Before doing this, you may manually review the settings, for example, &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;static IP address in DHCP/Firewall (see more in the &lt;code&gt;extra tips&lt;/code&gt; section below)&lt;/li&gt;
&lt;li&gt;you should not need to push &lt;code&gt;system&lt;/code&gt; config to new router, especially the new router is a different model.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/router-config root@new-router:/etc/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After all these, simply do a reboot.&lt;/p&gt;

&lt;h2&gt;
  
  
  3 Scheduled tasks
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rjkb673i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uiwk7ltq7xy7v6caqkfh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rjkb673i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uiwk7ltq7xy7v6caqkfh.png" alt="schedule" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;OpenWRT's scheduled tasks are actually just &lt;code&gt;cron&lt;/code&gt; jobs in Linux.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Go to old router, &lt;code&gt;crontab -e&lt;/code&gt;, it will open a vi editor to display all cron jobs&lt;/li&gt;
&lt;li&gt;Copy them&lt;/li&gt;
&lt;li&gt;Login to the new router, run the command again, &lt;code&gt;crontab -e&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Paste them&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  4 Some extra tips
&lt;/h2&gt;

&lt;p&gt;There is one thing I found quite useful, because for software installation, the new router will require internet access as well, so what I found &lt;strong&gt;quite useful is to set the new router as sub-router of the old router, but with different LAN IP.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For example, for my old router, it is &lt;code&gt;192.168.1.1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;For my new router, it is &lt;code&gt;172.16.1.1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So that, I can use one computer to login to 2 different router secure shells. It makes it very easy to copy the configuration and set them to new ones.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;However, there is a disadvantage for this practice as well, in step 2 to copy configurations, for &lt;strong&gt;networks&lt;/strong&gt;,  &lt;strong&gt;DHCP&lt;/strong&gt;, and &lt;strong&gt;firewall&lt;/strong&gt; (if there are some static IP configuration) settings, we need to manually replace the old IP to new ones. It anyone has better idea for this, please share it to me. :) &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;After these 3 steps, you should be able to unplug old router and plug the new one, and all the clients supposed to just work without any changes.&lt;/p&gt;

&lt;p&gt;If you want to let me know more about OpenWrt&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to set up OpenWrt router? &lt;/li&gt;
&lt;li&gt;How to install it?&lt;/li&gt;
&lt;li&gt;What are good practices to set up OpenWrt Firewall?&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>openwrt</category>
      <category>opensource</category>
      <category>security</category>
      <category>networking</category>
    </item>
    <item>
      <title>Learn Coaching in My Workplace</title>
      <dc:creator>Tech Tim (@TechTim42)</dc:creator>
      <pubDate>Fri, 14 Jul 2023 09:00:00 +0000</pubDate>
      <link>https://forem.com/timhub/learn-coaching-in-work-place-from-culture-amp-3b03</link>
      <guid>https://forem.com/timhub/learn-coaching-in-work-place-from-culture-amp-3b03</guid>
      <description>&lt;p&gt;Coaching is a transformative process that aims to unlock potential, foster growth, and support individuals in achieving their goals. It goes beyond simply providing advice or instructions; it is about creating a safe and empowering environment where individuals can explore their thoughts, feelings, and aspirations. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Yir2f_Vk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2n8xx8awuy45vuwgcjrc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Yir2f_Vk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2n8xx8awuy45vuwgcjrc.png" alt="1 to 1 talk and coaching" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Effective coaching involves several key elements, including active listening, asking thought-provoking questions, empathising, summarising, and maintaining an open-minded approach.&lt;/p&gt;

&lt;p&gt;Recently I learnt about how to do coaching in work place from Culture AMP. In this post, I want to share some fundamental aspects of coaching and explore how they can be applied in practice to drive meaningful change.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Power of Listening:
&lt;/h3&gt;

&lt;p&gt;At the core of coaching lies the art of active listening. It is about giving someone your undivided attention, focusing on their words, tone, and body language.&lt;br&gt;
By listening attentively, &lt;strong&gt;you create a space where individuals feel heard and valued&lt;/strong&gt;, allowing them to freely express their thoughts and emotions. Through active listening, you can gain deeper insights into their perspectives, concerns, and aspirations, which serves as a foundation for effective coaching. &lt;/p&gt;

&lt;h3&gt;
  
  
  2. The Art of Asking Questions:
&lt;/h3&gt;

&lt;p&gt;As a coach, your role is &lt;strong&gt;not to provide answers but to facilitate self-discovery and growth&lt;/strong&gt;. Asking powerful questions is an essential skill in coaching. By utilizing open-ended questions that begin with "how," "what," "where," and "when," rather than closed-ended questions that elicit simple "yes" or "no" responses, &lt;strong&gt;you encourage individuals to explore their own thoughts and come up with meaningful solutions&lt;/strong&gt;. Thought-provoking questions spark introspection, expand perspectives, and uncover new possibilities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l3jdBliy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tbdqsatzsrf83d4nvciu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l3jdBliy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tbdqsatzsrf83d4nvciu.png" alt="asking questions" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The Importance of Empathy:
&lt;/h3&gt;

&lt;p&gt;Empathy plays a crucial role in coaching. It is the ability to &lt;strong&gt;understand and share the feelings&lt;/strong&gt; and experiences of another person. By empathising with individuals, you create a safe and non-judgmental space where they can freely express themselves without fear of criticism or rejection. Demonstrating empathy fosters trust and builds a strong coach-client relationship, enabling individuals to open up and explore their challenges and aspirations more authentically. &lt;/p&gt;

&lt;h3&gt;
  
  
  4. The Power of Summarising:
&lt;/h3&gt;

&lt;p&gt;Summarising is a skill that helps both the coach and the individual &lt;strong&gt;gain clarity&lt;/strong&gt; and perspective. By summarising what has been discussed, you demonstrate your understanding of their thoughts, feelings, and goals. This process also allows individuals to reflect on their own insights and make connections between different aspects of their lives. Summarising helps to distill the essence of the conversation and serves as a foundation for future exploration and growth.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Embracing an Open-Minded Approach:
&lt;/h3&gt;

&lt;p&gt;Coaching requires &lt;strong&gt;an open-minded and non-judgmental attitude&lt;/strong&gt;. It means putting aside preconceived notions, biases, and personal agendas to fully embrace the individual's unique experiences and perspectives. By maintaining an open mind, you create a space where individuals can freely express themselves without fear of judgment. This fosters an environment of trust, authenticity, and collaboration, enabling individuals to explore new possibilities and embrace positive change.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dE13Za3S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u2do8e0n731n1yqieijf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dE13Za3S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u2do8e0n731n1yqieijf.png" alt="growing plant" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Coaching is a powerful tool for personal and professional growth, enabling individuals to tap into their potential and overcome challenges. By incorporating &lt;strong&gt;active listening, powerful questioning, empathy, summarisation, and an open-minded approach&lt;/strong&gt; into the coaching practice, it will help create a supportive and transformative environment for individuals in workplace.&lt;/p&gt;

</description>
      <category>management</category>
      <category>coaching</category>
      <category>career</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>What is a real diversity in workplace</title>
      <dc:creator>Tech Tim (@TechTim42)</dc:creator>
      <pubDate>Thu, 04 May 2023 08:33:38 +0000</pubDate>
      <link>https://forem.com/timhub/what-is-a-real-diversity-in-workplace-22gc</link>
      <guid>https://forem.com/timhub/what-is-a-real-diversity-in-workplace-22gc</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BHSqHeM5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.unsplash.com/photo-1581343191085-f2ded7b8d9d0%3Fixid%3DMnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8%26ixlib%3Drb-1.2.1%26auto%3Dformat%26fit%3Dcrop%26w%3D1500%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BHSqHeM5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.unsplash.com/photo-1581343191085-f2ded7b8d9d0%3Fixid%3DMnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8%26ixlib%3Drb-1.2.1%26auto%3Dformat%26fit%3Dcrop%26w%3D1500%26q%3D80" alt="colorful pens" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Diversity is a real concern for more and more companies. I think the reason for that is the increasing awareness of human rights protection.&lt;/p&gt;

&lt;p&gt;I talked to many people in work place about diversity as well, I think different people have different understandings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aq_Ph5J2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.pexels.com/photos/3760607/pexels-photo-3760607.jpeg%3Fauto%3Dcompress%26cs%3Dtinysrgb%26w%3D1260%26h%3D750%26dpr%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aq_Ph5J2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.pexels.com/photos/3760607/pexels-photo-3760607.jpeg%3Fauto%3Dcompress%26cs%3Dtinysrgb%26w%3D1260%26h%3D750%26dpr%3D1" alt="question to ask" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I knew one guy, he has opinion like this.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We are a real diversity focused team, because we have people from Asia, we have people from America, Europe, and We have local people, we have males and females.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I knew another person who cares about diversity in workplace, she asked a question I remembered during acquisition.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nearly all the board members are male, do we have a diversity in the organization, and do we really care about it?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Honestly, I think &lt;strong&gt;gender diversity, nationality diversity&lt;/strong&gt; should not be such a big concern. What is more important, is to respect the difference, and collaborate different people and understand different people to work together towards the objectives.&lt;/p&gt;

&lt;p&gt;It does not really matter where the person is from, or whether the person is male or female.&lt;/p&gt;

&lt;p&gt;Everyone is unique, if an employee’s review is based on whether he is social, whether he is good at a specific language, or on appearance, it would make it unfair, and it makes the problem in the workplace more serious to have a gender or race diversity.&lt;/p&gt;

&lt;p&gt;A fair and a diverse working culture should be a person’s review is basing on&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  what the person does,&lt;/li&gt;
&lt;li&gt;  what the persons are good at,&lt;/li&gt;
&lt;li&gt;  how well the person communicates, (even the work language is not the person’s native language, or whether the person communicates in a tech-guy way or not).&lt;/li&gt;
&lt;li&gt;  etc&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fpoMAQZx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.unsplash.com/photo-1560264280-88b68371db39%3Fixlib%3Drb-1.2.1%26ixid%3DMnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8%26auto%3Dformat%26fit%3Dcrop%26w%3D1000%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fpoMAQZx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://images.unsplash.com/photo-1560264280-88b68371db39%3Fixlib%3Drb-1.2.1%26ixid%3DMnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8%26auto%3Dformat%26fit%3Dcrop%26w%3D1000%26q%3D80" alt="rectangular brown wooden table" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I met a colleague in workplace, he always likes to give colleagues tags, like,&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Social, Hard-working, Brave, Collaborating&lt;/strong&gt;, etc. It is OK because of all these tags are neural, nothing good or bad. The only problem for that is the criteria, his standard is that, if you are not doing like me to meet people or talk to people, you are not social, if I cannot understand what you talk, you are not collaborating, if you do not match my exception in my mind, you are not hard-working. All criteria are subjective. This basically creates more problems in work place, even have a good diversity, but no respect, no objective standard for review, that only makes things worse.&lt;/p&gt;

&lt;p&gt;So IMO the real diversity is to &lt;strong&gt;respect the difference&lt;/strong&gt; and the most important thing in a work place should be Respect, Objectives, Collaboration and Happiness.&lt;/p&gt;

</description>
      <category>diversity</category>
      <category>culture</category>
      <category>career</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to choose AWS Database</title>
      <dc:creator>Tech Tim (@TechTim42)</dc:creator>
      <pubDate>Fri, 21 Apr 2023 23:03:35 +0000</pubDate>
      <link>https://forem.com/aws-builders/how-to-choose-aws-database-19hi</link>
      <guid>https://forem.com/aws-builders/how-to-choose-aws-database-19hi</guid>
      <description>&lt;p&gt;AWS offers many different options for different &lt;a href="https://aws.amazon.com/free/database/"&gt;Database&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;All database could fall into 2 categories, Relation Database and Non-relational database.&lt;/p&gt;

&lt;p&gt;In this article, we are talking about an overview of different cloud native database on AWS, to compare some limit and differences between each Databse Options, how to choose each database in different use cases.&lt;/p&gt;

&lt;h1&gt;
  
  
  Relational Database — AWS Aurora
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iPJDiKhd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:411/1%2A4cx8dY8sNotDMDCZoeSrcQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iPJDiKhd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:411/1%2A4cx8dY8sNotDMDCZoeSrcQ.png" alt="aws relational db" width="411" height="519"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AWS Aurora is a fully managed relational database engine, It has 2 compatibility models, PostgreQL and MySQL/MariaDB,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  storage limit is 128TB&lt;/li&gt;
&lt;li&gt;  table size limit 64TB(MySQL) and 32TB (Postgres)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Non-relational Database
&lt;/h1&gt;

&lt;p&gt;There are more options for non-relational db in AWS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qv9EK0SB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:700/1%2AtLThGywdtaO60XCP8T61qw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qv9EK0SB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:700/1%2AtLThGywdtaO60XCP8T61qw.png" alt="AWS Non Relational DB diagram" width="700" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Document Based
&lt;/h1&gt;

&lt;h2&gt;
  
  
  DynamoDB:
&lt;/h2&gt;

&lt;p&gt;One of the most popular database from AWS. It is a highly scalable and highly available NoSQL database that is designed for low-latency, high-throughput applications. DynamoDB is a document-based database that uses tables, items, and attributes to store and retrieve data. It supports both document and key-value data models, allowing you to choose the data model that best fits your application needs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  item size: 400kb, (per row) &lt;a href="https://www.alexdebrie.com/posts/dynamodb-limits/#dynamodb-item-size-limit"&gt;ref: DynamoDB Limit&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  storage limit: &lt;a href="https://www.effectual.com/amazon-dynamodb/"&gt;Unlimited in theory&lt;/a&gt;, there are transactions limit applied&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;While 400KB is large enough for most normal database operations, it is significantly lower than the other options. MongoDB allows for documents to be 16MB, while Cassandra allows blobs of up to 2GB. And if you really want to get beefy, Postgres allows rows of up to 1.6TB (1600 columns X 1GB max per field)!&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  AWS Document DB(MongoDB Compatible)
&lt;/h2&gt;

&lt;p&gt;AWS DocumentDB is a document-based database service that is compatible with MongoDB. It is designed to help you run your MongoDB workloads on AWS with high performance, scalability, and availability. DocumentDB supports the MongoDB API, allowing you to use your existing MongoDB applications, drivers, and tools with minimal changes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  max db size 64TB&lt;/li&gt;
&lt;li&gt;  max collection size 32TB (similar to a table in Relational Database)&lt;/li&gt;
&lt;li&gt;  max document size 16MB&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Simple DB
&lt;/h2&gt;

&lt;p&gt;SimpleDB is a highly available and flexible non-relational data store that is designed to help you store and query structured data. It is a fully managed service that provides automatic scaling and high availability, making it easy to build scalable and highly available applications. SimpleDB is ideal for storing small amounts of data that require simple querying and indexing, such as product catalogs, user profiles, and event logs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Maximum domain size: 10 GB (similar to a table in Relational DB)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to Choose between DynamoDB, Document DB and Simple DB?
&lt;/h2&gt;

&lt;p&gt;If you are already using MongoDB and want to migrate your workload to AWS, AWS DocumentDB is a great option. If you need a highly available, flexible data store for small amounts of structured data, SimpleDB is a good choice. If you need a highly scalable, highly available NoSQL database for low-latency, high-throughput applications, DynamoDB is the right option. All three services are fully managed and can be easily integrated with other AWS services.&lt;/p&gt;

&lt;h1&gt;
  
  
  Graph Based
&lt;/h1&gt;

&lt;p&gt;Neptune is AWS’s graph-based database that is designed to store and navigate highly connected data. It supports popular graph query languages such as Apache TinkerPop Gremlin and SPARQL, making it easy to develop graph-based applications. The one big compatible Graph db on the market is Neo4j, AWS offer &lt;a href="https://docs.aws.amazon.com/neptune/latest/userguide/migrating-from-neo4j.html"&gt;a migration guide from Neo4j to AWS Neptune&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Data Warehouse or Column Oriented
&lt;/h1&gt;

&lt;p&gt;Redshift, on the other hand, is AWS’s data warehousing solution. It is designed to help businesses analyze and process large amounts of data quickly and cost-effectively. Redshift is a columnar database that uses massively parallel processing (MPP) to distribute queries across multiple nodes, allowing for high-performance data processing. Redshift also offers a range of security features, including encryption, network isolation, and fine-grained access controls. It has some limitations as well, one is it does not support updates or deletes on tables with a sort key, so you may need to redesign your table schema to work with Redshift.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Choose Redshift?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In short, if you need a column oriented database, or a warehouse, choose Redshift.&lt;/p&gt;

&lt;h1&gt;
  
  
  Key Value Database
&lt;/h1&gt;

&lt;p&gt;ElastiCache is AWS’s in-memory data store that supports two open-source in-memory engines, Redis and Memcached. It is designed to help improve the performance and scalability of your applications by caching frequently accessed data in memory. ElastiCache allows you to create, scale, and manage in-memory data stores with ease, and it supports use cases such as caching, session management, and real-time analytics. With ElastiCache, you can increase the throughput and reduce the latency of your applications while reducing the load on your backend databases. — &lt;a href="https://dev.to/aws-builders/the-in-memory-cache-db-amazon-elasticache-3d4a"&gt;More about ElasiCache&lt;/a&gt; Limitation of ElastiCache:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  ElastiCache is not a durable data store, so if you lose your cache, you will need to rebuild it from your data source.&lt;/li&gt;
&lt;li&gt;  ElastiCache does not support data replication across regions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Memory DB, on the other hand, is AWS’s in-memory database that is designed for real-time applications that require sub-millisecond response times. Memory DB is fully managed and highly available, and it supports high-throughput, low-latency workloads that require fast and predictable response times. Memory DB can be used for applications such as gaming, real-time bidding, and finance, where sub-millisecond response times are critical.&lt;/p&gt;

&lt;p&gt;Limitation of Memory DB:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  MemoryDB is designed for high performance, but it may not be as flexible or scalable as other database engines.&lt;/li&gt;
&lt;li&gt;  MemoryDB is currently only available in a limited number of AWS regions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How to choose between ElastiCache and MemoryDB?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In short, if cache is needed, choose ElastiCache, if latency is the issue or you want to build some real time application, choose Memory DB&lt;/p&gt;

&lt;h1&gt;
  
  
  In Sum
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;This article does not include all database categories, for example, AWS Timestream and AWs Ledget Database.&lt;/p&gt;

&lt;p&gt;Different cloud provider may offer similar products, for example Oracle’s JSON-base Database is very similar to AWS Document DB.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>database</category>
      <category>aws</category>
      <category>cloud</category>
      <category>cloudnative</category>
    </item>
    <item>
      <title>What LLM does not help for SaaS</title>
      <dc:creator>Tech Tim (@TechTim42)</dc:creator>
      <pubDate>Thu, 13 Apr 2023 20:34:45 +0000</pubDate>
      <link>https://forem.com/timhub/what-llm-does-not-help-for-saas-2hna</link>
      <guid>https://forem.com/timhub/what-llm-does-not-help-for-saas-2hna</guid>
      <description>&lt;p&gt;LLMs, such as the ChatGPT model released by OpenAI, have become a prominent topic in the field of natural language processing (NLP) and artificial intelligence (AI). These models are capable of generating human-like text responses, making them valuable for a wide range of applications, including SaaS products.&lt;/p&gt;

&lt;p&gt;There are some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://github.com/emcf/engshell" rel="noopener noreferrer"&gt;engshell&lt;/a&gt;, bring native language in shell to run command in computer.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.konjer.xyz/" rel="noopener noreferrer"&gt;konjer&lt;/a&gt;, talk to your book.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.gptduck.com/" rel="noopener noreferrer"&gt;gptduck&lt;/a&gt;, learn about a code repo though LLM.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is nearly half a year now since the release of ChatGPT. Tons of SaaS company has integrated or want to intergrate Open AI, GPT3.5 or GPT4 to their SaaS products. However, before implementing or planning, there are two challenges I have noticed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost of LLM, API Rate
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A700%2F0%2AY_tdS_BuZ3XNAqFt" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A700%2F0%2AY_tdS_BuZ3XNAqFt" alt="us dollars"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/es/@jinyun?utm_source=medium&amp;amp;utm_medium=referral" rel="noopener noreferrer"&gt;金 运&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=medium&amp;amp;utm_medium=referral" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These costs can vary depending on the type of LLM being used, the size of the input data, and the number of requests made. For example, the GPT-4 model from OpenAI charges $0.03 per 1,000 tokens for 8k context, while the GPT-3.5-Turbo model charges $0.002 per 1,000 tokens. SaaS providers need to carefully account for these costs and ensure that they are transparently communicated to their users to avoid any surprises or unexpected charges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bring Low SLA to SaaS
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A700%2F0%2AoNjMMWD56jUmxjb0" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A700%2F0%2AoNjMMWD56jUmxjb0" alt="bar chart of SLA"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@isaacmsmith?utm_source=medium&amp;amp;utm_medium=referral" rel="noopener noreferrer"&gt;Isaac Smith&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=medium&amp;amp;utm_medium=referral" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In addition to cost considerations, there is also the issue of the &lt;strong&gt;SLA for LLM APIs&lt;/strong&gt;. OpenAI does not provide a guaranteed SLA for the availability of its APIs, which means that SaaS providers cannot guarantee the availability of their products when relying on these APIs. For example, if a SaaS provider has an original SLA of 99.5%, introducing the GPT-4 API into their product could potentially reduce this SLA due to the lack of a guaranteed SLA for the API.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For SLA Calculation. If a SaaS contains 2 tier, if first tier SLA is 90%, the second tier is 90% too, for the product, the SLA is 81%. In this case, if the SLA for OpenAI is unknown, the OpenAI is integrated as part of core of the products, the new SLA is 0%, which it means it will break the agreement.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  How to overcome these 2 Potential Issues?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A700%2F0%2A2nPpU182bOel8_VQ" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A700%2F0%2A2nPpU182bOel8_VQ" alt="show a solution in front of a laptop"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@johnschno?utm_source=medium&amp;amp;utm_medium=referral" rel="noopener noreferrer"&gt;John Schnobrich&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=medium&amp;amp;utm_medium=referral" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How to Save the Cost of Integrating LLM in SaaS?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;There is no perfect way to solve these issues. For the pricey, one potential solution is to &lt;strong&gt;bring your own OpenAI API Key.&lt;/strong&gt; This could save the cost from the SaaS provider, since the price will be charged from end users. However, SaaS providers need to ensure that proper security measures are in place to protect the API keys and the data processed by the LLM APIs if they are stored and managed by SaaS provider.&lt;/p&gt;

&lt;p&gt;There is &lt;strong&gt;another issue for the products that ask API Key from clients/consumers, it is not in a SaaS style&lt;/strong&gt;. The reason for a SaaS product becoming popular, because it let users to have the cross-platform experience in all services in one, data persistency, computing, and easy to use UI/UX. At the same time, users are charged in one bill as well. Bringing API Key basically break the purpose of building a SaaS products.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How to Increase the SLA of LLM APP?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Self-host + Replication&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One potential solution to these challenges is to &lt;strong&gt;self-host LLMs and replicate them across different regions&lt;/strong&gt; to ensure availability and reduce latency. However, this approach can also be expensive, particularly from a time perspective, as it requires significant resources to set up and maintain the infrastructure needed to host and replicate LLMs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not Integrate LLM into Core Product&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This could work for SaaS products which do not require LLM AI as core service of it.&lt;/p&gt;

&lt;p&gt;For example, one approach f*&lt;em&gt;or a Facebook Marketplace-like web application would be to avoid relying on LLM to extract information from sale listings, and instead utilize LLM as an optional chat assistant&lt;/em&gt;*. This would allow for the core product functionalities to remain independent of low SLA LLM, while still enabling users to benefit from LLM capabilities.&lt;/p&gt;

&lt;h1&gt;
  
  
  In Conclusion
&lt;/h1&gt;

&lt;p&gt;Integrating LLM APIs into SaaS products can offer significant benefits in terms of functionality and user experience. However, SaaS providers need to carefully consider the cost, security, and availability considerations associated with using these APIs. &lt;strong&gt;Bringing your own API key&lt;/strong&gt; can offer a seamless experience for users, but requires proper security measures. Self-hosting LLMs can provide greater availability and reduced latency, but requires significant resources to set up and maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  References:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://vickiboykis.com/2023/02/26/what-should-you-use-chatgpt-for/" rel="noopener noreferrer"&gt;What should you use ChatGPT for&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>llm</category>
      <category>ai</category>
      <category>saas</category>
      <category>openai</category>
    </item>
    <item>
      <title>How to Set Up Your Raspberry Pi: A Beginner’s Guide to WIFI, Docker, and More!</title>
      <dc:creator>Tech Tim (@TechTim42)</dc:creator>
      <pubDate>Mon, 27 Mar 2023 09:00:00 +0000</pubDate>
      <link>https://forem.com/timhub/how-to-set-up-your-raspberry-pi-a-beginners-guide-to-wifi-docker-and-more-1l0l</link>
      <guid>https://forem.com/timhub/how-to-set-up-your-raspberry-pi-a-beginners-guide-to-wifi-docker-and-more-1l0l</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Mwbbq87m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AB09NyAaJDQfX0pf0" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Mwbbq87m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AB09NyAaJDQfX0pf0" alt="Raspberry" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I recently found my Raspberry Pi 3B in one of my storage box. As a small, affordable and versatile computer that can be used for a wide range of projects, from media centers to &lt;strong&gt;home automation&lt;/strong&gt; systems.&lt;/p&gt;

&lt;p&gt;If you’re new to Raspberry Pi, setting up your device can be a little daunting, but don’t worry — it’s easier than you might think. In this guide, we’ll walk you through the steps required to get your Raspberry Pi up and running.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connect Monitor and Set up Keyboard
&lt;/h3&gt;

&lt;p&gt;The first step is to connect a monitor and a keyboard to your Raspberry Pi. You’ll need a monitor with an HDMI input, and a USB keyboard. Plug the HDMI cable into the HDMI port on the Raspberry Pi, and the other end into the monitor. Then connect the USB keyboard to one of the USB ports on the Raspberry Pi.&lt;/p&gt;

&lt;p&gt;When you first boot up your Raspberry Pi, you’ll be asked to choose a keyboard layout. This is important, as it will affect the way your keyboard behaves. Make sure to choose the correct layout for your keyboard. If you’re unsure which layout to choose, try the default layout for your region.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://raspberrytips.com/keyboard-layout-on-raspberry-pi/"&gt;&lt;strong&gt;How to Change your Keyboard Layout on Raspberry Pi? (RPI OS) | RaspberryTips&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
_If, like me, you don't use a QWERTY keyboard, the first thing you are probably looking for on your Raspberry Pi is how…_raspberrytips.com&lt;/a&gt;&lt;a href="https://raspberrytips.com/keyboard-layout-on-raspberry-pi/"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Set up WIFI/LAN in CLI
&lt;/h4&gt;

&lt;p&gt;Next, you’ll need to connect your Raspberry Pi to the internet. You can do this either via GUI, by clicking the WIFI icon at right corner. (If GUI Desktop Environment was installed)&lt;/p&gt;

&lt;p&gt;Or update it in CLI. &lt;/p&gt;

&lt;p&gt;Raspberry Pi store the network config in &lt;code&gt;/etc/wpa_supplicant/wpa_supplicant.conf&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;This could be manually updated, or through the config CLI &lt;code&gt;_raspi-config_&lt;/code&gt; &lt;em&gt;,&lt;/em&gt; a restart may be required after netwoek changed.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Anytime after the first booting, if you want to change keyboard layout, region, WIFI etc, run &lt;code&gt;sudo raspi-config&lt;/code&gt; in your terminal&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More about &lt;code&gt;_raspi-config_&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.raspberrypi.com/documentation/computers/configuration.html"&gt;&lt;strong&gt;Raspberry Pi Documentation - Configuration&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
_raspi-config is the Raspberry Pi configuration tool originally written by Alex Bradbury. To open the configuration…_www.raspberrypi.com&lt;/a&gt;&lt;a href="https://www.raspberrypi.com/documentation/computers/configuration.html"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Install docker and docker compose
&lt;/h3&gt;

&lt;p&gt;Finally, you’ll want to install Docker and Docker Compose on your Raspberry Pi. Docker is a tool for building, deploying, and managing containers, while Docker Compose is a tool for defining and running multi-container Docker applications. To install Docker and Docker Compose, follow the steps outlined in the following tutorial:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/elalemanyo/how-to-install-docker-and-docker-compose-on-raspberry-pi-1mo"&gt;&lt;strong&gt;How To Install Docker and Docker-Compose On Raspberry Pi&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
_Raspberry Pi with a running Raspbian OS SSH connection enabled To do this you can check Raspberry Pi Setup. First of…_dev.to&lt;/a&gt;&lt;a href="https://dev.to/elalemanyo/how-to-install-docker-and-docker-compose-on-raspberry-pi-1mo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note that you may not need to install pip3 or Python 3 for the latest version of Docker on the ARM architecture, and Docker Compose may be installed by default. You also may not need to set up a user group.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MKeUF5x9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.pexels.com/photos/16094828/pexels-photo-16094828.jpeg%3Fauto%3Dcompress%26cs%3Dtinysrgb%26w%3D1260%26h%3D750%26dpr%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MKeUF5x9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.pexels.com/photos/16094828/pexels-photo-16094828.jpeg%3Fauto%3Dcompress%26cs%3Dtinysrgb%26w%3D1260%26h%3D750%26dpr%3D1" alt="pi" width="880" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s it! You should now have a fully functional Raspberry Pi with Docker and Docker Compose installed. From here, you can start building your own projects and exploring the full potential of this amazing little computer. These are some cool home projects could be run in docker on Pi.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://pi-hole.net/"&gt;pi-hole&lt;/a&gt;, DNS level Ads Blocker&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.home-assistant.io/"&gt;home assistant&lt;/a&gt;, home automation tool for IoT devices&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>raspberrypi</category>
      <category>docker</category>
      <category>tutorial</category>
      <category>iot</category>
    </item>
    <item>
      <title>GitHub CLI: Your Secret Weapon for Slaying Code Reviews</title>
      <dc:creator>Tech Tim (@TechTim42)</dc:creator>
      <pubDate>Sun, 19 Mar 2023 02:40:03 +0000</pubDate>
      <link>https://forem.com/timhub/github-cli-your-secret-weapon-for-slaying-code-reviews-15o7</link>
      <guid>https://forem.com/timhub/github-cli-your-secret-weapon-for-slaying-code-reviews-15o7</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A700%2F1%2Aj_Y8Rf0rZd39jK2JvNs5Iw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A700%2F1%2Aj_Y8Rf0rZd39jK2JvNs5Iw.jpeg" alt="a screenshot for github cli"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hey there, fellow coders! You know what’s worse than getting feedback on your code? Having to switch between multiple tabs and tools just to make a pull request. It’s a real pain, right? But fear not, my friends! I’m here to introduce you to &lt;strong&gt;GitHub CLI&lt;/strong&gt; — the fun and easy way to improve your code quality in just five minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create pull requests with ease:
&lt;/h2&gt;

&lt;p&gt;Creating pull requests can be a pain, but with GitHub CLI, you can create them from the comfort of your command line. No more switching between browser tabs and copy-pasting information! You can create a pull request with just a few commands, like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gh pr create --title "Added new feature" --body "This feature will improve user experience" --assignee @joh&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Request code reviews:
&lt;/h2&gt;

&lt;p&gt;Requesting code reviews is essential to ensure that your code is up to par. With GitHub CLI, you can request reviews from your peers without leaving your command line. You can even specify a due date for the review, so everyone knows when to get it done. Here’s an example command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gh pr request-review --reviewer @jane --due-date 2023-03-21&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Check pull request status:
&lt;/h2&gt;

&lt;p&gt;You don’t want to be the person who constantly checks the pull request page to see if anything has changed. GitHub CLI makes it easy to check the status of your pull requests directly from your command line. Here’s how you can do it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gh pr list --state open&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will list all of your open pull requests, along with some essential information like the title, author, and state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Respond to code review comments:
&lt;/h2&gt;

&lt;p&gt;Code review comments are essential for improving your code quality, but they can be overwhelming to keep track of. GitHub CLI allows you to respond to code review comments directly from your command line. Here’s how you can do it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gh pr review 123 --comment "Thanks for the suggestion, I'll make that change"&lt;/code&gt;`&lt;/p&gt;

&lt;p&gt;This command allows you to respond to a specific comment on a pull request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Merge pull requests:
&lt;/h2&gt;

&lt;p&gt;When your code has been reviewed and approved, it’s time to merge it into the main branch. GitHub CLI allows you to do this directly from your command line, without ever leaving your cozy terminal. Here’s how you can do it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gh pr merge 123&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command merges the pull request with ID 123 into the main branch.&lt;/p&gt;

&lt;h2&gt;
  
  
  In the end
&lt;/h2&gt;

&lt;p&gt;In a nutshell, GitHub CLI is a lifesaver for developers who want to streamline their code review process. It’s like having a superpower that allows you to create pull requests, request code reviews, check pull request status, respond to code review comments, and merge pull requests — all from the comfort of your command line. So next time you’re about to submit a pull request, remember to channel your inner superhero and use GitHub CLI to save time, improve your code quality, and have fun while doing it!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://cli.github.com/" rel="noopener noreferrer"&gt;GitHub CLI | Take GitHub to the command line&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>github</category>
      <category>git</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How To Improve Code Quality In Last 5 Minutes Before Submitting PR</title>
      <dc:creator>Tech Tim (@TechTim42)</dc:creator>
      <pubDate>Fri, 17 Mar 2023 07:00:00 +0000</pubDate>
      <link>https://forem.com/timhub/how-to-improve-code-quality-in-last-5-minutes-before-submitting-pr-gb</link>
      <guid>https://forem.com/timhub/how-to-improve-code-quality-in-last-5-minutes-before-submitting-pr-gb</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A700%2F0%2AQ43itGAg6o2y0j9l" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A700%2F0%2AQ43itGAg6o2y0j9l" alt="Git"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, you’re just about to submit your Pull Request, and you’re thinking, “Wait a minute, is my code up to par?” Don’t panic, my friend, I got you covered with some last-minute tips to improve your code quality before you hit that submit button.&lt;/p&gt;

&lt;h2&gt;
  
  
  One Step Back
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A500%2F0%2AO1HDO67BYYpeksT4" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A500%2F0%2AO1HDO67BYYpeksT4" alt="One Step Back with a cup of coffee"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First things first, take a chill pill and step back from your code. Take a deep breath, grab a cup of coffee, or do whatever it takes to clear your mind. Then, take a good look at your code and ask yourself, “&lt;strong&gt;Is this clean, readable, and easy to maintain&lt;/strong&gt;?” If not, you know what to do next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Tools
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A700%2F1%2AXDO1-bil7MCLVMSXwQZhQw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A700%2F1%2AXDO1-bil7MCLVMSXwQZhQw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use some fancy Integration Code review tools if you can. These tools can save your bacon by spotting any potential bugs, errors, or bad practices in your code. They’ll give you instant feedback, so you can fix any issues and feel confident that your code is top-notch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test Coverage:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://about.codecov.io/" rel="noopener noreferrer"&gt;CodeCov&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://coveralls.io/" rel="noopener noreferrer"&gt;CoverAlls&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;For Auto Code Review:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.codacy.com/" rel="noopener noreferrer"&gt;Codacy&lt;/a&gt; for code review, it says it could save 60% of code review time&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.codefactor.io/" rel="noopener noreferrer"&gt;CodeFactor&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Local Tools:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://git-scm.com/docs/githooks" rel="noopener noreferrer"&gt;Git Hook&lt;/a&gt; and &lt;a href="https://typicode.github.io/husky/" rel="noopener noreferrer"&gt;Husky&lt;/a&gt; trigger scripts before commit, or push etc&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://prettier.io/" rel="noopener noreferrer"&gt;Prettier&lt;/a&gt;, to make codes look prettier&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://cli.github.com/" rel="noopener noreferrer"&gt;GH Gtihub CLI&lt;/a&gt; create and review PR in one line of command and more&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A564%2F1%2A-cDZ-VZaq-0fULnNxQK-Kw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A564%2F1%2A-cDZ-VZaq-0fULnNxQK-Kw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Github CLI — gh commands&lt;/p&gt;

&lt;p&gt;Want to Know More about the Github CLI &lt;code&gt;gh&lt;/code&gt; , you can read it here&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@TechTim42/github-cli-your-secret-weapon-for-slaying-code-reviews-47b454a4e33d" rel="noopener noreferrer"&gt;GitHub CLI: Your Secret Weapon for Slaying Code Reviews! | by Tech Tim (@TechTim42) | Mar, 2023 | Medium&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prepare Yourself For Comments and Feedback
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A700%2F0%2A-BpH_ERb79XFu9km" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A700%2F0%2A-BpH_ERb79XFu9km" alt="Relax Yourself"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, here’s a pro tip: &lt;strong&gt;be humble and open to suggestions&lt;/strong&gt;. Nobody’s perfect, and we all make mistakes. So, don’t be afraid to ask for feedback from your peers and reviewers. Listen to their suggestions, learn from their expertise, and make your code even better.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lastly, Remember Quality is More Important
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A700%2F0%2AJkptMhnzNw_Iflw8" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A700%2F0%2AJkptMhnzNw_Iflw8" alt="Code Qualiity is King"&gt;&lt;/a&gt;&lt;br&gt;
Code Qualiity is King&lt;/p&gt;

&lt;p&gt;Lastly, remember that &lt;strong&gt;quality is king&lt;/strong&gt;. Don’t rush to submit your PR just to meet a deadline. Take your time, prioritize quality over speed, and submit your code with confidence. Trust me, it’s better to delay submission and ensure code quality than to submit subpar code that can cause issues down the road.&lt;/p&gt;

&lt;p&gt;Improving code quality doesn’t have to be stressful. Take a break, use some tools, ask for feedback, and prioritize quality. With these last-minute tips, you can submit your PR with ease and feel proud of your code. Happy coding!&lt;/p&gt;

</description>
      <category>github</category>
      <category>developmentexperience</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>The Power of Open-Source Software: My Story with Ubuntu</title>
      <dc:creator>Tech Tim (@TechTim42)</dc:creator>
      <pubDate>Wed, 15 Mar 2023 17:00:00 +0000</pubDate>
      <link>https://forem.com/timhub/the-power-of-open-source-software-my-story-with-ubuntu-2hc6</link>
      <guid>https://forem.com/timhub/the-power-of-open-source-software-my-story-with-ubuntu-2hc6</guid>
      <description>&lt;p&gt;Ubuntu is a popular open-source operating system that has been gaining traction among computer enthusiasts and businesses alike. It was first released in 2004 and has since become one of the most widely used Linux-based operating systems in the world. The operating system is known for its ease of use, stability, and security features, which have made it a favorite among many users.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A1400%2F0%2AlX6aqDc-osFgmZWr" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A1400%2F0%2AlX6aqDc-osFgmZWr" alt="Ubuntu Terminal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ubuntu and Me
&lt;/h2&gt;

&lt;p&gt;When I first started using Ubuntu in 2011, I was drawn to its user-friendly interface and stability. As someone who was interested in technology and open-source software, Ubuntu offered a unique opportunity to explore a different kind of computing experience.&lt;/p&gt;

&lt;p&gt;I was impressed with the wide range of software available on Ubuntu, which was often free and open-source. This allowed me to experiment with different programs and tools without having to worry about licensing fees or proprietary software limitations.&lt;/p&gt;

&lt;p&gt;One of the most memorable experiences for me was receiving the Ubuntu OS CD in the mail. This physical representation of the operating system was a tangible reminder of the power of open-source software and the community that supported it.&lt;/p&gt;

&lt;p&gt;Ubuntu is Humanity — The Video on Ubuntu Image&lt;/p&gt;

&lt;p&gt;As I continued to use Ubuntu over the years, I became more involved in the Linux community. I participated in forums and online communities, sharing my experiences and learning from others. This sense of community was a crucial aspect of the open-source movement and helped to shape my understanding of technology.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ubuntuforums.org/" rel="noopener noreferrer"&gt;Ubuntu Forums A help and support forum for Ubuntu Linux. ubuntuforums.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://askubuntu.com/" rel="noopener noreferrer"&gt;Ask Ubuntu Q&amp;amp;A for Ubuntu users and developers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://launchpad.net/ubuntu" rel="noopener noreferrer"&gt;Ubuntu in Launchpad Ubuntu also includes a wide variety of software through its network of software repositories. Once your system is… launchpad.net&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Dead Personal Cloud Storage — Ubuntu One
&lt;/h2&gt;

&lt;p&gt;That time it is the cloud technology developing time, same for Canonical, it offered Ubuntu One for personal users.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A1400%2F0%2ATmFNUwesZAssVfam.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afit%3A1400%2F0%2ATmFNUwesZAssVfam.png" alt="Ubuntu One Screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ubuntu One Screenshot — Author &lt;a href="https://commons.wikimedia.org/wiki/User:Insulam_Simia" rel="noopener noreferrer"&gt;Insulam Simia&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ubuntu One is a cloud storage and synchronization service developed by Canonical, the company behind the Ubuntu operating system. It allows users to store their files and data online, and access them from any device that is connected to the internet.&lt;/p&gt;

&lt;p&gt;Ubuntu One provides 5 GB of free storage space, and users can purchase additional storage if needed. It supports a variety of file types, including documents, photos, music, and videos.&lt;/p&gt;

&lt;p&gt;One of the key features of Ubuntu One is its synchronization capabilities. Users can synchronize their files across multiple devices, such as desktops, laptops, and smartphones, so that changes made on one device are automatically reflected on all other devices. This makes it easy to keep files up-to-date and accessible from any device.&lt;/p&gt;

&lt;p&gt;In addition to its cloud storage and synchronization features, Ubuntu One also includes an integrated music store, where users can purchase and download music directly to their Ubuntu One accounts, which is simiar to Apple iTunes/Apple Store.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ubuntu Single Sign-on was rebranded under Ubuntu One in 2013.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Today, Ubuntu has become an integral part of my computing experience. It has helped me to develop my skills and knowledge of open-source software, and it has allowed me to take control of my computing experience in ways that were not possible with proprietary software.&lt;/p&gt;

&lt;p&gt;My story is just one example of how Ubuntu and open-source software have impacted individuals around the world. As more people continue to explore the benefits of open-source software, the community will continue to grow and innovate, creating new opportunities for collaboration and innovation.&lt;/p&gt;

&lt;h2&gt;
  
  
  References:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Ubuntu_One" rel="noopener noreferrer"&gt; Ubuntu One - Wikipedia Ubuntu One is an OpenID-based single sign-on service operated by Canonical Ltd. to allow users to log onto many… en.wikipedia.org&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ubuntu</category>
      <category>cloud</category>
      <category>opensource</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
