<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Noppanit</title>
    <description>My personal adventure</description>
    <link>https://www.noppanit.com</link>
    <atom:link href="https://www.noppanit.com/feed.xml" rel="self" type="application/rss+xml" />
    
      <item>
        <title>Eight Years of Silence</title>
        <description>&lt;p&gt;It’s been eight years since I last wrote here. That’s a long time to be quiet.&lt;/p&gt;

&lt;p&gt;I’ve thought about what to say in a “comeback” post. Should I apologize? Explain? Pretend nothing happened? None of those felt right. So instead, I’ll just tell you what actually happened.&lt;/p&gt;

&lt;h2 id=&quot;the-disappearance&quot;&gt;The Disappearance&lt;/h2&gt;

&lt;p&gt;In 2018, I joined big tech. I stopped writing. That’s it. It wasn’t dramatic. I didn’t burn out or rage quit blogging. I just stopped. The things I was learning felt too company-specific to share. The problems I was solving belonged to my employer. And honestly, I was drinking from a firehose. There was no bandwidth left for public reflection.&lt;/p&gt;

&lt;p&gt;That’s okay. I’ve made peace with it.&lt;/p&gt;

&lt;h2 id=&quot;the-shame-of-being-public&quot;&gt;The Shame of Being Public&lt;/h2&gt;

&lt;p&gt;But if I’m being really honest, there was something else going on too.&lt;/p&gt;

&lt;p&gt;I was ashamed. Not of the work itself, but of putting myself out there. I cared way too much about what people might think. What if my takes were wrong? What if someone from work saw it? What if I looked stupid?&lt;/p&gt;

&lt;p&gt;There’s this weird thing that happens when you stay quiet for long enough. You start believing that asking for help is weakness. That showing uncertainty is failure. That the only acceptable version of yourself is the one that already has everything figured out.&lt;/p&gt;

&lt;p&gt;I don’t know when I started believing that. But somewhere along the way, I did.&lt;/p&gt;

&lt;h2 id=&quot;the-pendulum&quot;&gt;The Pendulum&lt;/h2&gt;

&lt;p&gt;Somewhere along the way, I also became an engineering manager. This was the harder transition to make sense of. There’s this piece by Charity Majors called &lt;a href=&quot;https://charity.wtf/2017/05/11/the-engineer-manager-pendulum/&quot;&gt;https://charity.wtf/2017/05/11/the-engineer-manager-pendulum&lt;/a&gt; that finally gave me language for what I’d been experiencing. The core insight is that management isn’t a promotion. It’s a career change. And the best leaders are the ones who swing back and forth. Building, then managing, then building again.&lt;/p&gt;

&lt;p&gt;What I’ve learned is that being an engineering manager isn’t about “managing people.” That framing has always felt incomplete to me. It’s really about being a tech lead with people skills. It’s about gathering humans to finish a project together. It’s about understanding the business domain deeply enough to make the right technical tradeoffs. The skills compound. Time spent as an IC makes you a better manager. Time spent managing makes you a better IC. The pendulum isn’t a step backward. It’s forward momentum in a different direction.&lt;/p&gt;

&lt;h2 id=&quot;still-falling-behind&quot;&gt;Still Falling Behind&lt;/h2&gt;

&lt;p&gt;Here’s the thing though. Even after years of learning finance, diving into AI and LLMs, building infrastructure at scale, I still felt empty. I still felt like I was falling behind.&lt;/p&gt;

&lt;p&gt;Everyone around me seemed to be moving. New jobs. New titles. New companies. LinkedIn became a highlight reel of promotions and “excited to announce” posts. Meanwhile, I was at the same company, doing what felt like variations of the same work.&lt;/p&gt;

&lt;p&gt;The comparison trap is real. It measures your career against everyone else’s curated narrative. And it’s exhausting.&lt;/p&gt;

&lt;h2 id=&quot;finding-a-different-kind-of-community&quot;&gt;Finding a Different Kind of Community&lt;/h2&gt;

&lt;p&gt;What actually helped was finding Substack.&lt;/p&gt;

&lt;p&gt;I know that sounds like I’m about to pitch you something, but I’m not. What I found there was genuinely life-changing, and it wasn’t the platform itself. It was the community.&lt;/p&gt;

&lt;p&gt;People on Substack build shamelessly. They share half-formed ideas. They write about failures. They ask for help without apologizing for it. The vibe is completely different from Reddit or Blind or X, where everyone seems to be tearing each other down. On Substack, people lift each other up when they’re struggling.&lt;/p&gt;

&lt;p&gt;That was new for me. I didn’t know communities like that existed online anymore.&lt;/p&gt;

&lt;h2 id=&quot;building-again&quot;&gt;Building Again&lt;/h2&gt;

&lt;p&gt;The other thing that changed was AI. It made building fun again.&lt;/p&gt;

