<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Miya Liu - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Miya Liu - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 19 May 2026 22:44:45 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/miyaliu/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ freeCodeCamp is Launching a Podcast in Chinese ]]>
                </title>
                <description>
                    <![CDATA[ Hello, everyone! I am Miya Liu. And I'm excited to announce the launch of the freeCodeCamp Chinese Podcast. In this podcast, we'll bring you the inspiring learning and career development stories of developers, technical content creators, and other te... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/freecodecamp-podcast-in-chinese/</link>
                <guid isPermaLink="false">66d85aab29e30bc0ad477650</guid>
                
                    <category>
                        <![CDATA[ Chinese ]]>
                    </category>
                
                    <category>
                        <![CDATA[ freeCodeCamp.org ]]>
                    </category>
                
                    <category>
                        <![CDATA[ podcast ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Fri, 04 Aug 2023 09:53:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/08/----.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Hello, everyone! I am Miya Liu. And I'm excited to announce the launch of the <a target="_blank" href="https://freecodecamp-in-chinese.transistor.fm/">freeCodeCamp Chinese Podcast</a>.</p>
<p>In this podcast, we'll bring you the inspiring learning and career development stories of developers, technical content creators, and other tech professionals We'll also share their insights into the world of tech with you.</p>
<p>This week we'll release the first three episodes:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/LumixSync_copy_2022-11-06_065117_0000JpegFile.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Liu Rui with his daughter</em></p>
<h3 id="heading-ep-1-liu-rui-enjoy-coding-and-live-with-developers-mindsethttpswwwfreecodecamporgchinesenewsinterview-liu-rui-enjoy-coding-and-live-with-developer-mindset"><a target="_blank" href="https://www.freecodecamp.org/chinese/news/interview-liu-rui-enjoy-coding-and-live-with-developer-mindset">Ep. 1 - Liu Rui: Enjoy Coding and Live with Developer's Mindset</a></h3>
<p>Liu Rui is an engineer with 15 years of experience in Java development. Over the past few years, he has published many articles and video tutorials on the freeCodeCamp community publication and YouTube channel.</p>
<p>When Liu Rui was in junior high school, he was inspired to learn about computers and coding because of his father's enthusiasm for teaching himself coding. Then Liu Rui taught himself Java in university.</p>
<p>In this episode, he shares how he grows from a developer without confidence to a software architect, and how he lives with the wisdom he's gained from coding – not wanting to repeat himself, accepting imperfections, and compromising wisely. He also talks about teaching his daughters to code :)</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/papaya.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Papaya Huang</em></p>
<h3 id="heading-ep-2-papaya-huang-coding-is-my-hogwartshttpswwwfreecodecamporgchinesenewsinterview-papaya-coding-is-my-hogwarts"><a target="_blank" href="https://www.freecodecamp.org/chinese/news/interview-papaya-coding-is-my-hogwarts/">Ep. 2 - Papaya Huang: Coding is My Hogwarts</a></h3>
<p>Papaya taught herself to code in her thirties. Now, she is a front-end developer working with a remote team.</p>
<p>She is big fan of Harry Potter, and she feels that the process of exploring the world of code is quite like going to Hogwarts: even though there's a number of obstacles, she keeps solving problems and having fun in the process.</p>
<p>She talks about her love for coding in this episode, and how she has overcome various challenges as a learner. She also shares a bunch of useful and interesting books, video tutorials, and APIs.</p>
<figure><img src="https://chinese.freecodecamp.org/news/content/images/2023/08/WechatIMG43-1.png" class="kg-image" alt="Chen Zhicheng" width="600" height="400" loading="lazy"><figcaption>Chen Zhicheng</figcaption></figure>

<h3 id="heading-ep-3-chen-zhicheng-front-end-development-vs-back-end-developmenthttpswwwfreecodecamporgchinesenewsinterview-chen-zhi-cheng-mission-and-front-end-vs-back-end-development"><a target="_blank" href="https://www.freecodecamp.org/chinese/news/interview-chen-zhi-cheng-mission-and-front-end-vs-back-end-development/">Ep. 3 - Chen Zhicheng: Front End Development vs Back End Development</a></h3>
<p>Zhicheng is an experienced full-stack engineer. When he was in junior high school, he worked with his father to develop a grade management system for his school using Visual Basic. And while he was at university, he worked with his teacher to build a Q&amp;A platform to answer all kinds of questions from students.</p>
<p>In the first few years of his work, he always worked overtime, and his work and life were out of balance. So, he quit his job and became a "digital nomad". </p>
<p>After understanding the meaning of life a bit better, he completed all the freeCodeCamp certifications within one month, systematically studied front-end development and NodeJS, and got a job at a big company. Now, he works as a technical lead at a start-up.</p>
<p>In this episode, Zhicheng shares his learning and working experience, his insights into front-end and back-end development, and how he's exploring his life's mission.</p>
<h2 id="heading-see-you-in-the-freecodecamp-chinese-podcast">See You in the freeCodeCamp Chinese Podcast</h2>
<p>We plan to post one episode every Friday.</p>
<p>If you enjoy these episodes, please share the podcast with your friends. It will help us a lot. </p>
<p>We'd also appreciate it if you could leave us a 5-star review on the platform where you listen to this podcast. Your support is valuable to freeCodeCamp and will help us provide more coding education resources for free.</p>
<p>Start your coding journey at freeCodeCamp and share your stories along the way. If you'd like to share your own story in our podcast, please email us at <a target="_blank" href="mailto:chinese@freecodecamp.org">chinese@freecodecamp.org</a>.</p>
<p>Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn JavaScript Object-Oriented Programming by Building a Timer Application ]]>
                </title>
                <description>
                    <![CDATA[ In this article, you will learn JavaScript object-oriented programming by creating a simple timer application. Object-oriented programming is an important programming paradigm. It organizes code into objects which makes it easier to manage and mainta... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-javascript-object-oriented-programming/</link>
                <guid isPermaLink="false">66d85aae8acc348be2a44273</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Tue, 11 Apr 2023 17:06:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/04/---.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, you will learn JavaScript object-oriented programming by creating a simple timer application.</p>
<p>Object-oriented programming is an important programming paradigm. It organizes code into objects which makes it easier to manage and maintain your applications.</p>
<p>Many articles explain in detail the benefits of object-oriented programming and how you can use it to build applications.</p>
<p>But beginners may have questions: Why should I apply object-oriented programming? When should I use it?</p>
<p>This article will help beginners understand these questions by building the same timer functionality based on both procedural and object-oriented programming methods.</p>
<h2 id="heading-what-we-will-cover">What We Will Cover</h2>
<ul>
<li>HTML basics, such as DOM methods and DOM events</li>
<li>CSS basics, like flex layouts</li>
<li>JavaScript knowledge, such as regular expressions, <code>class</code>es, <code>constructor()</code>s, objects, the <code>this</code> keyword, the <code>setInterval()</code> method, event mechanisms, and so on.</li>
</ul>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-how-to-create-a-timer-interface-with-html-and-css">How to Create a Timer Interface with HTML and CSS</a></li>
<li><a class="post-section-overview" href="#heading-how-to-build-a-timer-using-procedural-programming">How to Build a Timer using Procedural Programming</a><ul>
<li><a class="post-section-overview" href="#heading-build-the-basic-functions">Build the Basic Functions</a></li>
<li><a class="post-section-overview" href="#heading-how-to-restrict-the-input-range-of-the-hours-minutes-and-seconds">How to Restrict the Input Range of the Hours, Minutes, and Seconds</a></li>
<li><a class="post-section-overview" href="#heading-how-to-optimize-the-format-of-the-hours-minutes-and-seconds">How to Optimize the Format of the Hours, Minutes, and Seconds</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-how-to-build-a-timer-using-object-oriented-programming">How to Build a Timer using Object-Oriented Programming</a><ul>
<li><a class="post-section-overview" href="#heading-new-timer-class">New Timer Class</a></li>
<li><a class="post-section-overview" href="#heading-timer-update">Timer Update</a></li>
<li><a class="post-section-overview" href="#heading-start-the-timer">Start the Timer</a></li>
<li><a class="post-section-overview" href="#heading-stop-the-timer">Stop the Timer</a></li>
<li><a class="post-section-overview" href="#heading-pause-the-timer">Pause the Timer</a></li>
<li><a class="post-section-overview" href="#heading-display-current-time">Display Current Time</a></li>
<li><a class="post-section-overview" href="#heading-create-object-instances">Create Object Instances</a></li>
<li><a class="post-section-overview" href="#heading-user-interface-interaction-with-functions">User Interface Interaction with Functions</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-how-to-add-the-event-mechanism-to-object-oriented-programming">How to Add the Event Mechanism to Object-Oriented Programming</a><ul>
<li><a class="post-section-overview" href="#heading-create-the-event-generator">Create the Event Generator</a></li>
<li><a class="post-section-overview" href="#heading-new-timer-class">New Timer Class</a></li>
<li><a class="post-section-overview" href="#heading-create-object-instances">Create Object Instances</a></li>
<li><a class="post-section-overview" href="#heading-user-interface-interaction-with-functions">User Interface Interaction with Functions</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h2 id="how-to-create-a-timer-interface-with-html-and-css">How to Create a Timer Interface with HTML and CSS</h2>

<p>First, let's write a basic timer interface with HTML and CSS, including an input field to display the time and a few buttons.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/image-70.png" class="center db" width="600" height="400" alt="image-70" loading="lazy"></p>
<p>The HTML looks like this:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Timer<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Timer<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"ipt"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"inputh"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"hour"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"inputm"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"minute"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"inputs"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"second"</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn-start"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"start_counting()"</span>&gt;</span>Start<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn-pause"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"pause_counting()"</span>&gt;</span>Pause<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn-stop"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"end_counting()"</span>&gt;</span>Stop<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"currentTime"</span>&gt;</span>current time: <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
</code></pre>
<p>The timer contains three input elements, with <code>id</code>s of <code>inputh</code>, <code>inputm</code> and <code>inputs</code>, and <code>type</code>s of <code>number</code>. These allow the user to enter the values of hours, minutes, and seconds.</p>
<p>Below the input field, three <code>button</code> elements start, pause, and stop the timer, respectively. </p>
<p>Each button has an <code>onclick</code> event. The property value of the <code>onclick</code> is a function, and we will write the code for this function in the JavaScript section. When the user clicks a button, the corresponding function is executed. </p>
<p>In JavaScript, we call the function by its name, so we need to put parentheses after the function name.</p>
<p>You can learn more about the <code>onclick</code> event in <a target="_blank" href="https://www.freecodecamp.org/news/html-button-onclick-javascript-click-event-tutorial/">this article</a>.</p>
<p>The <code>p</code> element below the button synchronizes the time in the input elements.</p>
<p>Let's add some simple CSS to the timer and style it:</p>
<pre><code class="lang-css">&lt;<span class="hljs-selector-tag">style</span>&gt;
    <span class="hljs-selector-class">.container</span> {
        <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> auto;
        <span class="hljs-attribute">width</span>: <span class="hljs-number">300px</span>;
        <span class="hljs-attribute">height</span>: <span class="hljs-number">300px</span>;
        <span class="hljs-attribute">display</span>: flex;
        <span class="hljs-attribute">flex-direction</span>: column;
        <span class="hljs-attribute">justify-content</span>: center;
        <span class="hljs-attribute">align-items</span>: center;
    }

    <span class="hljs-selector-class">.ipt</span> {
        <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> auto;
        <span class="hljs-attribute">display</span>: flex;
        <span class="hljs-attribute">justify-content</span>: center;
        <span class="hljs-attribute">align-items</span>: center;
    }

    <span class="hljs-selector-tag">input</span> {
        <span class="hljs-attribute">width</span>: <span class="hljs-number">100px</span>;
        <span class="hljs-attribute">height</span>: <span class="hljs-number">50px</span>;
        <span class="hljs-attribute">font-size</span>: <span class="hljs-number">20px</span>;
        <span class="hljs-attribute">text-align</span>: center;
    }

    <span class="hljs-selector-class">.btn</span> {
        <span class="hljs-attribute">margin</span>: <span class="hljs-number">10px</span>;
        <span class="hljs-attribute">display</span>: flex;
        <span class="hljs-attribute">justify-content</span>: center;
        <span class="hljs-attribute">align-items</span>: center;
    }

    <span class="hljs-selector-tag">button</span> {
        <span class="hljs-attribute">margin</span>: <span class="hljs-number">10px</span> <span class="hljs-number">10px</span>;
        <span class="hljs-attribute">width</span>: <span class="hljs-number">50px</span>;
        <span class="hljs-attribute">height</span>: <span class="hljs-number">30px</span>;
        <span class="hljs-attribute">font-size</span>: <span class="hljs-number">10px</span>;
    }

    <span class="hljs-selector-id">#currentTime</span> {
        <span class="hljs-attribute">margin</span>: <span class="hljs-number">10px</span>;
        <span class="hljs-attribute">color</span>: green;
    }
&lt;/<span class="hljs-selector-tag">style</span>&gt;
</code></pre>
<p>We use Flexbox to center the elements. Add the CSS below to the parent element:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">display</span>: <span class="hljs-selector-tag">flex</span>;
<span class="hljs-selector-tag">justify-content</span>: <span class="hljs-selector-tag">center</span>;
<span class="hljs-selector-tag">align-items</span>: <span class="hljs-selector-tag">center</span>;
</code></pre>
<p>This centers the child element horizontally and vertically, relative to the parent element.</p>
<p>You can see more information about <a target="_blank" href="https://www.freecodecamp.org/news/how-to-center-a-div-with-css-10-different-ways/">CSS Layout</a> in this article, or you can further style the timer as you like.</p>
<p>Next, we'll add the JavaScript code to start, pause, and stop the timer.</p>
<h2 id="timer-pp">How to Build a Timer using Procedural Programming</h2>

<h3 id="basic-functions"> Build the Basic Functions</h3>

<p>This code shows a timer program designed with an event-driven, procedural-oriented mindset consisting of:</p>
<ul>
<li>2 sets of global variables: the hour/minute/second variables and the return value of the <code>setInterval()</code> function</li>
<li>4 key functions: the event handlers for the start, pause, and stop buttons, and the execution function that is called in a loop during the countdown</li>
</ul>
<p>First, initialize the button state with the DOM method <code>document.getElementById().disabled</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// initialize button state</span>
<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"btn-pause"</span>).disabled = <span class="hljs-literal">true</span>;
<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"btn-stop"</span>).disabled = <span class="hljs-literal">true</span>;
</code></pre>
<p>Next, we define global variables to store hour, minute, and second values.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// define global variables</span>
<span class="hljs-keyword">var</span> timer = <span class="hljs-literal">null</span>; <span class="hljs-comment">// store the returned value of timer</span>
<span class="hljs-keyword">var</span> h = <span class="hljs-number">0</span>; <span class="hljs-comment">// store the value of hour</span>
<span class="hljs-keyword">var</span> m = <span class="hljs-number">0</span>; <span class="hljs-comment">// store the value of minute</span>
<span class="hljs-keyword">var</span> s = <span class="hljs-number">0</span>; <span class="hljs-comment">// store the value of second</span>
</code></pre>
<p>In the <code>start_counting()</code> function which starts the timer, we use <code>document.getElementById().value</code> to get the values of the elements with <code>id</code> of <code>inputh</code>, <code>inputm</code>, and <code>inputs</code>, respectively. These are the values of hours, minutes, and seconds entered by the user in the timer input field, and assign values to <code>h</code>, <code>m</code> and <code>s</code>.</p>
<p>Then we check the hour, minute, and second values entered by the user through the <code>if</code> statement. If the values are all equal to 0, or if one of the values is less than 0, it shows the popup message <code>The time entered is illegal!</code> and returns, and the program stops execution.</p>
<p>Assign the value <code>setInterval()</code> to the timer variable <code>timer</code>. This method takes two arguments, the first being a function and the second being a time in milliseconds. In this example, we specify that the timer executes a function <code>counting</code> every 1000 milliseconds (i.e., 1 second), which is described below.</p>
<p>For more information about the <code>setInterval()</code> method, you can see the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/setInterval">MDN docs</a>.</p>
<p>After that, change the state of buttons and input fields to prohibit users from re-entering numbers.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// define a function</span>
<span class="hljs-comment">// start the timer</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">start_counting</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// get the time entered or set a default value</span>
    h = +<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"inputh"</span>).value || h;
    m = +<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"inputm"</span>).value || m;
    s = +<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"inputs"</span>).value || s;

    <span class="hljs-comment">// check for illegal input</span>
    <span class="hljs-keyword">if</span> (
        (h == <span class="hljs-number">0</span> &amp;&amp; m == <span class="hljs-number">0</span> &amp;&amp; s == <span class="hljs-number">0</span>) ||
        (h &lt; <span class="hljs-number">0</span> || m &lt; <span class="hljs-number">0</span> || s &lt; <span class="hljs-number">0</span>)
    ) {
        alert(<span class="hljs-string">"The time entered is illegal!"</span>);
        <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-comment">// start the timer</span>
    timer = <span class="hljs-built_in">setInterval</span>(counting, <span class="hljs-number">1000</span>);

    <span class="hljs-comment">// change the state of buttons and input fields to prohibit users from re-entering numbers</span>
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"btn-start"</span>).disabled = <span class="hljs-literal">true</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"btn-pause"</span>).disabled = <span class="hljs-literal">false</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"btn-stop"</span>).disabled = <span class="hljs-literal">false</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"inputh"</span>).disabled = <span class="hljs-literal">true</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"inputm"</span>).disabled = <span class="hljs-literal">true</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"inputs"</span>).disabled = <span class="hljs-literal">true</span>;
}
</code></pre>
<p>Then, in the <code>pause_counting()</code> function, which is responsible for pausing the timer, you set the state of the buttons and input fields when the timer is paused, and call <code>clearInterval()</code> to remove the timer and stop the countdown.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// pause the timer</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">pause_counting</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// change the state of buttons and input fields to allow users to re-enter numbers</span>
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"btn-start"</span>).disabled = <span class="hljs-literal">false</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"btn-pause"</span>).disabled = <span class="hljs-literal">true</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"btn-stop"</span>).disabled = <span class="hljs-literal">false</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"inputh"</span>).disabled = <span class="hljs-literal">false</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"inputm"</span>).disabled = <span class="hljs-literal">false</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"inputs"</span>).disabled = <span class="hljs-literal">false</span>;

    <span class="hljs-comment">// pause the timer</span>
    <span class="hljs-built_in">clearInterval</span>(timer);
}
</code></pre>
<p>The <code>end_counting()</code> function ends the timer. It also calls <code>clearInterval()</code>, and resets the hours, minutes, and seconds to 0. The text below, "Current time:", is updated to "Timer stopped".</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// stop the timer</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">end_counting</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// change the state of buttons and input fields to allow users to re-enter numbers</span>
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"btn-start"</span>).disabled = <span class="hljs-literal">false</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"btn-pause"</span>).disabled = <span class="hljs-literal">true</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"btn-stop"</span>).disabled = <span class="hljs-literal">true</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"inputh"</span>).disabled = <span class="hljs-literal">false</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"inputm"</span>).disabled = <span class="hljs-literal">false</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"inputs"</span>).disabled = <span class="hljs-literal">false</span>;

    <span class="hljs-comment">// stop the timer</span>
    <span class="hljs-built_in">clearInterval</span>(timer);

    <span class="hljs-comment">// reset the time variables</span>
    h = <span class="hljs-number">0</span>;
    m = <span class="hljs-number">0</span>;
    s = <span class="hljs-number">0</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"currentTime"</span>).innerHTML = <span class="hljs-string">"Timer stopped"</span>;
}
</code></pre>
<p>Next is the <code>counting()</code> function, which is the function called in <code>setInterval()</code>. It checks if the hour, minute, or second is 0 with an <code>if</code> statement, and performs the relative action. </p>
<p>This is the conventional implementation for timers, and it is easy to understand with our experience in daily life, for example, when the number of seconds hits 0, it then becomes 59 by "borrowing" 1 from the number of minutes – like this: 00:03:02, 00:03:01, 00:03:00, 00:02:59...</p>
<p>The <code>setInterval()</code> method updates the values of <code>h</code>, <code>m</code> and <code>s</code> once per second. We synchronize the updated time in the <code>current time:</code> text by using <code>document.getElementById().innerHTML</code>.</p>
<p>Finally, the <code>if</code> statement checks the hour, minute and second values, and when all three values are 0, the <code>end_counting()</code> function and the <code>setTimeout()</code> function are executed. In the <code>setTimeout()</code> function, execute the popup message "Time is up!".</p>
<blockquote>
<p>Here's an interesting fact: you can try removing <code>setTimeout()</code> and running <code>alert("Time is up!")</code> directly after <code>end_counting()</code>,  you'll see that the popup blocks DOM rendering - that is, it pops up the "Time is up!" and then change the state of the button and input fields. When we use <code>setTimeout()</code>, these two actions happen synchronously. You can think about the function of <code>setTimeout()</code> here.</p>
</blockquote>
<p>If you want to learn more about the usage of <code>setTimeout()</code>, check out <a target="_blank" href="https://www.freecodecamp.org/news/javascript-wait-how-to-sleep-n-seconds-in-js-with-settimeout/">this article</a> on freeCodeCamp.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// countdown</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">counting</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// check if the second is 0</span>
    <span class="hljs-keyword">if</span> (s == <span class="hljs-number">0</span>) {
        <span class="hljs-comment">// check if the minute is 0 when the second is 0</span>
        <span class="hljs-keyword">if</span> (m == <span class="hljs-number">0</span>) {
            <span class="hljs-comment">// the entered time has already been checked for legality before starting the timer, so there is no need to check the value of the variable h again here</span>
            h--;
            m = <span class="hljs-number">59</span>;
            s = <span class="hljs-number">59</span>;
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-comment">// when the minute is not 0, the minute minus 1 and the second becomes 59</span>
            m--;
            s = <span class="hljs-number">59</span>;
        }
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-comment">// when the second is not 0, the second minus 1</span>
        s--;
    }

    <span class="hljs-comment">// display current time</span>
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"currentTime"</span>).innerHTML = <span class="hljs-string">"current time: "</span> + h + <span class="hljs-string">" h "</span> + m + <span class="hljs-string">" m "</span> + s + <span class="hljs-string">" s"</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"inputh"</span>).value = h;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"inputm"</span>).value = m;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"inputs"</span>).value = s;

    <span class="hljs-comment">// check if the second is 0</span>
    <span class="hljs-keyword">if</span> (s == <span class="hljs-number">0</span>) {
        <span class="hljs-comment">// when the second is 0, check if the minute is 0</span>
        <span class="hljs-keyword">if</span> (m == <span class="hljs-number">0</span>) {
            <span class="hljs-comment">// when the minute is 0, check if the hour is 0</span>
            <span class="hljs-keyword">if</span> (h == <span class="hljs-number">0</span>) {
                <span class="hljs-comment">// when the hour is 0, stop the timer</span>
                <span class="hljs-comment">// stop the timer</span>
                end_counting();
                <span class="hljs-comment">// execute popup in the next event loop to prevent it from blocking DOM rendering</span>
                <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
                    alert(<span class="hljs-string">"The time is up!"</span>);
                }, <span class="hljs-number">0</span>);
                <span class="hljs-keyword">return</span>;
            }
        }
    }
}
</code></pre>
<p>Sometimes the user may enter a negative number in the hour, minute, or second input fields, and the code alerts the user by popping up "The time entered is illegal!". Other times, the user may enter hours greater than 24, or minutes and seconds greater than 59, which doesn't work either.</p>
<p>In addition, to make the time display more beautiful, we may want to display the hours, minutes, and seconds as two digits.</p>
<p>We can improve the code above in two ways.</p>
<h3 id="inputs-range">How to Restrict the Input Range of the Hours, Minutes, and Seconds</h3>