&lt;p&gt;I’m not saying this as hype. I’m saying it as someone who just migrated an entire blog from Octopress to modern Jekyll with essentially one prompt. Something that would have taken me a weekend of yak-shaving, searching Stack Overflow, debugging Ruby version conflicts, fixing broken gems, took an afternoon.&lt;/p&gt;

&lt;p&gt;The friction is gone. When I want to code something now, I just code it. I open Claude Code and start building. The iteration loop is so much tighter. The activation energy to start a project dropped from “do I really want to spend my Saturday on this?” to “let me just try it.”&lt;/p&gt;

&lt;p&gt;This is the first time in years I’ve felt genuinely excited about side projects. Not because AI writes perfect code. It doesn’t. But because the bottleneck shifted. It’s no longer about remembering syntax or searching for the right library. It’s about knowing what you want to build.&lt;/p&gt;

&lt;h2 id=&quot;what-i-actually-learned&quot;&gt;What I Actually Learned&lt;/h2&gt;

&lt;p&gt;Looking back, I wasn’t stuck. I was deepening. There’s a difference between stagnation and mastery. Sometimes staying in place means going deeper instead of wider. Sometimes the growth isn’t visible on a resume.&lt;/p&gt;

&lt;p&gt;And sometimes, the pendulum is just gathering momentum for the next swing.&lt;/p&gt;

&lt;h2 id=&quot;whats-next&quot;&gt;What’s Next&lt;/h2&gt;

&lt;p&gt;I don’t know exactly what this blog becomes now. I’m not going to promise a posting schedule or commit to a content strategy. That’s not how I work.&lt;/p&gt;

&lt;p&gt;But I’m building again. I’m thinking out loud again. And I’m trying to care a little less about what people think.&lt;/p&gt;

&lt;p&gt;After eight years of silence, that feels like enough.&lt;/p&gt;

&lt;p&gt;Let’s see where it goes.&lt;/p&gt;
</description>
        <pubDate>Thu, 01 Jan 2026 00:00:00 +0000</pubDate>
        <link>https://www.noppanit.com/posts/eight-years-of-silence</link>
        <guid isPermaLink="true">https://www.noppanit.com/posts/eight-years-of-silence</guid>
      </item>
    
      <item>
        <title>Back to building</title>
        <description>&lt;p&gt;After a long hiatus, I’m back to building and writing again.&lt;/p&gt;

&lt;p&gt;I’ve recently refactored this entire blog from Octopress to pure Jekyll, which was quite a journey.&lt;/p&gt;

&lt;p&gt;Stay tuned!&lt;/p&gt;
</description>
        <pubDate>Tue, 30 Dec 2025 00:00:00 +0000</pubDate>
        <link>https://www.noppanit.com/posts/back-to-building</link>
        <guid isPermaLink="true">https://www.noppanit.com/posts/back-to-building</guid>
      </item>
    
      <item>
        <title>My Minimalist Phone Screen</title>
        <description>&lt;h1 id=&quot;why&quot;&gt;Why?&lt;/h1&gt;
&lt;p&gt;It first started when I decided to delete almost all of my social networks (Facebook, Instagram and Pinterest) to reduce all of the mindlessly scrolling through my phone. Later that year, I was introduced to this book &lt;a href=&quot;https://www.amazon.com/dp/B00KK0PICK/ref=dp-kindle-redirect?_encoding=UTF8&amp;amp;btkr=1&quot;&gt;The life-changing magic of tidying up&lt;/a&gt; which I haven’t read it fully but I get the concept of the method. Then I began the journey of tidying up my room, closest and my desk setup. I sold my mechanical keyboard (I know!) and I went all wireless. I haven’t got the blog for those up yet as I’m still in the process. I moved on to tidy up my phone (iPhone 6s) because I feel like it’s way easier to do.&lt;/p&gt;

&lt;h2 id=&quot;apps&quot;&gt;Apps&lt;/h2&gt;
&lt;p&gt;The beginning of all thing; Apps. I’m still experimenting with this setup as I don’t want to go to absolute minimum just yet.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/wp-content/uploads/2018/06/iphone-screen.PNG&quot; alt=&quot;iPhone Screen 2018&quot; /&gt;&lt;/p&gt;

&lt;p&gt;These are the only apps I use in day to day life and work. I still download new apps from time to time but if I don’t use it for 2 weeks straight I will just delete it immediately.&lt;/p&gt;

&lt;p&gt;The apps that I’m still considering deleting are Twitter, Reddit, Spotify and banking app (I consolidate everything with Mint which I will blog about that next). The reason is I can use those on my laptop but I’m still keeping them just for the convenience. To all the front-end developers please make good webapp and don’t prompt me to download the native app unless it’s absolutely necessary.&lt;/p&gt;

&lt;p&gt;I’m thinking of deleting Spotify because I change my habit to listen to podcasts more when I’m working out or commuting. Podcasts are free and the Podcasts app that comes with the phone works just fine.&lt;/p&gt;

&lt;h2 id=&quot;no-notification&quot;&gt;No notification!&lt;/h2&gt;
&lt;p&gt;I turned off all of my notification from every app. If I really need it I will just have the Badge App Icon only. So, I won’t get any alert whatsoever. My phone is always on No Disturb mode and on silent.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/wp-content/uploads/2018/06/iphone-notification.PNG&quot; alt=&quot;iPhone Notification 2018&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;no-games&quot;&gt;No games&lt;/h2&gt;
&lt;p&gt;I decided to delete all of the games I have. I didn’t play much anyway and I feel like all the games these days need connection which doesn’t make much sense for my commute when I spend most of the time underground. If I’m going to be sitting on the plane for a longer period of time I might download games that I can just kill time. However, I realise that I would rather just catch up on my podcasts.&lt;/p&gt;

&lt;h2 id=&quot;web-apps&quot;&gt;Web apps&lt;/h2&gt;
&lt;p&gt;I experimented with this by deleting YouTube. Now I’m using the Web app version instead of the native app. It’s been great even though the experience of the app is not that great but I get what I wanted which is watching videos. I also switch to use the web version of hackernews which is my source of getting latest tech-related news.&lt;/p&gt;

&lt;h2 id=&quot;download-on-the-go&quot;&gt;Download on the go&lt;/h2&gt;
&lt;p&gt;With the fast connection that we have these days, most of the time I would just download the app as needed. For example, if I get lazy one day I would just download Lyft or Uber to get home. If I’m going to travel I would download Booking.com or AirBnb or other related apps and delete them after completing the trip.&lt;/p&gt;

&lt;h2 id=&quot;go-native&quot;&gt;Go native&lt;/h2&gt;
&lt;p&gt;What I mean by that is I use whatever comes with the phone. For example, I would just use Weather app rather than downloading other app. Or I would just use Stock rather than Yahoo Financial. I find that all the advanced things I really need, I would get a better version on my laptop. I use to have Adobe Lightroom but I found out that the functionality that comes with iPhone is more than enough for my need. If I really want a heavy editing I would rather just use my laptop.&lt;/p&gt;

&lt;h2 id=&quot;benefits&quot;&gt;Benefits?&lt;/h2&gt;
&lt;p&gt;Apart from everything looks clean, my phone is fast because I still have 30GB left on my device out of 64GB. I often upload all my photos to my laptop so I free up space. The battery life is also great because I don’t have all the apps constantly pulling data in the background. I also don’t have the need to upgrade my phone so I save some \(\) to invest in Apple and hopefully I get 7% return :-).&lt;/p&gt;

&lt;p&gt;I also feel like I don’t miss out on anything. I still get messages from my friends and coworkers. I still get in touch with my family. I can still be productive when needed. I can still keep myself up-to-date with my financial or what’s going on in the world. I don’t live in the woods just yet :-)&lt;/p&gt;

&lt;h2 id=&quot;inspiration&quot;&gt;Inspiration&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://betterhumans.coach.me/beautility-my-ultimate-iphone-setup-1b3dd0c588a0&quot;&gt;https://betterhumans.coach.me/beautility-my-ultimate-iphone-setup-1b3dd0c588a0&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://wellbeing.google/&quot;&gt;https://wellbeing.google/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 25 Jun 2018 00:00:00 +0000</pubDate>
        <link>https://www.noppanit.com/posts/my-minimalist-phone-screen</link>
        <guid isPermaLink="true">https://www.noppanit.com/posts/my-minimalist-phone-screen</guid>
      </item>
    
      <item>
        <title>So, You Want to Understand Recursion - Part one</title>
        <description>&lt;p&gt;I’m studying recursion as part of my learning about Algorithms and Data Structures. This is my attempt to explain the steps I took to learn the topic and I hope it will benefit anyone who comes across this post in the future.&lt;/p&gt;

&lt;p&gt;For those who are unfamiliar with recursion, here is a good introductory &lt;a href=&quot;https://www.youtube.com/watch?v=HXNhEYqFo0o&amp;amp;t=321s&quot;&gt;video&lt;/a&gt; that really captures the history and core concepts of recursion.&lt;/p&gt;

&lt;p&gt;I have also found this &lt;a href=&quot;http://pythontutor.com/visualize.html#mode=edit&quot;&gt;site&lt;/a&gt; that helps in visualizing the step-by-step process of how a recursive program works. Alternatively, you can use a debugger on your IDE.&lt;/p&gt;

&lt;p&gt;This is an example of the visualization.&lt;/p&gt;