<p>When the number of hours entered is greater than 24, we want to modify it to 24 automatically. Similarly, when it is less than 0, we want to modify it to 0.</p>
<p>And when the number of minutes and seconds entered is greater than 59, we want it to be automatically modified to 59. When it is less than 0, modify it to 0.</p>
<p>The event listener method <code>addEventListener()</code> is used here to execute the function when the <code>input</code> event occurs. <code>parseInt()</code> is also used to convert the input values to numeric types.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> inputh = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"inputh"</span>);
inputh.addEventListener(<span class="hljs-string">"input"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ 
    inputh.value = <span class="hljs-built_in">parseInt</span>(inputh.value||<span class="hljs-number">0</span>);
    <span class="hljs-keyword">if</span> (inputh.value &gt; <span class="hljs-number">24</span>) inputh.value = <span class="hljs-number">24</span>;
    <span class="hljs-keyword">if</span> (inputh.value &lt; <span class="hljs-number">0</span>) inputh.value = <span class="hljs-number">0</span>;
});

<span class="hljs-keyword">var</span> inputm = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"inputm"</span>);
inputm.addEventListener(<span class="hljs-string">"input"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    inputm.value = <span class="hljs-built_in">parseInt</span>(inputm.value||<span class="hljs-number">0</span>);
    <span class="hljs-keyword">if</span> (inputm.value &gt; <span class="hljs-number">59</span>) inputm.value = <span class="hljs-number">59</span>;
    <span class="hljs-keyword">if</span> (inputm.value &lt; <span class="hljs-number">0</span>) inputm.value = <span class="hljs-number">0</span>;
});

<span class="hljs-keyword">var</span> inputs = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"inputs"</span>);
inputs.addEventListener(<span class="hljs-string">"input"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    inputs.value = <span class="hljs-built_in">parseInt</span>(inputs.value||<span class="hljs-number">0</span>);
    <span class="hljs-keyword">if</span> (inputs.value &gt; <span class="hljs-number">59</span>) inputs.value = <span class="hljs-number">59</span>;
    <span class="hljs-keyword">if</span> (inputs.value &lt; <span class="hljs-number">0</span>) inputs.value = <span class="hljs-number">0</span>;
});
</code></pre>
<h3 id="inputs-format">How to Optimize the Format of the Hours, Minutes, and Seconds</h3>

<p>When the numbers of hours, minutes, or seconds are a single digit, we can prefix them with 0 by using a regular expression.</p>
<pre><code class="lang-javascript">h = h.toString();
m = m.toString();
s = s.toString();
<span class="hljs-keyword">if</span> (h.match(<span class="hljs-regexp">/^\d$/</span>)) { <span class="hljs-comment">// If the hour is a single digit, add 0 in the front</span>
    h = <span class="hljs-string">"0"</span> + h;
}
<span class="hljs-keyword">if</span> (m.match(<span class="hljs-regexp">/^\d$/</span>)) { <span class="hljs-comment">// If the minute is a single digit, add 0 in the front</span>
    m = <span class="hljs-string">"0"</span> + m;
}
<span class="hljs-keyword">if</span> (s.match(<span class="hljs-regexp">/^\d$/</span>)) { <span class="hljs-comment">// If the second is a single digit, add 0 in the front</span>
    s = <span class="hljs-string">"0"</span> + s;
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/pp.gif" class="center db" width="600" height="400" alt="pp" loading="lazy"></p>
<p>You can view the online <a target="_blank" href="https://codepen.io/miyaliu666-the-styleful/pen/VwEYwoJ">demo</a> on CodePen:</p>
<p></p><p>
  <span>See the Pen <a href="https://codepen.io/miyaliu666-the-styleful/pen/VwEYwoJ">
  pp</a> by miyaliu666 (<a href="https://codepen.io/miyaliu666-the-styleful">@miyaliu666-the-styleful</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p><p></p>


<p>Alright, we've built a timer!</p>
<p>You might be thinking: what if I want to add multiple timers to a project?</p>
<p>In this case, you'll need to set different <code>id</code>s for each timer's <code>input</code> field so that <code>document.getElementById().value</code> gets the corresponding value.</p>
<p>For example, for timer No.1 with <code>id</code> <code>inputh1</code>, we assign <code>h1 = +document.getElementById("inputh1").value</code> to <code>start_counting()</code>. For timer No.2 with <code>id</code> <code>inputh2</code>, we assign <code>h2 = +document.getElementById("inputh1").value</code>, and so on.</p>
<p>The actual project business is usually not as simple as just creating a bunch of timers. As you can imagine, the code can easily become lengthy and messy.</p>
<p>So now it's time to introduce object-oriented programming.</p>
<h2 id="timer-oop">How to Build a Timer using Object-Oriented Programming</h2>

<p>You may have heard developers say they need to "new an object" on some occasions - as if you can get what you want by just using the <code>new</code> keyword. Behind this is the concept of object-oriented programming.</p>
<p>In this section, we'll refactor the timer in the previous section with object-oriented programming, separating the "timer function" from the "user interface interaction".</p>
<p>The HTML and CSS are similar to the previous section, so we won't go over them here. You can see the entire code in <a target="_blank" href="https://codepen.io/miyaliu666-the-styleful/pen/oNaggXR">this CodePen demo</a>.</p>
<p></p><p>
  <span>See the Pen <a href="https://codepen.io/miyaliu666-the-styleful/pen/oNaggXR">
  oop</a> by miyaliu666 (<a href="https://codepen.io/miyaliu666-the-styleful">@miyaliu666-the-styleful</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p><p></p>


<p>If you have gone through freeCodeCamp's <a target="_blank" href="https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/object-oriented-programming/">Object-Oriented Programming course</a>, you'll likely remember that "objects in JavaScript are used to model real-world objects, giving them properties and behavior just like their real-world counterparts", such as cars, shops, and birds.</p>
<p>So let's start by defining the properties and methods (behavior) of objects :)</p>
<h3 id="new-class-1">New Timer Class</h3>

<p>The <code>class</code> keyword creates a class named <code>Timer</code> that has a <code>constructor()</code> with <code>_on_update()</code>, <code>start()</code>, <code>stop()</code>, <code>pause()</code>, and <code>show()</code> methods.</p>
<pre><code class="lang-javascript">&lt;script&gt;
    <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Timmer</span> </span>{
        <span class="hljs-keyword">constructor</span>() {
            <span class="hljs-built_in">this</span>.name = <span class="hljs-string">'undefined'</span>;
            <span class="hljs-built_in">this</span>.timmer = <span class="hljs-literal">undefined</span>;
            <span class="hljs-built_in">this</span>.h = <span class="hljs-number">0</span>;
            <span class="hljs-built_in">this</span>.m = <span class="hljs-number">0</span>;
            <span class="hljs-built_in">this</span>.s = <span class="hljs-number">10</span>;

            <span class="hljs-built_in">this</span>._on_update_callback = <span class="hljs-literal">undefined</span>;
            <span class="hljs-built_in">this</span>._on_stop_callback = <span class="hljs-literal">undefined</span>;
        }

        _on_update() {

        }

        start() {

        }

        stop() {

        }

        pause() {

        }

        show() {

        }
    }

&lt;/script&gt;
</code></pre>
<p>According to the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor">MDN</a>,</p>
<blockquote>
<p>The <strong><code>constructor</code></strong> method is a special method of a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes">class</a> for creating and initializing an object instance of that class.</p>
</blockquote>
<p>In it, we initialize several variables – that is, properties of the object –  with the <code>this</code> keyword. </p>
<p>In JavaScript, the value of <code>this</code> depends on context. In this case, it refers to the object that calls the function, that is an instance of <code>Timer</code>. </p>
<p>We also use <code>this</code> to initialize the callback function <code>_on_update_callback</code> when the timer is updated and the callback function <code>_on_stop_callback</code> when the timer is stopped.</p>
<p>The <code>_on_update()</code>, <code>start()</code>, <code>stop()</code>, <code>pause()</code>, and <code>show()</code> methods are used to update, start, stop and pause the timer, and display the current time, respectively. We will add code for them step by step.</p>
<h3 id="timer-update">Timer Update</h3>

<p>We'll handle the timer update using the <code>_on_update()</code> method. As above, we'll still use the <code>if</code> statement to execute code when the hours, minutes, and seconds are 0.</p>
<p>Call the external callback function <code>_on_update_callback</code> if it exists.</p>
<pre><code class="lang-javascript">_on_update() { 
    <span class="hljs-keyword">if</span> (<span class="hljs-number">0</span> === <span class="hljs-built_in">this</span>.h &amp;&amp; <span class="hljs-number">0</span> === <span class="hljs-built_in">this</span>.m &amp;&amp; <span class="hljs-number">0</span> === <span class="hljs-built_in">this</span>.s) {
        <span class="hljs-built_in">this</span>.stop();
        <span class="hljs-keyword">return</span>;
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-number">0</span> === <span class="hljs-built_in">this</span>.s) {
        <span class="hljs-built_in">this</span>.s = <span class="hljs-number">59</span>;
        <span class="hljs-keyword">if</span> (<span class="hljs-number">0</span> === <span class="hljs-built_in">this</span>.m) {
            <span class="hljs-built_in">this</span>.m = <span class="hljs-number">59</span>;
            <span class="hljs-built_in">this</span>.h = <span class="hljs-built_in">this</span>.h - <span class="hljs-number">1</span>;
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">this</span>.m = <span class="hljs-built_in">this</span>.m - <span class="hljs-number">1</span>;
        }
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-built_in">this</span>.s = <span class="hljs-built_in">this</span>.s - <span class="hljs-number">1</span>;
    }

    <span class="hljs-built_in">this</span>.show();
    <span class="hljs-keyword">if</span> (<span class="hljs-number">0</span> === <span class="hljs-built_in">this</span>.h &amp;&amp; <span class="hljs-number">0</span> === <span class="hljs-built_in">this</span>.m &amp;&amp; <span class="hljs-number">0</span> === <span class="hljs-built_in">this</span>.s) {
        <span class="hljs-built_in">this</span>.stop();
    }

    <span class="hljs-comment">// call the external callback function if it exists</span>
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>._on_update_callback &amp;&amp; <span class="hljs-keyword">typeof</span> <span class="hljs-built_in">this</span>._on_update_callback === <span class="hljs-string">'function'</span>) {
        <span class="hljs-built_in">this</span>._on_update_callback();
    }
}
</code></pre>
<h3 id="timer-start">Start the Timer</h3>

<p>We're using the <code>start()</code> method to start the countdown – that is, it is executed after the user clicks the <code>Start</code> button. With the <code>setInterval()</code> method, <code>_on_update()</code> is executed once every second.</p>
<pre><code class="lang-javascript">start() {
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.timmer) {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>] started`</span>);
        <span class="hljs-keyword">return</span>;
    }
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>] starts`</span>);
    <span class="hljs-built_in">this</span>.timmer = <span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-built_in">this</span>._on_update();
    }, <span class="hljs-number">1000</span>);
    <span class="hljs-built_in">this</span>.show();
}
</code></pre>
<h3 id="timer-stop">Stop the Timer</h3>

<p>The <code>stop()</code> method is used to stop the timer. Use <code>clearInterval()</code> to stop the countdown. Call the external callback function <code>_on_stop_callback()</code> if it exists.</p>
<pre><code class="lang-javascript">stop() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>] stopped`</span>);
    <span class="hljs-built_in">clearInterval</span>(<span class="hljs-built_in">this</span>.timmer);
    <span class="hljs-built_in">this</span>.timmer = <span class="hljs-literal">undefined</span>;

    <span class="hljs-comment">// smiliar to update, check for the stop callback function</span>
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>._on_stop_callback &amp;&amp; <span class="hljs-keyword">typeof</span> <span class="hljs-built_in">this</span>._on_stop_callback === <span class="hljs-string">'function'</span>) {
        <span class="hljs-built_in">this</span>._on_stop_callback();
    }
}
</code></pre>
<h3 id="timer-pause">Pause the Timer</h3>

<p>Use the <code>pause()</code> method to pause the timer and use <code>clearInterval()</code> to stop the countdown.</p>
<pre><code class="lang-javascript">pause() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>] paused`</span>);
    <span class="hljs-built_in">clearInterval</span>(<span class="hljs-built_in">this</span>.timmer);
    <span class="hljs-built_in">this</span>.timmer = <span class="hljs-literal">undefined</span>;
}
</code></pre>
<h3 id="show-current-time">Display Current Time</h3>