&lt;iframe width=&quot;800&quot; height=&quot;500&quot; frameborder=&quot;0&quot; src=&quot;https://pythontutor.com/iframe-embed.html#code=def%20factorial%28n%29%3A%0A%20%20%20%20if%20n%20%3D%3D%200%3A%0A%20%20%20%20%20%20%20%20return%201%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20return%20n%20*%20factorial%28n-1%29%0A%20%20%20%20%20%20%20%20%0Afactorial%285%29&amp;amp;codeDivHeight=400&amp;amp;codeDivWidth=350&amp;amp;cumulative=false&amp;amp;curInstr=0&amp;amp;heapPrimitives=false&amp;amp;origin=opt-frontend.js&amp;amp;py=3&amp;amp;rawInputLstJSON=%5B%5D&amp;amp;textReferences=false&quot;&gt; &lt;/iframe&gt;

&lt;p&gt;Of all the books and websites I’ve come across, the most efficient method to learn about recursion is to visualize the execution of the program and practice A LOT.&lt;/p&gt;

&lt;p&gt;Recursion is an important foundational concept for other complex algorithms such as Dynamic Programming, Backtracking or Divide and Conquer, which I’ll cover in the upcoming posts. It will benefit you greatly if you understand the fundamentals of this simple algorithm. So, let’s dive in.&lt;/p&gt;

&lt;h3 id=&quot;types-of-recursions&quot;&gt;&lt;a href=&quot;https://www.amazon.com/Introduction-Recursive-Programming-Manuel-Rubio-Sanchez/dp/1498735282&quot;&gt;Types of Recursions&lt;/a&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Linear recursion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Linear recursion is a function where a method calls itself only once. An example of this type of recursion is the &lt;em&gt;factorial&lt;/em&gt; problem.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Tail recursion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tail recursion is the same as Linear recursion, but calling the recursion is the last operation of the function. For example:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
def print(n):
    if n == 0:
        return
    print(n)
    print(n - 1)

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

&lt;ul&gt;
  &lt;li&gt;Multiple recursion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Multiple recursion happens when a method calls itself multiple times. An example of this type of recursion is the &lt;em&gt;fibonacci&lt;/em&gt; number.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Mutual recursion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mutual recursion happens when functions call each other.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Nested recursion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Ackermann_function&quot;&gt;Ackermann function&lt;/a&gt; is an example of nested recursion where the argument of the function is the function itself. I won’t go into the details of this function since I haven’t found many cases of this type of recursion except for &lt;a href=&quot;https://www.youtube.com/watch?v=i7sm9dzFtEI&amp;amp;t=758s&quot;&gt;this&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is not necessary to memorize the different types of recursion as it won’t really help you to solve the problem, however, it is good to know the keywords so that you can use them to do a web-search on the problem later on.&lt;/p&gt;

&lt;h3 id=&quot;the-factorial-problem&quot;&gt;The factorial problem.&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Factorial&quot;&gt;Factorial&lt;/a&gt; is the product of all positive integers less than or equal to &lt;em&gt;n&lt;/em&gt;. For example:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
5! = 5 x 4 x 3 x 2 x 1

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

&lt;p&gt;It could be written in Python like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n-1)

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

&lt;p&gt;The code reads like this: When n equals to 0 we return 1, otherwise, we return a product of &lt;em&gt;n&lt;/em&gt; and &lt;em&gt;factorial(n-1)&lt;/em&gt;, which means we subtract n by 1 and call the function again. We repeat this process until the number equals to 0, when the function will start to unwind.&lt;/p&gt;

&lt;h3 id=&quot;how-to-solve-recursion&quot;&gt;How to solve recursion.&lt;/h3&gt;

&lt;h4 id=&quot;base-case&quot;&gt;Base case&lt;/h4&gt;

&lt;p&gt;What does base case mean? Every recursion function needs to have at least one base case to end the program. Otherwise, the program will run forever and eventually it will be terminated by your compiler. For example, if you run the following in your IDE:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
def factorial(n):
    return n * factorial(n-1)

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

&lt;p&gt;You will get error like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
RecursionError: maximum recursion depth exceeded

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

&lt;p&gt;And almost all recursion functions will have a skeleton/template like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
def function(some_arguments):
    if (base case):
        // do something
    else
        // call itself or other function 

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

&lt;h4 id=&quot;sub-problem&quot;&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Overlapping_subproblems&quot;&gt;Sub problem&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;What does it mean? It means that your problem has to be able to be broken down into smaller problems in order for the problem to be solved recursively.&lt;/p&gt;

&lt;p&gt;For example, in the factorial function, the smaller version of &lt;em&gt;factorial(5)&lt;/em&gt; is &lt;em&gt;factorial(5-1)&lt;/em&gt;. If you want to write a program to sum the values from an array of integers such as:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
nums = [1, 2, 3, 4, 5]

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

&lt;p&gt;, the sub problem of this program would be that we need to make the array smaller by increasing the position/index of the array. When the index hits the end of the array and as the program unwinds we then add up the number being returned from the function.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
def summation(nums, size):
    if size == 0:
        return nums[size]
    return summation(nums, size - 1) + nums[size]