<p>Use the <code>show()</code> method to print the current time on the console.</p>
<pre><code class="lang-javascript">show() { <span class="hljs-comment">// display the current time</span>
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>] current time: <span class="hljs-subst">${<span class="hljs-built_in">this</span>.h}</span>:<span class="hljs-subst">${<span class="hljs-built_in">this</span>.m}</span>:<span class="hljs-subst">${<span class="hljs-built_in">this</span>.s}</span>`</span>);
}
</code></pre>
<h3 id="create-objects-1">Create Object Instances</h3>

<p>Next, use the <code>new</code> keyword to create two object instances, that is two timers, which have the properties and methods of the <code>Timer</code> object.</p>
<p>According to <a target="_blank" href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/new">MDN</a>,</p>
<blockquote>
<p>The <strong><code>new</code></strong> operator lets developers create an instance of a user-defined object type or of one of the built-in object types that has a constructor function.</p>
</blockquote>
<p>Assign two objects to <code>t1</code> and <code>t2</code> and put them into the array <code>list_timmer</code>. Also, create an array of sounds <code>list_sound</code>, which we will use later.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> t1 = <span class="hljs-keyword">new</span> Timmer();
t1.name = <span class="hljs-string">'Timer 1'</span>;
<span class="hljs-keyword">const</span> t2 = <span class="hljs-keyword">new</span> Timmer();
t2.name = <span class="hljs-string">'Timer 2'</span>;
<span class="hljs-keyword">const</span> list_timmer = [t1, t2];
<span class="hljs-keyword">const</span> list_sound = [<span class="hljs-string">'meow'</span>, <span class="hljs-string">'woof'</span>];
</code></pre>
<h3 id="UI-with-functions-1">User Interface Interaction with Functions</h3>

<p>Next, we'll create 6 functions.</p>
<p>The first function, <code>play_audio()</code>, has one argument. The function creates an <code>audio</code> element in the DOM and assigns it to <code>audio</code>. Then it sets the value of the <code>src</code> property to a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals">template literal</a> and calls its <code>play()</code> method to play the sound.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">play_audio</span>(<span class="hljs-params">sound</span>) </span>{
    <span class="hljs-comment">// meow.mp3 and woof.mp3 are local files and should be in the same directory with HTML file</span>
    <span class="hljs-keyword">const</span> audio = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'audio'</span>);
    audio.src = <span class="hljs-string">`<span class="hljs-subst">${sound}</span>.mp3`</span>;
    audio.play();
}
</code></pre>
<p>The second function, <code>btn_start_onclick()</code>, has one argument, <code>i</code>. This function is called when the "start" buttons of the two timers are clicked, passing either 1 or 2 as an argument:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"tmr-1-btn-start"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">" btn"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"start"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"btn_start_onclick(1)"</span> /&gt;</span>
</code></pre>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"tmr-2-btn-start"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"start"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"btn_start_onclick(2)"</span> /&gt;</span>
</code></pre>
<p>The function first gets the value of the input field and assigns it to the timer. Then it sets the state of the input field and the button with the <code>dom_update_inputs()</code> function. We will set <code>dom_update_inputs()</code> later.</p>
<p><strong>Remember that we initialized two callback functions at the beginning? Here we will assign an arrow function to them.</strong></p>
<p><code>_on_stop_callback</code> executes the callback function <code>dom_update_inputs</code>, which we'll discuss below.</p>
<p>The callback function <code>play_audio()</code> is also executed here with the argument <code>list_sound[i - 1]</code>, that is it takes the element <code>meow</code> or <code>woof</code> from the array <code>list_sound</code> defined earlier and passes it to the <code>src</code> property of <code>audio</code> to play the corresponding sound when the timer is stopped. For example, when <code>i</code> is 1, <code>audio.src = meow.mp3;</code>.</p>
<p><code>_on_update_callback</code> executes the callback function <code>dom_update_timmer()</code>, which we will talk about shortly.</p>
<p>Take the corresponding timer from the timer array through <code>const tmr = list_timmer[i - 1];</code> and execute the <code>start()</code> method to start the timer.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">btn_start_onclick</span>(<span class="hljs-params">i</span>) </span>{
    <span class="hljs-comment">// get the input value</span>
    <span class="hljs-keyword">const</span> ipt_h = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`ipt-<span class="hljs-subst">${i}</span>-h`</span>);
    <span class="hljs-keyword">const</span> ipt_m = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`ipt-<span class="hljs-subst">${i}</span>-m`</span>);
    <span class="hljs-keyword">const</span> ipt_s = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`ipt-<span class="hljs-subst">${i}</span>-s`</span>);

    <span class="hljs-comment">// set the state of input fields and buttons</span>
    dom_update_inputs(i, <span class="hljs-string">"COUNTING"</span>);
    <span class="hljs-comment">// take the corresponding timer from the timer array</span>
    <span class="hljs-keyword">const</span> tmr = list_timmer[i - <span class="hljs-number">1</span>];
    <span class="hljs-comment">// assign the input value to timer</span>
    tmr.h = <span class="hljs-built_in">Number</span>(ipt_h.value);
    tmr.m = <span class="hljs-built_in">Number</span>(ipt_m.value);
    tmr.s = <span class="hljs-built_in">Number</span>(ipt_s.value);

    <span class="hljs-comment">// set the callback function</span>
    tmr._on_stop_callback = <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-comment">// play the sound</span>
        play_audio(list_sound[i - <span class="hljs-number">1</span>]);
        <span class="hljs-comment">// set the state of input fields and buttons</span>
        dom_update_inputs(i, <span class="hljs-string">"STOPPED"</span>);
    }
    tmr._on_update_callback = <span class="hljs-function">() =&gt;</span> {
        dom_update_timmer(i);
    }
    <span class="hljs-comment">// start the timer</span>
    tmr.start();
}
</code></pre>
<p>The third function, <code>btn_pause_onclick()</code>, has one argument and is called when the <code>pause</code> buttons for both timers are clicked, passing in either 1 or 2. The callback function, <code>dom_update_inputs</code>, is executed to set the state of the input fields and buttons, and the <code>pause()</code> method is executed to pause the timer.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">btn_pause_onclick</span>(<span class="hljs-params">i</span>) </span>{
    dom_update_inputs(i, <span class="hljs-string">"PAUSED"</span>);

    <span class="hljs-comment">// take the corresponding timer from the timer array</span>
    <span class="hljs-keyword">const</span> tmr = list_timmer[i - <span class="hljs-number">1</span>];

    <span class="hljs-comment">// pause the timer</span>
    tmr.pause();
}
</code></pre>
<p>The fourth function, <code>btn_stop_onclick()</code>, is similar to the third function. It's called when the "stop" buttons of both timers are clicked, and sets the state of the input fields and buttons when the timer is stopped. Then the <code>stop()</code> method is executed to stop the timer.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">btn_stop_onclick</span>(<span class="hljs-params">i</span>) </span>{
    dom_update_inputs(i, <span class="hljs-string">"STOPED"</span>);

    <span class="hljs-comment">// take the corresponding timer from the timer array</span>
    <span class="hljs-keyword">const</span> tmr = list_timmer[i - <span class="hljs-number">1</span>];


    <span class="hljs-comment">// stop the timer</span>
    tmr.stop();
}
</code></pre>
<p>The fifth function <code>dom_update_inputs()</code> has two arguments, <code>i</code> and <code>status</code>. It sets the state of the input fields and buttons through <code>if.... .else if...</code> statements when <code>status</code> is met. </p>
<p>When this function is called in the second, third, and fourth functions above, it defines the state of the input fields and buttons when the timer is started, paused, and stopped.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">dom_update_inputs</span>(<span class="hljs-params">i, status</span>) </span>{
    <span class="hljs-keyword">if</span> (<span class="hljs-string">'COUNTING'</span> === status) {
        <span class="hljs-comment">// set the state of input fields</span>
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`ipt-<span class="hljs-subst">${i}</span>-h`</span>).disabled = <span class="hljs-literal">true</span>;
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`ipt-<span class="hljs-subst">${i}</span>-m`</span>).disabled = <span class="hljs-literal">true</span>;
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`ipt-<span class="hljs-subst">${i}</span>-s`</span>).disabled = <span class="hljs-literal">true</span>;

        <span class="hljs-comment">// set the state of buttons</span>
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`tmr-<span class="hljs-subst">${i}</span>-btn-start`</span>).disabled = <span class="hljs-literal">true</span>;
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`tmr-<span class="hljs-subst">${i}</span>-btn-pause`</span>).disabled = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`tmr-<span class="hljs-subst">${i}</span>-btn-stop`</span>).disabled = <span class="hljs-literal">false</span>;
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-string">'PAUSED'</span> === status) {
        <span class="hljs-comment">// set the state of input fields</span>
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`ipt-<span class="hljs-subst">${i}</span>-h`</span>).disabled = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`ipt-<span class="hljs-subst">${i}</span>-m`</span>).disabled = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`ipt-<span class="hljs-subst">${i}</span>-s`</span>).disabled = <span class="hljs-literal">false</span>;

        <span class="hljs-comment">// set the state of buttons</span>
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`tmr-<span class="hljs-subst">${i}</span>-btn-start`</span>).disabled = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`tmr-<span class="hljs-subst">${i}</span>-btn-pause`</span>).disabled = <span class="hljs-literal">true</span>;
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`tmr-<span class="hljs-subst">${i}</span>-btn-stop`</span>).disabled = <span class="hljs-literal">false</span>;
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-string">'STOPPED'</span> === status) {
        <span class="hljs-comment">// set the state of input fields</span>
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`ipt-<span class="hljs-subst">${i}</span>-h`</span>).disabled = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`ipt-<span class="hljs-subst">${i}</span>-m`</span>).disabled = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`ipt-<span class="hljs-subst">${i}</span>-s`</span>).disabled = <span class="hljs-literal">false</span>;

        <span class="hljs-comment">// set the state of buttons</span>
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`tmr-<span class="hljs-subst">${i}</span>-btn-start`</span>).disabled = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`tmr-<span class="hljs-subst">${i}</span>-btn-pause`</span>).disabled = <span class="hljs-literal">true</span>;
        <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`tmr-<span class="hljs-subst">${i}</span>-btn-stop`</span>).disabled = <span class="hljs-literal">true</span>;
    }
}
</code></pre>
<p>The sixth function <code>dom_update_timmer()</code> is used to synchronize the time to the page.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">dom_update_timmer</span>(<span class="hljs-params">i</span>) </span>{
    <span class="hljs-comment">// take the corresponding timer from the timer array</span>
    <span class="hljs-keyword">const</span> tmr = list_timmer[i - <span class="hljs-number">1</span>];

    <span class="hljs-comment">// synchronize the time to the page</span>
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`ipt-<span class="hljs-subst">${i}</span>-h`</span>).value = tmr.h;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`ipt-<span class="hljs-subst">${i}</span>-m`</span>).value = tmr.m;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`ipt-<span class="hljs-subst">${i}</span>-s`</span>).value = tmr.s;
}
</code></pre>
<p>Above, we have encapsulated the "timer function" in the Timmer class and kept the "user interface interaction" in the global scope, so that multiple timers as the Timmer class instances can run simultaneously.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/04/oop.gif" class="center db" width="600" height="400" alt="oop" loading="lazy"></p>
<p>In this section, I didn't set a limit on the range of hour, minute and second inputs or optimize their format. If you are interested, you can refer to the code in the previous section and do it yourself in the CodePen demo :)</p>
<p>Thinking further, what if our project has other functional modules besides this set of two timers - for example, two sets of timers, which are object instances of the same type <code>Timer</code>? When assigning values to the callback function <code>_on_stop_callback</code>, one set of instances needs to play a beep through the <code>play_audio()</code> function, while the other set needs to set the color of the timer by another function. Then the second assignment will overwrite the first one.</p>
<p>Here we'll introduce the event mechanism to solve this problem.</p>
<h2 id="timer-oop-with-events">How to Add the Event Mechanism to Object-Oriented Programming</h2>

<p>This section is similar to the previous section, except we'll add an event mechanism to replace the original callback function. </p>
<p>The benefit of the event mechanism is that multiple objects can be notified when the state of the timer changes. In our case, when the timer's state changes, it notifies the buttons on the page so that the buttons' states change in sync.</p>
<p>Again, the HTML and CSS are similar to the first section so I won't repeat them here.</p>
<p>You can see the full code in this <a target="_blank" href="https://codepen.io/miyaliu666-the-styleful/pen/JjmooXz">CodePen demo</a>.</p>
<p></p><p>
  <span>See the Pen <a href="https://codepen.io/miyaliu666-the-styleful/pen/JjmooXz">
  oop_with_events</a> by miyaliu666 (<a href="https://codepen.io/miyaliu666-the-styleful">@miyaliu666-the-styleful</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p><p></p>


<h3 id="eventemitter">Create the Event Generator</h3>

<p>First, we create a new class <code>EventEmitter</code>, which is an event emitter used to implement the event mechanism – in this case, to implement the timer state change notification.</p>
<p><code>on</code> is used to listen (subscribe) to events. When an event occurs, a callback function is executed, and the parameters of the callback function are the parameters of the event. <code>this</code> in the callback function refers to the trigger of the event.</p>
<p><code>emit</code> is used to emit (throw) the event.</p>
<p><code>removeListener</code> is used to remove a listener from an event.</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">EventEmitter</span> </span>{
    <span class="hljs-keyword">constructor</span>() {
        <span class="hljs-built_in">this</span>._events = {};
    }

    on(type, listener) {
        <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>._events[type]) {
            <span class="hljs-built_in">this</span>._events[type].push(listener);
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">this</span>._events[type] = [listener];
        }
    }

    emit(type, ...args) {
        <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>._events[type]) {
            <span class="hljs-built_in">this</span>._events[type].forEach(<span class="hljs-function"><span class="hljs-params">listener</span> =&gt;</span> {
                listener(...args);
            });
        }
    }

    removeListener(type, listener) {
        <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>._events[type] &amp;&amp; listener) {
            <span class="hljs-built_in">this</span>._events[type] = <span class="hljs-built_in">this</span>._events[type].filter(<span class="hljs-function"><span class="hljs-params">l</span> =&gt;</span> l !== listener);
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>._events[type] &amp;&amp; !listener) {
            <span class="hljs-built_in">this</span>._events[type] = [];
        }
    }
}
</code></pre>
<h3 id="new-class-2">New Timer Class</h3>

<p>Here, we create a new class <code>Timmer</code>. The <code>extends</code> keyword means that <code>Timmer</code> is a child class of the <code>EventEmitter</code> class. The child class inherits all the properties and methods of the parent class.</p>
<p>Check this <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends">doc</a> for more information about the <code>extends</code> keyword.</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Timmer</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">EventEmitter</span> </span>{
    <span class="hljs-keyword">constructor</span>() {
        <span class="hljs-built_in">super</span>();
        <span class="hljs-built_in">this</span>.name = <span class="hljs-string">'undefined'</span>;
        <span class="hljs-built_in">this</span>.timmer = <span class="hljs-literal">undefined</span>;
        <span class="hljs-built_in">this</span>.h = <span class="hljs-number">0</span>;
        <span class="hljs-built_in">this</span>.m = <span class="hljs-number">0</span>;
        <span class="hljs-built_in">this</span>.s = <span class="hljs-number">10</span>;
    }

    _on_update() {
        <span class="hljs-keyword">if</span> (<span class="hljs-number">0</span> === <span class="hljs-built_in">this</span>.h &amp;&amp; <span class="hljs-number">0</span> === <span class="hljs-built_in">this</span>.m &amp;&amp; <span class="hljs-number">0</span> === <span class="hljs-built_in">this</span>.s) {
            <span class="hljs-built_in">this</span>.stop();
            <span class="hljs-keyword">return</span>;
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-number">0</span> === <span class="hljs-built_in">this</span>.s) {
            <span class="hljs-built_in">this</span>.s = <span class="hljs-number">59</span>;
            <span class="hljs-keyword">if</span> (<span class="hljs-number">0</span> === <span class="hljs-built_in">this</span>.m) {
                <span class="hljs-built_in">this</span>.m = <span class="hljs-number">59</span>;
                <span class="hljs-built_in">this</span>.h = <span class="hljs-built_in">this</span>.h - <span class="hljs-number">1</span>;
            } <span class="hljs-keyword">else</span> {
                <span class="hljs-built_in">this</span>.m = <span class="hljs-built_in">this</span>.m - <span class="hljs-number">1</span>;
            }
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">this</span>.s = <span class="hljs-built_in">this</span>.s - <span class="hljs-number">1</span>;
        }

        <span class="hljs-built_in">this</span>.show()
        <span class="hljs-comment">// emit an event</span>
        <span class="hljs-built_in">this</span>.emit(<span class="hljs-string">'update'</span>, {
            <span class="hljs-attr">h</span>: <span class="hljs-built_in">this</span>.h,
            <span class="hljs-attr">m</span>: <span class="hljs-built_in">this</span>.m,
            <span class="hljs-attr">s</span>: <span class="hljs-built_in">this</span>.s
        });
        <span class="hljs-keyword">if</span> (<span class="hljs-number">0</span> === <span class="hljs-built_in">this</span>.h &amp;&amp; <span class="hljs-number">0</span> === <span class="hljs-built_in">this</span>.m &amp;&amp; <span class="hljs-number">0</span> === <span class="hljs-built_in">this</span>.s) {
            <span class="hljs-built_in">this</span>.stop();
        }
    }

    start() {
        <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.timmer) {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>] started`</span>);
            <span class="hljs-keyword">return</span>;
        }
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>] starts`</span>);
        <span class="hljs-built_in">this</span>.timmer = <span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =&gt;</span> {
            <span class="hljs-built_in">this</span>._on_update();
        }, <span class="hljs-number">1000</span>);
        <span class="hljs-built_in">this</span>.show();

        <span class="hljs-comment">// emit an event</span>
        <span class="hljs-built_in">this</span>.emit(<span class="hljs-string">'start'</span>, {
            <span class="hljs-attr">h</span>: <span class="hljs-built_in">this</span>.h,
            <span class="hljs-attr">m</span>: <span class="hljs-built_in">this</span>.m,
            <span class="hljs-attr">s</span>: <span class="hljs-built_in">this</span>.s
        });
    }

    stop() {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>] stoped`</span>);
        <span class="hljs-built_in">clearInterval</span>(<span class="hljs-built_in">this</span>.timmer);
        <span class="hljs-built_in">this</span>.timmer = <span class="hljs-literal">undefined</span>;

        <span class="hljs-comment">// emit an event</span>
        <span class="hljs-built_in">this</span>.emit(<span class="hljs-string">'stop'</span>, {
            <span class="hljs-attr">h</span>: <span class="hljs-built_in">this</span>.h,
            <span class="hljs-attr">m</span>: <span class="hljs-built_in">this</span>.m,
            <span class="hljs-attr">s</span>: <span class="hljs-built_in">this</span>.s
        });
    }

    pause() {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>] paused`</span>);
        <span class="hljs-built_in">clearInterval</span>(<span class="hljs-built_in">this</span>.timmer);
        <span class="hljs-built_in">this</span>.timmer = <span class="hljs-literal">undefined</span>;

        <span class="hljs-comment">// emit an event</span>
        <span class="hljs-built_in">this</span>.emit(<span class="hljs-string">'pause'</span>, {
            <span class="hljs-attr">h</span>: <span class="hljs-built_in">this</span>.h,
            <span class="hljs-attr">m</span>: <span class="hljs-built_in">this</span>.m,
            <span class="hljs-attr">s</span>: <span class="hljs-built_in">this</span>.s
        });
    }

    show() {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>]current time: <span class="hljs-subst">${<span class="hljs-built_in">this</span>.h}</span>:<span class="hljs-subst">${<span class="hljs-built_in">this</span>.m}</span>:<span class="hljs-subst">${<span class="hljs-built_in">this</span>.s}</span>`</span>);
    }
}
</code></pre>
<p>In the above code, you can see in the comments that there are four "throw events". The <code>emit</code> method throws four events <code>update</code>, <code>start</code>, <code>stop</code>, and <code>pause</code>, which emit the changes inside the timer. All objects subscribed to these events will execute the corresponding callback functions.</p>
<h3 id="create-objects-2">Create Object Instances</h3>

<p>Similarly, we create two new timer object instances <code>t1</code> and <code>t2</code>, and arrays storing timers and sounds assigned to <code>list_timmer</code> and <code>list_sound</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> t1 = <span class="hljs-keyword">new</span> Timmer();
t1.name = <span class="hljs-string">'Timer 1'</span>;
<span class="hljs-keyword">const</span> t2 = <span class="hljs-keyword">new</span> Timmer();
t2.name = <span class="hljs-string">'Timer 2'</span>;
<span class="hljs-keyword">const</span> list_timmer = [t1, t2];
<span class="hljs-keyword">const</span> list_sound = [<span class="hljs-string">'meow'</span>, <span class="hljs-string">'woof'</span>];
<span class="hljs-keyword">const</span> list_sound_str = [<span class="hljs-string">'🐱meow~~~'</span>, <span class="hljs-string">'🐶woof~woof~woof~'</span>];
</code></pre>
<h3 id="UI-with-functions-2">User Interface Interaction with Functions</h3>

<p>In this case, we'll create 6 functions as well.</p>
<p>Among them, <code>play_audio()</code>, <code>btn_pause_onclick</code>, <code>btn_stop_onclick</code>, <code>dom_update_inputs()</code>, <code>dom_update_timmer()</code> are the same as the functions in the previous section.</p>
<p>Let's take the <code>btn_start_onclick()</code> function as an example to illustrate the mechanism of event subscription.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">btn_start_onclick</span>(<span class="hljs-params">i</span>) </span>{
    <span class="hljs-comment">// get the input value</span>
    <span class="hljs-keyword">const</span> ipt_h = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`ipt-<span class="hljs-subst">${i}</span>-h`</span>);
    <span class="hljs-keyword">const</span> ipt_m = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`ipt-<span class="hljs-subst">${i}</span>-m`</span>);
    <span class="hljs-keyword">const</span> ipt_s = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">`ipt-<span class="hljs-subst">${i}</span>-s`</span>);

    <span class="hljs-comment">// set the state of input fields and buttons</span>
    dom_update_inputs(i, <span class="hljs-string">"COUNTING"</span>);

    <span class="hljs-comment">// take the corresponding timer from the timer array</span>
    <span class="hljs-keyword">const</span> tmr = list_timmer[i - <span class="hljs-number">1</span>];
    <span class="hljs-comment">// assign the input value to the timer</span>
    tmr.h = <span class="hljs-built_in">Number</span>(ipt_h.value);
    tmr.m = <span class="hljs-built_in">Number</span>(ipt_m.value);
    tmr.s = <span class="hljs-built_in">Number</span>(ipt_s.value);

    <span class="hljs-comment">// listen to the timer's update event and synchronize the time to the page</span>
    tmr.removeListener(<span class="hljs-string">'update'</span>);
    tmr.removeListener(<span class="hljs-string">'stop'</span>);
    tmr.on(<span class="hljs-string">'update'</span>, <span class="hljs-function">() =&gt;</span> dom_update_timmer(i));
    tmr.on(<span class="hljs-string">'stop'</span>, <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-built_in">console</span>.log(list_sound_str[i - <span class="hljs-number">1</span>]);
    });
    tmr.on(<span class="hljs-string">'stop'</span>, <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-comment">// play the sound</span>
        play_audio(list_sound[i - <span class="hljs-number">1</span>]);
        <span class="hljs-comment">// set the state of input fields and buttons</span>
        dom_update_inputs(i, <span class="hljs-string">"STOPPED"</span>);
    });

    <span class="hljs-comment">// start the timer</span>
    tmr.start();
}
</code></pre>
<p>This function is called when the user clicks the "Start" button. It listens to the <code>update</code> event via the <code>on()</code> method, and executes the <code>dom_update_timmer()</code> callback function.</p>
<p>It subscribes to the <code>stop</code> event twice, executing different function modules - first to print the sound text in the console, and then to play a sound and set the state of input fields and buttons (without interfering with each other). </p>
<p><strong>This is the advantage of the event mechanism compared to the <code>_on_stop_callback</code> callback function in the previous section.</strong></p>
<p>Note the <code>tmr.removeListener('update');</code> and <code>tmr.removeListener('stop');</code> at the beginning - this is to remove the event listener (if any) each time <code>this.start()</code> is executed.</p>
<h2 id="conclusion">Conclusion</h2>