if __name__ == &apos;__main__&apos;:
    nums = [1, 2, 3, 4, 5, 6]
    print(summation(nums, len(nums)))

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

&lt;p&gt;In conclusion, when you approach a recursion problem, you need to be thinking: how can I break this problem down into smaller chunks, and as the program unwinds how can I capture the result of each small problem?&lt;/p&gt;

&lt;h3 id=&quot;reference&quot;&gt;Reference&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=gl3emqCuueQ&amp;amp;list=PLFE6E58F856038C69&amp;amp;index=8&quot;&gt;Lecture 8 from Stanford&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=uFJhEPrbycQ&amp;amp;list=PLFE6E58F856038C69&amp;amp;index=9&quot;&gt;Lecture 9 from Stanford&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=NdF1QDTRkck&amp;amp;index=10&amp;amp;list=PLFE6E58F856038C69&quot;&gt;Lecture 10 from Stanford&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=p-gpaIGRCQI&amp;amp;list=PLFE6E58F856038C69&amp;amp;index=11&quot;&gt;Lecture 11 from Stanford&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;practice&quot;&gt;Practice&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://codingbat.com/java/Recursion-1&quot;&gt;http://codingbat.com/java/Recursion-1&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://codingbat.com/java/Recursion-2&quot;&gt;http://codingbat.com/java/Recursion-2&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/mirandaio/codingbat/tree/master/java&quot;&gt;Solution for coding bat&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;books&quot;&gt;Books&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.amazon.com/Thinking-Recursively-Java-Eric-Roberts/dp/0471701467&quot;&gt;Thinking Recursively&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.amazon.com/Programming-Abstractions-C-Eric-Roberts/dp/0133454843&quot;&gt;Programming abstractions in c++&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.amazon.com/Introduction-Recursive-Programming-Manuel-Rubio-Sanchez/dp/1498735282&quot;&gt;Introduction to recursive programming&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 03 Jan 2018 02:29:20 +0000</pubDate>
        <link>https://www.noppanit.com/posts/so-you-want-to-understand-recursion-part-one</link>
        <guid isPermaLink="true">https://www.noppanit.com/posts/so-you-want-to-understand-recursion-part-one</guid>
      </item>
    
      <item>
        <title>My resolutions for 2018</title>
        <description>&lt;h1 id=&quot;reflections-on-2016&quot;&gt;Reflections on &lt;a href=&quot;https://www.noppanit.com/posts/2016&quot;&gt;2016&lt;/a&gt;&lt;/h1&gt;

&lt;h2 id=&quot;fitness-psychically-and-mentally&quot;&gt;Fitness, psychically and mentally.&lt;/h2&gt;

&lt;p&gt;I stagnated physically. I didn’t increase any of my limits from last year. My mind was also really cluttered with personal issues.&lt;/p&gt;

&lt;h2 id=&quot;spanish&quot;&gt;Spanish&lt;/h2&gt;

&lt;p&gt;I didn’t follow through with my Spanish.&lt;/p&gt;

&lt;h2 id=&quot;become-a-data-scientist&quot;&gt;Become a Data Scientist&lt;/h2&gt;

&lt;p&gt;I didn’t become Data Scientist but I did joined Conde Nast as a Data Engineer which I work closely with Machine Learning engineers and Data Scientists. From this I realised that I enjoy building product and architecture more. On this point I don’t think I’m going to chase after this in 2018&lt;/p&gt;

&lt;h2 id=&quot;travel&quot;&gt;Travel&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Argentina&lt;/li&gt;
  &lt;li&gt;Mt. Rainer (More on this later)&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;reflections-on-2017&quot;&gt;Reflections on 2017&lt;/h1&gt;

&lt;p&gt;2017 was a painful year for me. I didn’t stick to my plan and I was completely detailed. One thing that I think I did great was investment. I opened a brokerage  account and I started investing with automatic deposit from my paycheck. I also set aside 401K and Roth.&lt;/p&gt;

&lt;p&gt;I did one 5K run and I finished it with 10:37 /mile. It’s a good start for me.&lt;/p&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;goals-for-2018&quot;&gt;Goals for 2018&lt;/h1&gt;

&lt;h2 id=&quot;career&quot;&gt;Career&lt;/h2&gt;

&lt;div style=&quot;max-width:854px&quot;&gt;&lt;div style=&quot;position:relative;height:0;padding-bottom:56.25%&quot;&gt;&lt;iframe src=&quot;https://embed.ted.com/talks/atul_gawande_want_to_get_great_at_something_get_a_coach&quot; width=&quot;854&quot; height=&quot;480&quot; style=&quot;position:absolute;left:0;top:0;width:100%;height:100%&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Atul talked about if you want to be great at something; Get a coach. This talk made me realised that I really wanted to improve my career professionally. More on this later.&lt;/p&gt;

&lt;p&gt;Some of the point that I want to improve upon.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Be more mindful. I realised one thing about myself. When I read or learn something I tend to skim instead of going deep into the subject. This create an illusion that I have learned something. The fact is I didn’t learn anything at all. Also, I’m also going to be more disciplined about using pomodoro.&lt;/li&gt;
  &lt;li&gt;Read more both technical and soft skills.&lt;/li&gt;
  &lt;li&gt;Invest more in myself. I’m getting a coach.&lt;/li&gt;
  &lt;li&gt;Talk at a conference. This is my personal goal that I wanted to get better at public speaking.&lt;/li&gt;
  &lt;li&gt;Learn Blockchain. 2017 is a big year for Bitcoin but I’m more interested in the technology behind it. I believe it’s going to create something more disruptive and bigger than Bitcoin.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;fitness-physically-and-mentally&quot;&gt;Fitness, physically and mentally&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Run half marathon. I decided to take baby step on this instead of going for a full marathon.&lt;/li&gt;
  &lt;li&gt;Fix my posture. Many people have told me that I slouch. I need to come up with a plan to fix this.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;This post took 2 pomodoros to complete&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Fri, 29 Dec 2017 20:01:06 +0000</pubDate>
        <link>https://www.noppanit.com/posts/my-resolutions-for-2018</link>
        <guid isPermaLink="true">https://www.noppanit.com/posts/my-resolutions-for-2018</guid>
      </item>
    
      <item>
        <title>How I learn to love awk</title>
        <description>&lt;h2 id=&quot;problem-statement&quot;&gt;Problem statement&lt;/h2&gt;

&lt;p&gt;I’m writing a Jenkins job to produce a file with a list of canonical urls from two separate sources. One source looks like this&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
File brand_urls

&quot;url1&quot;,&quot;brand&quot;
&quot;url2&quot;,&quot;brand&quot;
&quot;url3&quot;,&quot;brand1&quot;

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

&lt;p&gt;The second looks like this&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
File url.json after manipulation using jq

The source looks like this