<p>In this article, we built timers based on both process-oriented and object-oriented programming. We also added an event mechanism to our app built with object-oriented programming and explored some best practices of the programming paradigm step by step. </p>
<p>If you want to discuss this article with me or give me suggestions, please send me a message on the <a target="_blank" href="https://forum.freecodecamp.org/">freeCodeCamp Forum</a>. My id is miyaliu.</p>
<p>Thank you for reading this article. Happy coding!</p>
<p>Cover image by <a href="https://unsplash.com/@yogendras31?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Yogendra Singh</a> on <a href="https://unsplash.com/s/photos/timer?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ My Six Years in the Open Source Community ]]>
                </title>
                <description>
                    <![CDATA[ Original article: 在开放社区中的六年，我做着喜欢且擅长的事情，利他而自利 by Miya Liu Translated by: Alan Luo Hello, I'm Yuyu Liu (Miya) from the freeCodeCamp community. freeCodeCamp.org is the world's largest open-source non-profit programming education community. It is also a... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/my-six-years-in-open-community/</link>
                <guid isPermaLink="false">66d85ab0c1231da2ef2b5b4e</guid>
                
                    <category>
                        <![CDATA[ community ]]>
                    </category>
                
                    <category>
                        <![CDATA[ freeCodeCamp.org ]]>
                    </category>
                
                    <category>
                        <![CDATA[ open source ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Fri, 04 Mar 2022 16:35:38 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/02/WechatIMG3506.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><strong>Original article:</strong> <a target="_blank" href="https://chinese.freecodecamp.org/news/my-six-years-in-open-community/">在开放社区中的六年，我做着喜欢且擅长的事情，利他而自利</a> by <a target="_blank" href="https://chinese.freecodecamp.org/news/author/miyaliu/">Miya Liu</a>
<strong>Translated by:</strong> <a target="_blank" href="https://twitter.com/iLtcDev">Alan Luo</a></p>
<p>Hello, I'm Yuyu Liu (Miya) from the <a target="_blank" href="http://freecodecamp.org/">freeCodeCamp</a> community.</p>
<p>freeCodeCamp.org is the world's largest open-source non-profit programming education community. It is also an open-source project that has more stars than any other repository on GitHub.</p>
<p>In this article, I'll share how I got invovled in the freeCodeCamp community way back in 2015. </p>
<p>I am an ordinary person who grew up in a rural area, who graduated from an ordinary second-tier university with an uncompetitive liberal arts major, and who switched from a traditional industry. And I've never worked at any of the famous Chinese companies (BAT as we call them in China: Baidu, Alibaba, Tencent).</p>
<p>If you are as ordinary as I am, and wondering if you can manage to do something, then I hope my story will give you some encouragement.</p>
<p>There are too many stories to write about from these past six years, but here are some that are the most meaningful to me:</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-who-should-read-this-article">Who Should Read This Article</a></li>
<li><a class="post-section-overview" href="#heading-a-bit-of-background">A Bit of Background</a><ul>
<li><a class="post-section-overview" href="#heading-about-the-topic-of-this-article">About the Topic of This Article</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-are-you-miya">"Are you Miya?"</a></li>
<li><a class="post-section-overview" href="#heading-the-awakening-of-self-awareness">The Awakening of Self-awareness</a></li>
<li><a class="post-section-overview" href="#heading-in-shenzhen-it-is-really-important-to-find-a-few-friends-and-spend-the-holidays-together">"In Shenzhen, it is really important to <strong>find a few friends and spend the holidays together</strong>."</a></li>
<li><a class="post-section-overview" href="#heading-bubble">Bubble</a></li>
<li><a class="post-section-overview" href="#heading-kedou-school-is-the-closest-open-source-community-to-us">"Kedou School is the closest open source community to us"</a></li>
<li><a class="post-section-overview" href="#heading-what-was-i-born-for">What Was I Born for?</a><ul>
<li><a class="post-section-overview" href="#heading-learning-by-doing">Learning by Doing</a></li>
<li><a class="post-section-overview" href="#heading-accept-yourself">Accept Yourself</a></li>
<li><a class="post-section-overview" href="#heading-this-world-is-pretty-good">This World Is Pretty Good</a></li>
</ul>
</li>
</ul>
<h2 id="heading-who-should-read-this-article">Who Should Read This Article</h2>
<p>If you:</p>
<ul>
<li>are thinking of exploring to be a better version of yourself and bring a beautiful change to the world at the same time, or</li>
<li>want to understand the impact of open communities and open collaboration on people, or</li>
<li>like people and stories with warmth</li>
</ul>
<p>I believe you'll find something useful.</p>
<h2 id="heading-a-bit-of-background">A Bit of Background</h2>
<p>After the successful conclusion of the <a target="_blank" href="https://www.bagevent.com/event/7685233">China Open Source Conference</a> (COSCon'21) a few days ago, my friends and I who organized the Chengdu event stayed up all night for an in-depth recap.</p>
<figure>
    <img src="https://www.freecodecamp.org/news/content/images/2022/03/2021-china-open-source-conference-chengdu-group-photo.png" alt="Group photo from the 2021 China Open Source Conference in Chengdu" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>2021 China Open Source Conference Chengdu Scene</figcaption>
</figure>

<p>The next day, I conducted a self-review and posted in the WeChat Moments:</p>
<blockquote>
<p>Nowadays, the things I think about the most, talk about the most, and that touch me the most are still the same as when I entered this field on the first day a few years ago. So I feel relieved and calm. The original intention is precious, and we encourage each other.</p>
</blockquote>
<p>In fact, my original intention was simple - I hope that I can have a good influence on others, and at the same time, that I can easily be moved by those who have pure, big or small dreams and are full of energy and sparkle.</p>
<p>I believe that all content that can convey goodwill is worthy of recommendation, so I have talked about many stories of friends or strangers on various occasions.</p>
<p>This time, with the opportunity to write for the "Open Source Story Collection" of the <a target="_blank" href="https://kaiyuanshe.cn/">kaiyuanshe</a>, I reviewed and recorded my own story for the first time and shared it publicly.</p>
<h3 id="heading-about-the-topic-of-this-article">About the Topic of This Article</h3>
<p>Community (社区) - Some people translate it as "community group (社群)." This word may remind people of "community economy (社群经济)" or something similar. I think it is a bit utilitarian, so I never liked it.</p>
<p>And recently, I have been reading the book "The Crowd: A Study of the Popular Mind Book" which talks about "group psychology." I just try not to be included in any group, hoping to live a little more freely and smartly within the scope of my ability, with fewer labels.</p>
<p>Some friends also translate it as "community (共同体)" and study it combined with anthropology, sociology, and economics. I find it very interesting, but I haven't done so much research yet, so I don't use this word.</p>
<p>In addition, although this article is submitted to the "Open Source Story Collection", I don't want to use the "Open Source Community (开源社区)". This is because, in fact, my feelings about the term "Open Source" are not as deep as those of friends who have been exposed to it from their school days and early days of work. </p>
<p>My "community" enlightenment does not come from "open source". Moreover, I believe that the "open source community" is included in the "open community," specifically referring to the "open community" built around software and hardware technologies.</p>
<p>Let's get started!</p>
<h2 id="heading-are-you-miya">"Are you Miya?"</h2>
<p>The first story is the prologue of all the stories, so I will look back quite far.</p>
<p>I come from a rural area of Sichuan.</p>
<p>Before high school, I was a top student in my hometown. Most of my self-confidence in life was cultivated at that time.</p>
<p>Later, I entered the best class in the best high school in the county. For various reasons, I got worse and worse in exams. Fortunately, I graduated before my confidence was completely worn away.</p>
<p>Due to age and geographical constraints, when filling out college applications, I, like many classmates, didn't know anything about what I would like to do in the future. So my university and major were not satisfying.</p>
<p>In the first semester, in a large literature class with one or two hundred people, I wanted to show off and asked the teacher a question about the book "The Ordinary World." </p>
<p>The teacher did not answer the question but changed the topic immediately and asked other students to read the articles in the book, just like we did in high school.</p>
<p>I sat down, feeling awkward. I thought this was very different from my imagined university atmosphere. I thought teachers and students would talk freely and explore the truth of the world. What could I gain from this university?</p>
<p>So, after the class, walking on the sunny wooded path, I decided that I would skip class and study independently.</p>
<p>From that point on, and even while working for a few years at an electronics company and a construction management company, I was thinking about and exploring what I should do, what I am suitable for, and what I will be really happy about in the future.</p>
<figure>
    <img src="https://www.freecodecamp.org/news/content/images/2022/03/6th-anniversary-suzhou-toastmasters-club-celebration.png" alt="Photo of the stage at the 6th anniversary Suzhou Toastmasters Club celebration" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>The 6th Anniversary Celebration of Suzhou Toastmasters Club</figcaption>
</figure>

<p>In May 2015, I accidentally participated in the Toastmasters International Speaking Association event. </p>
<p>It was the first time I came into the open community. When I first met some entrepreneurs in the Internet industry, I was infected by their vitality and thought that I would be thrilled if I could become one of them.</p>
<p>In July, I came across a special bus driver by chance.</p>
<figure>
    <img src="https://www.freecodecamp.org/news/content/images/2022/03/suzhou-bus-178-driver-wechat-moment.png" alt="A screenshot of a WeChat moment story about the Suzhou Bus 178 driver" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>I shared his story in WeChat Moment</figcaption>
</figure>

<p>Here's what this picture says: I met a young bus driver of Suzhou Bus 178, who was discharged from the army and had been driving the bus for a year. He had decorated the little area in front of him very interestingly. I asked him if I could take photos because good things should be shared. Everyone who can be positive with their current position deserves a better future. 🌞 He's the most handsome bus driver in Suzhou. Let's spread his story!</p>
<p>I think people like bus drivers, security guards, migrant workers, and so on may never get a chance to attend events like Toastmasters. Still, they also have touching stories to share, and they also desire better jobs and lives.</p>
<p>I suddenly realized that I wanted to spread the good stories of ordinary people or to create a stage for ordinary people to show themselves.</p>
<p>So I ran to the bus terminal and spent an afternoon waiting for Bus 178, found the driver, told him that I might organize some activities in the future, and invited him. We exchanged WeChat IDs.</p>
<figure>
    <img src="https://www.freecodecamp.org/news/content/images/2022/03/suzhou-bus-178-driver.png" alt="A closeup of the Suzhou Bus 178 driver" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>The bus driver, who is handsome and likes to laugh</figcaption>
</figure>

<p>Later, my friend and I tried to build a community around "reading, speaking, and making friends." We invited him to share his story. He also donated some books to the community.</p>
<p>Soon, he told me that he started to drive the "Suzhou Top Ten Model Bus."</p>
<p>I told this story on the stage of Suzhou's first New Year's Eve speech party at the end of 2015: <strong>Suzhou has more than 10,000 buses, but there are only 10 Model Bus.</strong> About two years after we met, he switched careers to Bosch Automotive for project management.</p>
<p>When writing this article, I contacted him again, and he said that he is doing well now. </p>
<p>I couldn't help crying. Haha, it has been six years, and I am still so emotional...</p>
<p>One night, it was pretty late, and I was sitting at the bus stop waiting for the bus. A car drove past the station and stopped. The driver leaned out from the passenger's door. It was the driver!</p>
<blockquote>
<p>- Are you Miya?</p>
<p>- Yeah, but you are not supposed to stop here, right?</p>
<p>- My shift has already ended. Do you need a ride?</p>
<p>- Sure!</p>
</blockquote>
<p>I rarely tell people about this scene. Later, whenever I think of him leaning out to greet me with the simple smiles and the dialogues between us, I feel warm and moved.</p>
<p>As bus drivers and passengers, we wouldn't have any communication except eye contact while swiping the cards or inserting the coins.</p>
<p>But in the community, when we remove our professional identity and just express and communicate as two people on an equal footing, we can become friends.</p>
<p>It's just like when I invited an old friend whom I had not seen for three years to dinner. He was Professor Sun, who was in his 80s. I was about to leave Suzhou, where I had stayed for ten years, and return to Chengdu. </p>
<p>He said:</p>
<blockquote>
<p>I like the light relationship between people, just like Miya suddenly invited me to dinner. I feel delighted. This is a heartfelt feeling, as precious as a pearl. It reminds us that there are good things in this world besides bad things. So I came to the dinner, let it be.</p>
</blockquote>
<p><strong>I really like this pure feeling not intentionally groomed. Therefore, I understand that my state in the community is the most satisfying and happiest.</strong></p>
<h2 id="heading-the-awakening-of-self-awareness">The Awakening of Self-awareness</h2>
<p>My first computer lesson came from my PE teacher. I know it sounds like a joke, but it is.</p>
<p>In the summer after graduating from junior high school, he taught me how to use Word, Excel, and Baidu in a small training room, facing a heavy and mysterious desktop computer. He might have also taught me something else, but I can't remember.</p>
<p>I couldn't wait to play Mario or mushroom picking or other small games during the break between classes. And he was playing "Red Alert."</p>
<p>I have almost no memory of the computer class in high school. Computer teachers often had unexpected errands at that time, so Science teachers often came and kept an eye on us.</p>
<p>But I remember that I had my first QQ account (a chat app) in my freshman year and gradually stopped taking care of UC (another older chat app).</p>
<p>At university, they "kindly" did not assign Advanced Mathematics for liberal arts students like me. Even in computer class, we just learned the simplest Visual FoxPro. After graduation, I never heard these two words again.</p>
<p>VFP was straightforward for me, and my first experience of writing programs was fun for me.</p>
<p>I often heard science and engineering students discussing challenging Advanced Mathematics and C Programming Language exams. I envied them for having the opportunity to study such exciting things.</p>
<p>In my sophomore year, I decided to sign up for the National Computer Rank Examination: Level 2 C Language Programming.</p>
<p>I borrowed a textbook from the library for self-learning, and found that C was very abstract for me. I then searched online for the previous year's test questions and the predictions of the current year's questions. </p>
<p>I worked on the questions, compared the answers, and felt that I could pass the exam. Yes, I learned the C language like I was learning other literature subjects.</p>
<p>At that time, the school put on training sessions on the computer before the exam. I only went to the training once to understand the basic procedures of the exam since I often skipped classes.</p>
<p>Finally, on exam day, I finished the questions very fast, ran the code and passed the test, and then submitted the code with confidence.</p>
<p>However, because of my absence from the pre-exam training, the way I submitted the code was wrong, and I did not get the certificate. I never took the exam again.</p>
<p>In 2012, I started to use WeChat, but I was still far from the Internet.
I followed my predecessors to learn to do jobs that I thought had little value and adapted to different stuff in the workplace. </p>
<p>At the same time, I was thinking about the meaning of life. I was unwilling to kill my passion in a closed circle, yet I didn't know where I should go.
I didn't even know that the Internet, entrepreneurship, technology, and so many dynamic things were happening on the other side of the city.</p>
<p>They were only a half-hour drive away from me at that time, but it was a completely different world.</p>
<p>However, I always longed for the future. Even my WeChat ID is Hello MrT. T stands for tomorrow. And I am still using it today.</p>
<p>It referred to a song called "Hello Tomorrow" by Milk Coffee (a pop group in China).</p>
<p>This song is a good representation of my state of mind in most of my youth, and now when I hear it, I can still feel it:</p>
<blockquote>
<p>When I walk in the opposite direction / Huddled in the corner of the stairway, I seek courage / Shoulders visibly shaking as I weep / I ask myself, where am I?</p>
<p>After every cry, I will smile running forward / Losing and finding something as I go along / To tomorrow, hello. Even in a small voice / But it jolts me awake to the meaning of courage.</p>
</blockquote>
<p>In 2016, my startup partner at the time introduced freeCodeCamp to me. </p>
<p>I was surprised that the community could have such energy. Thanks to my former partner.</p>
<figure>
    <img src="https://www.freecodecamp.org/news/content/images/2022/03/fcc-group-photos.png" alt="Photos of tech events from freeCodeCamp groups in China, the Philippines, Canada, Nigeria, and other countries." class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>freeCodeCamp students from all over the world organize local tech events</figcaption>
</figure>

<p>As a result, I spent two consecutive nights working on the curriculum challenges and achieved more than 160 points. That was the first time I felt that my code might become a product.</p>
<p>In a phrase that we are familiar with - this opened the door to a new world for me: </p>
<p>I started to understand what kind of product WeChat is, and I also started to understand other products, instead of just being a regular user.</p>
<p>I connected with a larger world through the Internet, and gradually got in touch with open source, education, and public welfare, social innovation, and social enterprise. And I also started to get in touch with the people in various countries who were intensely involved in these fields.</p>
<p>I gradually understood the world's rules, learned to accept others and myself, and saw many possibilities in my future.</p>
<figure>
    <img src="https://www.freecodecamp.org/news/content/images/2022/03/chinese-freecodecamp-learn.png" alt="The Chinese freeCodeCamp Learn curriculum map" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>freeCodeCamp Chinese Site: https://chinese.freecodecamp.org/</figcaption>
</figure>

<p>I remember that when I walked with Luoyang Hu, who's an early contributor to the Chinese freeCodeCamp site, in early 2019, I talked about a point: <strong>In this complex and changeable world, the rarest thing for people is the awakening of self-awareness.</strong></p>
<p>At that time, I looked back and was surprised that I started to embrace the Internet gradually in 2015. Without this change, how long would I remain in the closed circle?</p>
<p>My awakening in the past few years has been more profound than in the past two decades!</p>
<p>But...</p>
<ul>
<li><p>when I graduated from junior high school and had just started to use the computer, if someone had told me that the machine in front of me could not only type, click the mouse, and pick mushrooms, but also do many more things – and that Baidu is not the entire Internet –</p>
</li>
<li><p>and when I first became interested in programming in college, if there were learning resources and open source communities like freeCodeCamp –</p>
</li>
<li><p>and in the first few years of my work, when I was trying to find the meaning of life, if I could've understood that there were many ordinary, passionate young people in this age who were making contributions to areas that are ignored by the public - it has nothing to do with fame and wealth, and they just hope to make this world a little better, and get some peace of mind –</p>
</li>
</ul>
<p>...would these awakenings have come earlier?</p>
<p>Or, how many children and young people are like me who are eager to change but unable to start because of various constraints? What can I do for them?</p>
<blockquote>
<p>Education is a tree shaking a tree, a cloud to promote a cloud, a soul to awaken another soul. - Unknown Source</p>
</blockquote>
<p>I once read the sentence, "<strong>We go to college for those who didn't go to college</strong>." I think it's true.</p>
<p>Therefore, <strong>I decided that this was the field I wanted to do well in: education for the public</strong>. I wanted to transform the knowledge and insights I had acquired over the years into educational resources, and pass them on to those in need in the community so they could bring good changes to their lives. In persevering and clarifying the "initial intention," my life became calmer and clearer.</p>
<figure>
    <img src="https://www.freecodecamp.org/news/content/images/2022/03/fcc-team-in-hong-kong.png" alt="Some of the fCC team members having dinner in Hong Kong" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>Some members of the freeCodeCamp team worked together in Hong Kong for a week in 2019, from left to right: Miya, Mrugesh, Quincy, Kris, Ahmad</figcaption>
</figure>

<p>Also, in 2019, I officially joined the freeCodeCamp team to collaborate with contributors.</p>
<p>I like to introduce myself as a freeCodeCamp contributor or freeCodeCamp Chinese community ambassador on formal occasions.</p>
<p>In fact, the freeCodeCamp team is a flat organization. There is no concept of subordinates, and no one has a title.</p>
<p>Quincy usually introduces himself as a teacher of freeCodeCamp, and when necessary, he will say that he is the founder.</p>
<p>Regarding my title, I told Quincy that I need a title to cooperate with others in China.</p>
<p>We don't like the term "person in charge (负责人)," which is a bit old-fashioned. So then he suggested the term "ambassador (大使)" instead. I know there are also names like "ambassador" in communities such as TEDx, so I accepted it.</p>
<h2 id="heading-in-shenzhen-it-is-really-important-to-find-a-few-friends-and-spend-the-holidays-together">"In Shenzhen, it is really important to <strong>find a few friends and spend the holidays together</strong>."</h2>
<p>In September 2021, I recorded a <a target="_blank" href="https://www.bilibili.com/video/BV1WR4y1H7tj?spm_id_from=333.999.0.0">video</a> to promote the China Open Source Conference, and I mentioned this story again.</p>
<p>Since 2016, I have often called and chatted with friends from various cities, including Chengdu, Guangzhou, Xi'an, Shenzhen, Tianjin, Zhengzhou, and others.</p>
<p>Most of them are programmers who want to organize freeCodeCamp offline technical events in their cities to help everyone learn to program and meet like-minded friends. Many times we've talked for one or two hours.</p>
<p>I also introduced them to help them get to know each other. I wrote in the 2016 community annual summary:</p>
<blockquote>
<p>In my view, these people are like pearls scattered in every corner of the world. I can feel their unique beauty.</p>
<p>However, I did not expect that as Sister Miya, I helped to gather them, attract each other, and connect them into a string of sparkling necklaces. This is one of the few things I have done in my life that I feel is particularly valuable.</p>
<p>In 2017, I will work hard to be a better Sister Miya.</p>
</blockquote>
<p>And then, I happened to see sentimental You Tiao (油条) posting an article in his moments, as sensitive as I am, and tears came instantly.</p>
<p>The article explained why he had to continue to lead a group of people to operate the freeCodeCamp Shenzhen Community, even when he had just dropped out of school and switched to front-end development less than a year ago. The boss of his team had high hopes, and the work was super busy:</p>
<blockquote>
<p>Everyone around me, including me, is facing perhaps the most challenging stage of life:</p>
<p>At the age of 20, we came to this city alone. And Shenzhen's ridiculously high rents have caused almost everyone to stay in a room smaller than 10 square meters (107.64 square feet) or live in an area that is an hour away from the company.</p>
<p>Life is difficult, and everyone starts to do everything alone. Extroverts may be better, but introverts are always in a bad situation.</p>
<p>I often say that the freeCodeCamp Shenzhen community wants to be an offline knowledge-sharing platform, but it is actually inaccurate.</p>
<p><strong>It is really important to find a few friends to spend the holidays with through offline events.</strong></p>
<p>Sometimes, my friends' conversations make me feel sorry.</p>
<p>I remember one night, while drunk, a friend said to me, "Did you know? I no longer have a home."</p>
<p>I didn't know. If he hadn't mentioned it, I would never have known it. I saw the kind of loneliness in his eyes.</p>
<p>I know he needs someone to help him, but Shenzhen is so big. Who cares about a person who usually does not talk?</p>
<p>One day, a friend from freeCodeCamp stayed after dinner and took me home. I guessed that he wanted to speak to me. We spoke pretty late that night.</p>
<p>He talked to me about his work, his love, and his social fears. Under the dim light of my house, I could feel the deep concern in his eyes.</p>
<p>That's it! If a person who is not good at expressing his feelings doesn't get a chance to do so, how can he expose his thoughts to others?</p>
</blockquote>
<p>I do understand this feeling! I once went to Suzhou to look for a job alone. Without a companion. I didn't even know where to go shopping if I wanted to buy clothes. </p>
<p>At that age, "loneliness" may be our closest friend. That was the first time I knew that freeCodeCamp has such meaning to these people. It would be great if every city had such a warm community.</p>
<p>You Tiao's article reminded me: <strong>We need to meet, to chat face to face, and to feel and listen attentively</strong>.</p>
<p>It's like the point in Fyodor Dostoevsky's "Brothers Karamazov" described by Prof. Luo Xiang (A famous Chinese jurist) recently:</p>
<blockquote>
<p>Love a specific person, not an abstract person.</p>
</blockquote>
<p>Since then, I no longer like to stand on stage in the spotlight. I prefer to listen to other people's stories off stage, encourage everyone to share, and applaud for them.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/2020-china-open-source-conference.png" alt="Miya and other participants at the 2020 China Open Source Conference" width="600" height="400" loading="lazy"></p>
<p>During the 2020 China Open Source Conference, I exchanged ideas about the concept of community with two volunteers.</p>
<p>I recently chatted with a friend. He said the most touching thing was that some friends told him that "participating in the community activities organized by you relieved my depression."</p>
<p>Yes, <strong>the impact of the community on people is far more significant than we thought</strong>. I am happy to have friends who have made the same discovery as I have and continue to pass on warmth and kindness through the community ^_^</p>
<p>At the end of the second day of this year's China Open Source Conference, a girl said to me: </p>
<p>"I have been observing you for a day and found that you can explain the word 'open source' in different ways that different people can understand. That is, you can combine with their own experience and make them understand - 'Oh, it turns out that this is open source.'</p>
<p>You also encouraged everyone to share. Nobody will feel that the activity has anything to do with them here. I like your warmth."</p>
<p>I said, "Thank you for expressing your approval for me so bluntly. The word 'warmth' is what I want to express!"</p>
<p>In fact, I understand what it is like to "feel that the activity has nothing to do with me and feel out of place."</p>
<p>Before switching to the Internet industry, I worked in an international project management company as a project assistant.</p>
<p>Later, I also started to work on contract management and business development. At that time, I worked very hard and the general manager, my superiors, colleagues, and customers all really appreciated me.</p>
<p>Once, the general manager Michael went to a large meeting and specifically asked my boss Jessie to inform me to go with him. </p>
<p>The purpose of letting me attend the event was to allow me to gain insight. </p>
<p>That morning, I was wearing my only formal suit, awkwardly stepping on high heels, and following Jessie into a large and luxurious meeting room in the hotel.</p>
<p>It was the first time I participated in such a grand event, and I was excited. </p>
<p>I was thinking about where I would sit when Jessie told me, "They only planned two seats for us. You should go and find somewhere else to sit."</p>
<p>As a result, I went to the conference room corner and sat in the staff resting area. I tried to listen to those one or two hundred people in academia and business area discussing topics that I did not understand. I couldn't listen at all. Even though I was well-dressed, I felt that I did not even have a seat. </p>
<p>It was ironic that, even though I was well-dressed, I did not even have a seat, and I didn't fit in with those successful people. Soon, my face was flushed, and I thought to myself: I hate this place, I want to leave.</p>
<p>Thanks to Michael, he is a very caring boss. Thanks to my boss Jessie, she always takes care of me like a big sister.</p>
<p>They seemed to notice my embarrassment, so Jessie walked over to me and said, "Miya, go sit next to Michael. I have to go back to the company."</p>
<p>I have no impression at all of what people discussed in that meeting.
But I remember that Michael lowered his head and said to me very gently: "To be honest, what they said has no value. You are nobody now, and no one will listen to you. But one day, when you become somebody, you will speak on it. Others will think what you are talking about is very important."</p>
<p>I was impressed by his words. I just nodded and thought secretly:</p>
<blockquote>
<p>If I really become somebody one day, I don't care where I sit or how many people listen to me. But I will pay attention to whether there is a girl in the corner who looks embarrassed because of being incompatible with the crowd.</p>
<p>I would walk over and smile and ask her: "What is your name? Do you have any thoughts on the topic everyone is talking about?"</p>
</blockquote>
<p>Just like I am willing to listen to a bus driver who is easily ignored - <strong>I believe that everyone has a story that is worth being heard. If no one provides them with such a stage, I will.</strong></p>
<h2 id="heading-bubble">Bubble</h2>
<p>In Quincy's <a target="_blank" href="https://community.hackernoon.com/t/im-quincy-larson-the-teacher-who-founded-freecodecamp-org-ask-me-anything-july-25-2019/5539">AMA</a>, I liked his answer to the following question. AMA stands for ask me anything.</p>
<p>How do you plan to teach/educate your kids? Did you ever consider homeschooling?</p>
<blockquote>
<p>Homeschooling is a good alternative if you have a lot of kids, and a parent at home who can teach. But socialization and building up EQ is important, and you kind of get that built in to the public school experience.</p>
<p>I learned a lot from going to public school. There were short-comings. But if I had just gone to a private school, I would have been insulated from reality. I don't want my kids to grow up in a bubble.</p>
</blockquote>
<p>What does it mean to grow up in a bubble? Maybe all her friends are little princes or princesses with good family conditions. She has no chance to meet someone who can't pay the tuition and has to eat buns in the corner during lunchtime. She will think everyone in this world is like her. That they all enjoy convenient and abundant living resources and educational resources.</p>
<p>But the reality of this world is not like this. When she grows up, can she handle the impact of reality?</p>
<p>Now, try to think about it. Are there any moments that make you feel that a bubble has broken?</p>
<p>Let me share some:</p>
<p>In December 2018, in Beijing, Quincy told me that a young man in rural Nigeria was learning to program on an old Nokia phone because he couldn't afford a computer.</p>
<p>Later, he became an Android engineer and worked remotely with people from Harvard and MIT. In fact, many people in the world learn to program like this.</p>
<p>At that time, I had just bought my second MacBook.</p>
<p>In May 2019, I participated in the <a target="_blank" href="https://changemakerxchange.org/">ChangemakerXchange Asia Summit</a> in Hangzhou. The organizer selects 20 people from nearly 1,000 applicants to participate in this event every year. These participants are very kind young people who care about the world.</p>
<p>In a discussion, a guy from Thailand who runs a non-profit organization in Myanmar asked us how we learned English. Two participants from Singapore and a girl from Beijing said they had English classes since the third grade of elementary school. I said, in Sichuan, I started to learn it in junior high school. I thought that guy would say that he started learning English in high school or university. Still, he told us he learned English in a refugee camp a year ago for the first time.</p>
<figure>
    <img src="https://www.freecodecamp.org/news/content/images/2022/03/2019-changemakerxchange-asia-summit.png" alt="Group photo at the 2019 ChangemakerXchange Asia Summit" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>Participants of the 2019 ChangemakerXchange Asia Summit and the beloved bear</figcaption>
</figure>

<p>In June 2019, my team and I were working in Hong Kong. Every night we would have a walk at Victoria Harbor after dinner and explore the city. </p>
<p>One night, I went back to the hotel, turned on the air conditioner, opened Facebook, and saw a piece of news: A refugee father and daughter drowned while trying to swim to the United States. The child was only one year old. Her mother was standing at the shore, looking at her, but could not help.</p>
<p>Also, in 2019, I read from an article by the founder of the Kedou School:
According to the statistics of the Stanford Rural Education Action Program (REAP), 63% of rural students in poverty-stricken areas of China have never entered a high school, let alone a university. </p>
<p>According to statistics from the National Bureau of Statistics of China, nearly 10 million children aged 16-18 become a new generation of migrant workers, constituting 3% of the migrant worker group.</p>
<p>I used to be a left-behind child. In May, I returned to my hometown to visit a teacher in junior high school. He told me that almost 20 years have passed, and most of the children in my hometown are still left-behind children.</p>
<p>In September 2021, I was sitting on the side of the road waiting for an old friend to have a hot pot together. A takeaway courier stopped his car in front of me, looking a little worried and helpless.</p>
<p>I asked him if he couldn't keep up with the delivery and advised him not to worry. He could call the customer to explain. The customer should understand.</p>
<p>He said that he had already missed the deadline, and the customer canceled the order for more than 50 cups of milk tea. The platform punished him for more than 500 yuan.</p>
<p>Even though I usually did not drink milk tea, I bought two cups from him and chatted with him.</p>
<p>The young man is 18 years old and just dropped out of high school. He came to Chengdu from his hometown in Dalian for love.</p>
<p>He was looking for various jobs and was scammed for money during that time.
Now that he is looking for his next job, he is worried that he will not be able to get married in the future, and he is very anxious.</p>
<p>So I recommended freeCodeCamp to him so he could learn to program. I added his WeChat ID and sent him the website.</p>
<p>He said it was great, and he had heard of programming and wanted to learn!
When he was about to set off, I told him that his life had just begun, and safety was the most important thing. Don't learn bad things. Learn a skill. If you can't persist, you can go back to your hometown.</p>
<p>On the way home that night, I thought: We weren't in such a good state at the beginning. When I was 18, I seemed to be so anxious to see what my future life would be like. With so many young couriers hurrying past us in this city, do they have a chance to stop and talk about their anxiety?</p>
<p>When I see and hear these things, I always feel sad and helpless: many people in this world need help. I can listen to some people and support some, but I can't help everyone.</p>
<p>In the article <a target="_blank" href="https://mp.weixin.qq.com/s/1mmgOjWHIBmJtFOHxqwonQ">Yi Nuo: What We See Is Often a One-Sided Fact</a>, Li Yinuo (李一诺), founder of <a target="_blank" href="https://www.etuschool.org/">ETUSchool</a> and former chief representative of the Beijing Representative Office of the Bill and Melinda Gates Foundation, wrote:</p>
<blockquote>
<p>Whose voice are we hearing? I think it is the voice of those who can speak. However, many social problems are often impacted by those who cannot speak up.</p>
</blockquote>
<p>Fortunately, in so many corners of the world, we have so many kind friends who are willing to listen to the voices of those who have no chance to speak up and then devote themselves to caring for refugees, migrant workers, longly old people, and left-behind children...</p>
<p>When discussing the focus of my work, Quincy once asked me: Do you want to help only people in Chengdu, Sichuan, or people all over the world?</p>
<p>I agree with what Quincy said:</p>
<blockquote>
<p>freeCodeCamp will help people at scale. Our resources are limited, and we want to help many people a little bit, not a few people a lot.</p>
</blockquote>
<p>In fact, a person who really desires to change only needs a little help and guidance from us. And they will follow the path to change. Sometimes, they will also turn around to guide others.</p>
<p>I like this article: <a target="_blank" href="https://www.freecodecamp.org/news/how-i-became-a-programmer-with-the-100daysofcode-challenge-19b01f17bca1/">How I became a programmer with the #100DaysofCode challenge</a>. The protagonist was born in a rural village in eastern Nigeria where resources are scarce, electricity is not available year-round, and people have no access to the Internet. Her mother knew that the only way out for a rural girl was to get an education, so she worked hard to receive higher education. </p>
<p>After graduation, she worked as a customer service representative in a company. The company was reorganized, so she decided to learn to program. Because she could not afford the tuition, she found that she could study for free at freeCodeCamp. </p>
<p>Later, she became a developer, improved her work and life, and founded a social enterprise, GreyAfricaHub, to help other young people learn to program and reduce the country's unemployment rate.</p>
<figure>
    <img src="https://www.freecodecamp.org/news/content/images/2022/03/greyafricahub.png" alt="Learners in a GreyAfricaHub class" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>GreyAfricaHub provides free web design training courses for local young people</figcaption>
</figure>

<p>There are many such student stories in the freeCodeCamp community.
For example, a security guard on the university campus <a target="_blank" href="https://www.freecodecamp.org/news/from-self-taught-coder-to-professional-backend-developer-my-long-winding-road-d8f7c428b637/">switched his career to become a back-end developer through self-taught programming</a>, created a better life for his family and founded a programming community Open Source Weekends to help more people.</p>
<figure>
    <img src="https://www.freecodecamp.org/news/content/images/2022/03/security-guard-to-developer-career-changer.png" alt="Screenshot showing a congratulatory tweet from Campus Madrid to a former security guard-turned-developer" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>The social media account of the Madrid campus sent a message to congratulate the security guard for his successful career change</figcaption>
</figure>

<p><strong>When we want to help a large community, working smart is more important than working hard.</strong></p>
<p>There are so many meaningful things we can do. Writing an article, recording a video tutorial, answering a question on the forum, submitting an issue or pull request on GitHub, chatting with a volunteer contributor, discussing activities with partners, and introducing to a university teacher what we are doing...</p>
<p>How can we prioritize everything among all the inexhaustible details and do the most correct thing at the moment? It is in this ability that a community leader needs to be trained.</p>
<p><strong>And if we continue to do the right thing, more and more people will support us, and the road will become broader and broader.</strong></p>
<p>Thanks Mr. Wang Wei from East China Normal University, for inviting us to participate in the <a target="_blank" href="https://mp.weixin.qq.com/s/Epgz0GeiAbDlDXgkh8Sw9w">First Symposium on Open Source Education in China (SOSEC)</a>.</p>
<p>We were honored to be the only representative from the grassroots community to communicate with people from more than a dozen universities, scientific research institutes, and large domestic and foreign companies across the country and benefit a lot.</p>
<figure>
    <img src="https://www.freecodecamp.org/news/content/images/2022/03/shui-ge-presenting.png" alt="Sui Ge presenting at a conference" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>Shui Ge (水歌), who has led the freeCodeCamp Chengdu community since 2018, was sharing at the meeting how open communities could help young people to grow</figcaption>
</figure>

<figure>
    <img src="https://www.freecodecamp.org/news/content/images/2022/03/miya-presenting-fcc.png" alt="Miya introducing fCC at a conference" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>I was introducing freeCodeCamp at the conference</figcaption>
</figure>

<p>The conference was held at the Sichuan Nationalities Institute in Kangding. I was happy to see many students at the meeting because I always hope that my sharing can inspire young people. Some friends told me one thing I said that they liked most:</p>
<blockquote>
<p>Bringing a beautiful change to the world is not about one person doing a lot, but everyone doing a little bit.</p>
</blockquote>
<p>At dinner, President Zhou of East China Normal University quoted Shui Ge in his speech:</p>
<blockquote>
<p>The open community is a space for young people to educate themselves in addition to family, school, and social education.</p>
</blockquote>
<p>President Zhou said that colleges and universities should cooperate in providing such space for young people. Thanks for the recognition!</p>
<h2 id="heading-kedou-school-is-the-closest-open-source-community-to-us">"Kedou School is the closest open source community to us"</h2>
<p>In the open session of this year's open source conference, someone told me that after hearing me talk about "open source," as a person who is not in this field, they feel that everyone has their own understanding of "open source community" in their hearts. I said that was right. I just wanted to share a story.</p>
<p>In 2019, my friend Ying from the <a target="_blank" href="http://www.ginkgofoundation.org/">Ginkgo Foundation</a> introduced me to the Principal <a target="_blank" href="https://mp.weixin.qq.com/s/lJdIcgGGHYWcTs_IU6oA6g">Ouyang Yanqin (欧阳艳琴</a>, the founder of the Kedou School, and volunteer Teacher <a target="_blank" href="https://chinese.freecodecamp.org/news/explore-programming-education-for-high-school-students-with-limited-resources/">Chen Yishuai (陈一帅)</a>. They are using freeCodeCamp's programming courses. </p>
<p>I have read a lot of information about this public welfare school for children of migrant workers or fringe urban youths aged 16-18, and have paid attention to its developments.</p>
<p>The school is committed to "promoting educational equity," similar to freeCodeCamp. The kindness and vitality of the teachers and classmates deeply moved me.</p>
<p>Especially Chen Yishuai, an associate professor at the School of Telecommunications of Beijing Jiaotong University. He is very easy-going. He volunteers at the school to teach programming. He explores with friends the front-end programming education program for high school students with limited resources under holistic education.</p>
<p>Later, I met several teachers from different universities, such as Teacher Wang Wei (王伟) from East China Normal University and Teacher Zeng Zheng (曾铮) from Beijing Information Science and Technology University.</p>
<p>These teachers have two things in common. One is that they are dedicated to helping students grow. The other is that they all recognize the value of freeCodeCamp.</p>
<p>Sometimes I think, should I connect these teachers so they can get to know each other just like I connect young people?</p>
<figure>
    <img src="https://www.freecodecamp.org/news/content/images/2022/03/chen-yishuai-and-students.png" alt="Chen Yishuai walking with students on the Kedou School campus" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>Chen Yishuai (陈一帅), a volunteer teacher in the programming class of the Kedou School, and his students</figcaption>
</figure>

<p>In October of this year, I recommended that <a target="_blank" href="https://chinese.freecodecamp.org/news/how-i-learn-to-code-within-online-and-offline-open-source-community/">Junyan (俊雁)</a> and <a target="_blank" href="https://chinese.freecodecamp.org/news/how-i-learn-to-code-within-online-and-offline-open-source-community-and-share-what-i-learn/">Eric</a> from the Kedou School give presentations at the <a target="_blank" href="https://sosconf.org/">Student Open Source Conference</a>. </p>
<p>This event is similar to the China Open Source Conference organized by the Chengdu community. However, it is the world's first open-source technology summit organized entirely by students. The primary purpose is to guide and encourage students so they learn how to understand, participate in, and contribute to open source.</p>
<p>Then, on the first evening of the China Open Source Conference, I chatted with Zhu Ruijie (朱芮捷), the chief orgnizer of the Student Open Source Conference and a student from the University of Electronic Science and Technology of China. He told me that he felt that <strong>the speakers from the Kedou School were better than most of the students he knew in the university</strong>.</p>
<p>Previously, I had read a lot of positive feedback about the students in the Kedou school from teachers, students, media, parents, and employers. But this was the first time I had heard such high feedback from an outstanding person of their peers!</p>
<p>That was the happiest moment in the whole COSCon. I felt very excited and pleasantly surprised. I wanted to share the story of the Kedou School with more people.</p>
<p>Of course, Ruijie is good at discovering the advantages of people around him and expressing his approval straightforwardly, which is also commendable in itself.</p>
<p>You know, the Kedou School is for children who are considered "study slackers" under the traditional education system, and some of them have been abandoned by teachers and expelled from the school.</p>
<p><strong>Thank you, Kedou School, for showing us another possibility for education.</strong></p>
<p>When I forwarded Ruijie's feedback to Ouyang, she said, "Miya, thank you, although I have never met you before, I feel so much warmth and support from you." Haha, the warmth is mutual.</p>
<p>Here is the speech (in Chinese) of the two students above. Feel free to read: <a target="_blank" href="https://mp.weixin.qq.com/s/H1NZvWVUO_Isz6omrTj3fA">Using Online and Offline Open Source Communities, Young People Who Have Never Had a Chance to Learn Become Programming Learners</a>.</p>
<p>In an interview before the meeting, the two students said:</p>
<blockquote>
<p>I think the Kedou School is the closest open source community to us. In the school, some students will learn programming, some will learn design, and some will learn other majors. Offline, students study together, discuss together, and help each other.</p>
<p>Every Saturday, students will also have a discussion meeting. Each student will share what they have learned this week, what problems they have encountered, and how they feel. There is a board in the school, with three words written on it, <code>&lt;Love /&gt;, &lt;Study /&gt;, &lt;Together /&gt;</code>. I think this is the experience that the open-source community of Kedou School brings to us.</p>
</blockquote>
<p>I like to communicate with these kinds of young, curious students who can speak very well when they talk about things they like.</p>
<p>I remember that in the open session of the China Open Source Conference, Eric (龙则灵), a freshman at the University of Electronic Science and Technology of China, shared with everyone his microservice framework Hive written in Rust with great enthusiasm. Even when the host directly told him, "It's time to stop," it couldn't stop him from talking.</p>
<p>My little fellow, Charles, a freshman at the University of Electronic Science and Technology of China, is very eager to share his experience in the school Linux user group.</p>
<p>I asked him what he did in the club, his big eyes flickered, and he said, "I'm a freshman, now I'm studying." Haha, it's cute.</p>
<p>And Ruijie, their senior, introduced to us the significance of the Student Open Source Conference and the Linux User Group to help students grow, which is as stable as ever and inspiring.</p>
<p>Jin Xiao (金霄) from Sichuan University talked about how he went from being quite introverted to becoming active in the community and actively cooperating with everyone in the student's association.</p>
<p>At the same time, he prepared the "Guess the Open Source Logo Game" to create a relaxed and cheerful atmosphere.</p>
<p>Ever since I met that bus driver in 2015, I have often been moved by energetic young people – they're always young, and they always have stars in their eyes.</p>
<p><strong>At this stage, I started to wonder, besides "education and public welfare," what else do I like and am I good at? What else do I have the capacity to do? I think it is "youth development."</strong></p>
<p>As mentioned above, in the whole process of exploring and discovering the meaning of life, I basically guided myself through the chaos bit by bit. 
Back then, I had hoped someone else could give me some guidance. Now, maybe I could give others some guidance.</p>
<p><strong>Thanks to this great era, young friends have many channels and opportunities to communicate with and learn from people from all fields of society. Of course, joining an open community is a great way to do it.</strong> In the community, no matter what you want to do, as long as you share it, someone will respond.</p>
<p>We are already collaborating with individuals and organizations concerned with developing youth at different stages – from elementary school to junior high school, high school, and university – to plan some beautiful actions.
All this requires long-term investment, and no rush. We'll spend many years doing this.</p>
<h2 id="heading-what-was-i-born-for">What Was I Born for?</h2>
<p>Recently, I was chatting with a musician friend trying to "bring music closer to life." I said to him, "You were born for 'music for good.'"</p>
<p>Then I thought: What was I born for?</p>
<p>This is the last story of this article, and we finally reach this ultimate question.</p>
<p>After writing thousands of words eloquently, I got stuck here.</p>
<p>I didn't know how to write it down, so I flipped through the book, went through Zhihu (知乎, a Chinese version of Quora), and thought about it...Three hours later, I suddenly understood: thinking about this question, it really takes a lot of time (smiling face).</p>
<p>I know that many young friends came to the community with this question, so let me talk about some key points that I think of now.</p>
<h3 id="heading-learning-by-doing">Learning by Doing</h3>
<p>In 2015, in the office of an entrepreneur friend, I saw a message from the founder of Virgin:</p>
<blockquote>
<p>If somebody offers you an amazing opportunity, but you are not sure you can do it, say yes – then learn how to do it later! —— Richard Branson</p>
</blockquote>
<p>I stood by that wall and looked at it for a long time. Then I kept this sentence in my heart and practiced it in the same way. This is similar to the learning philosophy advocated by our freeCodeCamp community – learning by doing.</p>
<p><strong>If we always feel confused, it may be because we have not done enough.</strong></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/03/miya-fang-hua.jpeg" alt="Miya with her back turned to the camera, on a sidewalk in the fall" width="600" height="400" loading="lazy"></p>
<p>I like this photo of myself. It makes me feel calm. It was taken in Chengdu in 2019, and I named it "Fang Hua (芳·华)", or Beautiful Age.</p>
<h3 id="heading-accept-yourself">Accept Yourself</h3>
<p>In 2019, at the sharing session before the end of the five-day ChangemakerXchange summit, I said:</p>
<blockquote>
<p>My biggest gain in this event is to accept myself – I don't have to be so good, I don't have to be so different, I don't have a high degree of education, I'm weak in hands-on skills, I don't know how to play Legos, I can't dance, I'm introverted. I won't be able to chat with everyone anytime soon ...</p>
<p>In my work, I will chat with many people, help many people, try to tolerate others, and act as if I can do everything.</p>
<p>Thanks for the experience of this event. It turns out that "admitting that I can't do it" is not so terrible. I really accepted myself for the first time.</p>
</blockquote>
<p>The official introduction of ChangemakerXchange is "the world's premier community platform for more than 600 young social entrepreneurs across 80 countries including Europe, Africa, and Asia".</p>
<p>In my opinion, it is to help everyone relax and heal. This event is the best event I have ever participated in.</p>
<p>When exchanging sugar cube parting words with each other, two of the things I received were:</p>
<blockquote>
<p>- You are the most adorable person I have ever seen, and you taught me to be myself and find courage in fragility.</p>
<p>- You are the most outstanding member of this summit, and you are as beautiful as blooming flowers.</p>
</blockquote>
<p><strong>Accepting yourself is a required course in life.</strong></p>
<h3 id="heading-this-world-is-pretty-good">This World Is Pretty Good</h3>
<p>In 2019, I saw <a target="_blank" href="https://mp.weixin.qq.com/s/Qr4dBwO77nUcj44ituMWQw">this article</a> telling a story that happened in Detroit, USA:</p>
<p>On the day an 86-year-old grandfather retired, the bus driver, passengers, family, friends, and colleagues held a warm and pleasant surprise "retirement ceremony" for him on the bus that he had been riding for 60 years.</p>
<p>For some of the drivers, they and the grandfather had not just had a typical relationship of driver and passenger, but had become friends for life.</p>
<p>A boy had been on the bus with this grandfather for more than ten years and came back from another city where he was working to take the 530 bus with him for the last time.</p>
<p>They boarded the bus with photos of this grandfather at different ages, from 20, 30, 40, to 86 years old... On this bus, the grandfather seemed to see his entire life.</p>
<p>I wrote in WeChat moments at the time:</p>
<blockquote>
<p>I feel more and more that this world is pretty good, and there is no need for the so-called "world-changing people," and no one can change the world.</p>
<p>What we need to change is ourselves. When we are more used to expressing our love and gratitude for others sincerely and naturally, we take a step towards a better world.</p>
<p>This action is simple, but it seems complicated.</p>
<p>May we all treat this world tenderly and be treated tenderly by the world.</p>
</blockquote>
<p><strong>Well, the world is pretty good. We don't have to worry about what we will change, just relax and experience and feel it.</strong></p>
<p>Now, the story is over.</p>
<p>So, I don't think about the profound question of "what was I born for." I used to discuss with a good friend that life is meaningless – go to bed early, get up early, go out in the sun when the weather is good, look at the flowers on the way to work, and spend every day vigorously......feel it, explore it – that is the meaning.</p>
<p>Oh, yes, I saw a chubby puppy jumping up happily on the road two days ago, so cute. I met it again the next day, and I couldn't help laughing.</p>
<p>A student in the Kedou School described his programming volunteer teacher Chen Yishuai as "a lively and kind fish." I like this description. I think it’s full of spirituality. It must be a wonderful student and a wonderful teacher to come up with such a beautiful sentence.</p>
<p>I also hope that I have that status.</p>
<p>There are two Yu, which means fish in Chinese, in my name, it just so happens. And I am Pisces, which also contains fish. I also like to eat fish. So I have a good relationship with fish ;)</p>
<p>Do good things, and don't ask about your future, as Steve Jobs said:</p>
<blockquote>
<p>You can't connect the dots looking forward; you can only connect them looking backward. So you have to trust that the dots will somehow connect in your future.</p>
</blockquote>
<p>Perhaps, when we are old, looking back on our life and connecting the bits and pieces together, we can answer very well why we lived in this life.</p>
<p>Thanks for reading.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Inside the Hack for Wuhan Hackathon – How Developers Fought COVID-19 ]]>
                </title>
                <description>
                    <![CDATA[ The Chinese New Year in 2020 was one of the saddest Chinese New Years in recent memory. After the sudden outbreak of the COVID-19 virus, the city pressed pause on all celebrations. And now – even as the pandemic lets up in China – schools remain clos... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/wuhan-hackathon/</link>
                <guid isPermaLink="false">66d85ab229e30bc0ad477652</guid>
                
                    <category>
                        <![CDATA[ coronavirus ]]>
                    </category>
                
                    <category>
                        <![CDATA[ hackathon ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Tue, 24 Mar 2020 23:05:05 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/03/image-38-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The Chinese New Year in 2020 was one of the saddest Chinese New Years in recent memory. After the sudden outbreak of the COVID-19 virus, the city pressed pause on all celebrations.</p>
<p>And now – even as the pandemic lets up in China – schools remain closed. Most of the shops are still closed. People still can’t go out and enjoy the spring.</p>
<p>In this global public health crisis, it's not just front line medical staff taking action. Other people are producing masks and protective equipment, transporting daily supplies, and providing psychological assistance to people in affected areas.</p>
<p>And developers are jumping into action, too.</p>
<h2 id="heading-the-hack-for-wuhan-hackathon"><strong>The </strong>Hack for Wuhan<strong> H</strong>ackathon<em>**</em></h2>
<p>The <a target="_blank" href="https://github.com/wuhan2020">wuhan2020 open source community</a> planned a big <a target="_blank" href="https://github.com/wuhan2020">hackathon</a>. The theme: open source collaboration to tackle the challenges behind the epidemic.</p>
<p>Together, they encouraged developers to take advantage of their own technology to support this new smokeless war.</p>
<p>wuhan2020 is a group of independent developers who write code to aggregate and analyze epidemic data. They use this to predict the spread of the virus and figure out where to send medical supplies.</p>
<p>Since wuhan2020 was created in January, it has already attracted more than 3,000 volunteers from different countries.</p>
<p>They reached out to freeCodeCamp asking if we'd be interested in helping support their upcoming hackathon. I also discovered that the leader of freeCodeCamp's Chengdu study group, Shui Ge, was one of wuhan2020's core developers.</p>
<h2 id="heading-how-freecodecamp-got-involved">How freeCodeCamp Got Involved</h2>
<p>freeCodeCamp joined the hackathon organization team as a cohost. Several of our contributors helped plan the competition, served as judges, and maintained the <a target="_blank" href="https://github.com/wuhan2020/Hackathon">GitHub repository</a>.</p>
<p>It took only 20 days from initial idea to hosting the hackathon itself.</p>
<p>Here is some quick data about the event:</p>
<ul>
<li>More than 50 volunteers hosted the competition</li>
<li>902 contestants from 33 countries signed up</li>
<li>33 teams entered the preliminary round. 12 teams reached the final round. And 8 teams won the grand prize.</li>
<li>4 companies provided technical resources for the competition, including IBM Developer, Agora.io, Tencent Serverless,  and Amazon Web Services.</li>
<li>45 industry professionals around the world provided guidance, such as Connie Chan at the Andreessen Horowitz Venture Capital firm, former Alibaba CTO Zhuang Ziming, and Eva Woo from The Stanford Center on Philanthropy and Civil Society (PACS)</li>
<li>48 media published articles about the hackathon that more than 700,000 people read</li>
</ul>
<p><img src="https://chinese.freecodecamp.org/news/content/images/2020/03/image-40.png" alt="Image" width="1080" height="485" loading="lazy">
<em>Even more data. Yes - this is in Chinese but if you can't read Chinese you may be able to guess the meaning from the icons :)</em></p>
<h2 id="heading-hackathon-themes"><strong>Hackathon </strong>Theme<strong>s</strong></h2>
<p>The overall theme of the hackathon was: use open source software to solve the social challenges behind the epidemic. </p>
<h2 id="heading-introducing-some-of-the-winning-projects"><strong>Introduc</strong>ing Some of the Winning Projects</h2>
<p>The 12 finalists started their live demos online, and judges were able to comment online as well.</p>
<h3 id="heading-finalist-a-one-stop-open-platform-for-epidemic-data"><strong>Finalist: A </strong>One-stop<strong> O</strong>pen<strong> P</strong>latform for<strong> E</strong>pidemic<strong> D</strong>ata<em>**</em></h3>
<p>This open platform helps researchers efficiently collect, label, and analyze outbreak data.</p>
<p>Lots of official agencies and health commissions report fine-grained epidemic data. But the data formats are often incompatible, and require humans to interpret them. This makes it impossible to use crawlers to automatically crawl and structure the data. You have to introduce skilled manual labor.</p>
<p>So how do you collect data efficiently with as little labor as possible?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-149.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This project adopts an open source collaboration method, bringing all people interested in the data to this platform. Then the platform helps people structure and label the data.</p>
<p>Once that's done, the platform makes the data available through a public API. Scientists and developers can build other tools on top of this API.</p>
<h3 id="heading-autovax"><strong>autovax</strong></h3>
<p>Autovax is a web application that allows a vaccine and other treatment drugs to be automatically generated from the virus genome and virus genes.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-151.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>A researcher from Harvard is developing this to help with COVID-19.</p>
<h3 id="heading-city-hero"><strong>City Hero</strong></h3>
<p>In this educational game, you can choose a profession – such as doctor or nurse – to experience their life during the pandemic. This helps players understand the people involved in the aid effort, and the difficult choices they face.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/image-148.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-the-path-forward">The Path Forward</h2>
<p>The Hack for Wuhan hackathon was not just a challenge for the contestants, but also a challenge for the organization team. We planned and executed everything in just 20 days, and helped 900 developers participate.</p>
<p>I want to thank everyone involved. And thank you for reading this hackathon report.</p>
<p>I hope you all will stay safe, and that we can all embrace spring as soon as it's safe.</p>
<p>If you are interested in learning more about these projects, or participating in our next hackathon, you can contact me on WeChat at fcczhongguo, or <a target="_blank" href="https://twitter.com/miyaliu666">on Twitter</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