[{
  slug: &quot;brand&quot;,
  ...,
  domain: {
    production: &apos;www.domain.com&apos;
  }
 }, {
  slug: &quot;brand1&quot;,
  ...,
  domain: {
    production: &apos;www.domain1.com&apos;
}]

# echo $BRAND_JSON | jq -r &apos;.[] | [.domain.production,.slug] | @csv&apos; &amp;gt;&amp;gt; slug.json

&quot;domain&quot;,&quot;brand&quot;
&quot;doamin1&quot;,&quot;brand1&quot;

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

&lt;p&gt;What I want is&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&quot;domain/url1&quot;
&quot;domain/url2&quot;
&quot;domain1/url3&quot;

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

&lt;p&gt;Basically, I want to join two files together by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;brand&lt;/code&gt; which I could have done that in SQL.&lt;/p&gt;

&lt;p&gt;So my initial thought would be something like this&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;nv&quot;&gt;BRAND_JSON&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;curl url.json&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt; 

&lt;span class=&quot;k&quot;&gt;while &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;IFS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; line
&lt;span class=&quot;k&quot;&gt;do
  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BRAND&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$line&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-F&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,&apos;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;{print $2}&apos;&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;s/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;//g&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;URI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$line&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-F&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;,&apos;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;{print $1}&apos;&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;s/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;//g&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$BRAND&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;DOMAIN&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$BRAND_JSON&lt;/span&gt; | jq &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;.[] | select(.slug==&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BRAND&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;) | .domain.production&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$DOMAIN&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$URI&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;https://&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DOMAIN&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$URI&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; urls
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt; &amp;lt; &lt;span class=&quot;s2&quot;&gt;&quot;brand_urls&quot;&lt;/span&gt;

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

&lt;p&gt;This is way too slow because I have about 900k of urls to filter and every url will do a O(n) search. Also, I created a lot of sub-shells&lt;/p&gt;

&lt;p&gt;And I thought hmm if I can make that a constant operation using some kind of Map then it would be a lot faster. I immediately thought of Map or associative array but my shell doesn’t have associative just yet. People might wonder why can’t I just use python or node script to manipulate that. I could have but I just want a script to run in Jenkins and bash is available already. I don’t have to install any runtime.&lt;/p&gt;

&lt;h2 id=&quot;awk-to-the-rescue&quot;&gt;Awk to the rescue&lt;/h2&gt;
&lt;p&gt;Awk already has associate array!&lt;/p&gt;

&lt;p&gt;Here’s my updated version of the code&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;nv&quot;&gt;INPUTFILE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;slug.json&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;DATAFILE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;brand_urls&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;OUTFILE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;all_urls&quot;&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;BEGIN {
  # mapping brand.json
  while (getline &amp;lt; &quot;&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$INPUTFILE&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;&quot;)
  {
    split($0,ft,&quot;,&quot;);
    domain=ft[1];
    gsub(/&quot;/, &quot;&quot;, domain);
    slug=ft[2];
    gsub(/&quot;/, &quot;&quot;, slug);
    key=slug;
    data=domain;
    domainMap[key]=data;
  }
  close(&quot;&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$INPUTFILE&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;&quot;);
  while (getline &amp;lt; &quot;&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DATAFILE&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;&quot;)
    {
      split($0,ft,&quot;,&quot;);
      uri=ft[1];
      gsub(/&quot;/, &quot;&quot;, uri);
      slug=ft[2];
      gsub(/&quot;/, &quot;&quot;, slug);
      domain=domainMap[slug]; 
      printf &quot;https://%s/%s\n&quot;, domain, uri &amp;gt; &quot;&apos;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$OUTFILE&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;&quot;;
    }
}&apos;&lt;/span&gt;

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

&lt;p&gt;I copied the script from &lt;a href=&quot;https://magvar.wordpress.com/2011/05/18/awking-it-how-to-load-a-file-into-an-array-in-awk/&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
        <pubDate>Sat, 14 Oct 2017 14:24:39 +0000</pubDate>
        <link>https://www.noppanit.com/posts/how-i-learn-to-love-awk</link>
        <guid isPermaLink="true">https://www.noppanit.com/posts/how-i-learn-to-love-awk</guid>
      </item>
    
      <item>
        <title>Lower your Redis memory footprint by a few lines of code</title>
        <description>&lt;p&gt;If you have Redis as your cache for your application you might want to lower your memory footprint by compressing your data. This will save you at least 50% of your memory usage for your Redis which will save you money.&lt;/p&gt;

&lt;p&gt;The code sample is for node.js but the concept work for any language.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;zlib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;zlib&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;redis&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Promise&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bluebird&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;promisifyAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;RedisClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;promisifyAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Multi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;expiration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;expire&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;expiration&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;expirationInSeconds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;zipAsync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;compressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;compressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;base64&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;compressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;redisClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setexAsync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;expire&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;compressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;redisClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getAsync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cachedResponse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cachedResponse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;gunzipAsync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cachedResponse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;base64&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;// Just in case if any cache is not compressed&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cachedResponse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

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

&lt;p&gt;You don’t need to use Bluebird if you don’t want to.&lt;/p&gt;

&lt;p&gt;Now the problem is I can’t just go in to my Redis and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Get ${key}&lt;/code&gt; I want because it won’t be readable. You can just do this.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;redis-cli &lt;span class=&quot;nt&quot;&gt;-h&lt;/span&gt; 127.0.0.1 GET &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;YOUR_KEY&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;base64&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-D&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;gzip&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; | jq
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jq&lt;/code&gt; because I &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JSON.stringify&lt;/code&gt; my value&lt;/p&gt;

&lt;p&gt;We lower our cache node from 16GB to just 3GB.&lt;/p&gt;
</description>
        <pubDate>Tue, 18 Apr 2017 18:48:38 +0000</pubDate>
        <link>https://www.noppanit.com/posts/lower-your-redis-memory-footprint-by-a-few-lines-of-code</link>
        <guid isPermaLink="true">https://www.noppanit.com/posts/lower-your-redis-memory-footprint-by-a-few-lines-of-code</guid>
      </item>
    
      <item>
        <title>Pay in local currency while you are travelling. It is cheaper</title>
        <description>&lt;h2 id=&quot;should-you-pay-in-local-or-home-currency-while-travelling&quot;&gt;Should you pay in local or home currency while travelling?&lt;/h2&gt;
&lt;p&gt;Short answer. Pay in local currency. For example, I have a credit card from the US and I’m going to be in Hong Kong for my vacation. I should pay in Hong Kong dollar.&lt;/p&gt;

&lt;p&gt;Long answer. There’s something about &lt;a href=&quot;https://en.wikipedia.org/wiki/Dynamic_currency_conversion&quot;&gt;DCC&lt;/a&gt; that you have to pay a small fee for the customer to see the amount in home currency in the receipt. Here’s an example.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/wp-content/uploads/2017/02/credit-card-receipt.jpg&quot; alt=&quot;Credit card receipt&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If I had paid in US dollar, I would have paid \$0.81 more. It doesn’t seem like a lot but it definitely adds up. I checked my credit card transaction and it showed \$19.33. It’s also good if you can get the card that doesn’t charge foreign transaction fee.&lt;/p&gt;
</description>
        <pubDate>Sun, 26 Feb 2017 03:20:49 +0000</pubDate>
        <link>https://www.noppanit.com/posts/pay-in-local-currency-while-you-are-travelling-it-is-cheaper</link>
        <guid isPermaLink="true">https://www.noppanit.com/posts/pay-in-local-currency-while-you-are-travelling-it-is-cheaper</guid>
      </item>
    
      <item>
        <title>OSX convert raw DNG to JPG</title>
        <description>&lt;h2 id=&quot;problem&quot;&gt;Problem&lt;/h2&gt;

&lt;p&gt;I like shooting raw and I’m still doing it. However, there’s a time when I had to Airdrop jpeg to my phone and I didn’t want to go into the trouble of import all the photos to Lightroom and export them again. So I turned to Google and here’s what I found.&lt;/p&gt;

&lt;p&gt;I’m lazy and I do most things in my terminal. Here’s the way you can do the same if you want to just quickly convert raw images to jpg.&lt;/p&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;You need &lt;a href=&quot;http://www.cybercom.net/~dcoffin/dcraw&quot;&gt;dcraw&lt;/a&gt; which you can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;brew&lt;/code&gt; to install&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
brew &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;dcraw

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

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;You need &lt;a href=&quot;http://www.ijg.org/&quot;&gt;cjpeg&lt;/a&gt; which is from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libjpeg&lt;/code&gt; so most likely you will have that already. Otherwise you can install by following these steps from &lt;a href=&quot;http://www.mutaku.com/wp/index.php/2011/02/cook-your-raw-photos-into-jpeg-with-linux/&quot;&gt;here&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Go into your raw photos folder and run this command&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;i &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do &lt;/span&gt;dcraw &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; | cjpeg &lt;span class=&quot;nt&quot;&gt;-quality&lt;/span&gt; 100 &lt;span class=&quot;nt&quot;&gt;-optimize&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-progressive&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;basename&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;.crw&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;.jpg&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This command will loop through all the files inside the folder and run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dcraw&lt;/code&gt; command for each file then pipe it through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cjpeg&lt;/code&gt; and same to the original name with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jpg&lt;/code&gt; extension.&lt;/p&gt;

&lt;p&gt;I didn’t really check the quality as I just wanted to quickly post on Twitter.&lt;/p&gt;

&lt;h3 id=&quot;reference&quot;&gt;Reference&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.mutaku.com/wp/index.php/2011/02/cook-your-raw-photos-into-jpeg-with-linux/&quot;&gt;http://www.mutaku.com/wp/index.php/2011/02/cook-your-raw-photos-into-jpeg-with-linux/&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Mon, 20 Feb 2017 06:23:19 +0000</pubDate>
        <link>https://www.noppanit.com/posts/osx-convert-raw-dng-to-jpg</link>
        <guid isPermaLink="true">https://www.noppanit.com/posts/osx-convert-raw-dng-to-jpg</guid>
      </item>
    
      <item>
        <title>Reservoir sampling</title>
        <description>&lt;p&gt;I have been working with Stream processing a lot lately. Here’s my usecase.&lt;/p&gt;

&lt;h2 id=&quot;problem&quot;&gt;Problem:&lt;/h2&gt;

&lt;p&gt;I have a stream of pageviews. But I don’t want to process every single pageview, because then I will process one pageview over and over again.
How do I sample the data so that I process just a subset of data but with equal probability of processing each pageview.&lt;/p&gt;

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

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[pageview1, pageview2, pageview1, pageview3]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now I want to choose 3 pageviews out of 4&lt;/p&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution:&lt;/h2&gt;
&lt;p&gt;We choose &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[pageview1, pageview2, pageview1]&lt;/code&gt; as the initial reservior. Then I choose pageview3 with a probability of 3/4&lt;/p&gt;

&lt;h2 id=&quot;code&quot;&gt;Code&lt;/h2&gt;
&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;samples&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;sampleSize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;pageviews&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;samples&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;sampleSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;samples&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rand&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;rand&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;sampleSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;samples&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;rand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I might not explain the math clearly, because I’m not very good at math. If you want to know more I recommend &lt;a href=&quot;https://gregable.com/2007/10/reservoir-sampling.html&quot;&gt;this&lt;/a&gt; and &lt;a href=&quot;https://jeremykun.com/2013/07/05/reservoir-sampling/&quot;&gt;this&lt;/a&gt; and &lt;a href=&quot;https://discuss.leetcode.com/topic/53753/brief-explanation-for-reservoir-sampling&quot;&gt;this&lt;/a&gt; and &lt;a href=&quot;http://austinrochford.com/posts/2014-11-30-reservoir-sampling.html&quot;&gt;this&lt;/a&gt;. There’s also my &lt;a href=&quot;https://stackoverflow.com/questions/42046581/is-sample-size-of-1-consider-reservoir-sampling/42053227?noredirect=1#comment71830111_42053227&quot;&gt;question&lt;/a&gt; on SO about proof.&lt;/p&gt;

</description>
        <pubDate>Mon, 20 Feb 2017 00:00:00 +0000</pubDate>
        <link>https://www.noppanit.com/posts/reservoir-sampling</link>
        <guid isPermaLink="true">https://www.noppanit.com/posts/reservoir-sampling</guid>
      </item>
    
  </channel>
</rss>
