<?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" version="2.0"><channel><title><![CDATA[ammarite]]></title><description><![CDATA[ammarite]]></description><link>https://mmarsaf.xyz</link><generator>RSS for Node</generator><lastBuildDate>Sat, 11 Apr 2026 18:53:23 GMT</lastBuildDate><atom:link href="https://mmarsaf.xyz/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Temporal as Data Orchestrator]]></title><description><![CDATA[This is neither some notes nor advice based on my experience of using Temporal as data orchestrator for my ETL pipeline. Initially I felt it just the same as other orchestrators like Airflow, Prefect, or Dags or what so ever, however I learned it in ...]]></description><link>https://mmarsaf.xyz/temporal-as-data-orchestrator</link><guid isPermaLink="true">https://mmarsaf.xyz/temporal-as-data-orchestrator</guid><category><![CDATA[temporalio]]></category><category><![CDATA[Orchestration]]></category><category><![CDATA[data pipeline]]></category><category><![CDATA[data-engineering]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Wed, 12 Nov 2025 01:27:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/4XvAZN8_WHo/upload/c894a822855745f473a690e5480c43aa.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is neither some notes nor advice based on my experience of using Temporal as data orchestrator for my ETL pipeline. Initially I felt it just the same as other orchestrators like Airflow, Prefect, or Dags or what so ever, however I learned it in hard way because of the concept of durable execution.</p>
<h1 id="heading-durable-execution">Durable execution?</h1>
<p>It means, the process or function or method that you want to run will never failed. (it actually will failed, based on the maximum attempt that you decide to put). What it means to be never failed is, it will do exponential backoff retry, to ensure the process succeed. Even if it is failed, it can continue from the last state or checkpoint it failed within the workflow.</p>
<p>In order to do this, Temporal saves the state in the event history, which has limited of payload size, which has became a headache for me to solve the issue at first (but then can be solve using Temporal features).</p>
<p>The reason is the limitation of the payload size, although you can overwrite it in config (sadly cannot configured through Python SDK, but in Go), is first because of the durable execution itself. Imagine, you have something huge, which is the payload that you fetched from API or database. The workflow then failed, which then will be retry again from the last checkpoint saved in the event history but fetching <em>again</em>; this workflow then will consume so much computation as it will retry and trying to process that big chad payload and still save it into the history, that soon will affect the performance.</p>
<p>Hence to solve this, Temporal introduced <code>continue_as_new</code> and <code>child_workflow</code> to solve the problem. By having continue-as-new, it will create a new fresh empty event history to run the workflow, while using the child workflow by iterating through all the item can batch the workflow into respective item to be executed, instead of relying on a single workflow.</p>
<p>This would also help the monitoring the workflow progression, and ensure decoupling and atomic workflow.</p>
<h1 id="heading-functional-or-oop">Functional or OOP</h1>
<p>In Temporal, the Workflow components consists of function, or can be called as Activity. Activity can be a function or a method (OOP). Personally if I can turn back time I will just do functional programming, instead of OOP in my pipeline. I used OOP because it is easier for me to access the method within the class, as of the assistance of intelli-sense within the VSCode.</p>
<p>Nevertheless, you can just design a <em>stateless</em> OOP, because we cannot having state within Temporal due to the durable execution again. Hence, to use OOP, you need to design in away either of <code>staticmethod</code> or just treat it like a normal function, but just in a class. (not saving or mutating the object attribute).</p>
<h1 id="heading-non-deterministic">Non-deterministic</h1>
<p>Another concept that I learned is the non-deterministic, which is from the non-deterministic error. This is just another fancy words in data engineering, similar to idempotent, which is the consistent value produced whenever the process run.</p>
<p>This happened when I intend to get the current timestamp using <code>datetime.now()</code> in the workflow. Anything that is non-deterministic are not allowed in the Workflow, also due to the durable execution. Temporal need to ensure that whenever the Workflow crashed or reset, and undergo retrying, the Workflow still have the same value like the first time execution. Using <code>datetime.now()</code> will produce different value whenever retrying happened, as it dynamically change the value based on the current time, hence it is not allowed in Temporal.</p>
<p>To solve this problem, we can declare the current time on the client side. This will make sure the execution of the time value variable like now, or yesterday would be consistent and allowed by Temporal.</p>
<h1 id="heading-steep-learning-curve">Steep learning curve</h1>
<p>I have some experience of using other data orchestrator such Airflow, Prefect and Dags, however Temporal giving the steepest learning curve for me to understand, given its design of durability execution and gRPC, and also the method of running the Activity and Workflow is different compared to Airflow and other dags based orchestrator that only required functions to be wrapped and executed.</p>
<p>Always in my mind during the development of the pipeline without Temporal that why it was limiting the payload size and history, because without Temporal, my current machine can easily handle it and run the process without any issues; while post-wrapped with Temporal has introduced the issue of the history (multiple times asking myself why I used this tool!)</p>
<p>However, thinking on Temporal architecture with retry, state checkpointing and durability features, I am insisted to grasp and understand it better, although the concept is kinda hard for me, especially the feature of Signal, Message and Query. At the moment, I just used Signal and not the later, although the implementation was not pushed to the production as of what I intended to develop is to schedule a series of workflow that is/are depend on others, communicated through Signal.</p>
<p>The problem is, using Signal required a static workflow id so that it can fetch the workflow id if the signal is send. (I called this - <em>waiting mode to fire</em>). Unfortunately, on the current Temporal version, if you schedule the workflow, it will create a workflow id appended with the <em>timestamp</em>, which makes the workflow id string dynamic, and hardly to hard code (inaccurate when I used <code>.now()</code>) ! The issue has been arisen in the the community forum and Github issue but still not patched and solved.</p>
<p>Nevertheless, let it be, as I found a workaround by</p>
<ol>
<li><p>Ensure all workflow is trigger with endpoint. (<code>/etl_1</code> , <code>/etl_2</code>, <code>etl_n</code>…)</p>
</li>
<li><p>Create an Activity that call the endpoint. (<code>/schedule_all_endpoint</code>)</p>
</li>
<li><p>Create a workflow that call this endpoint - <code>SchedulerWorkflow</code></p>
</li>
<li><p>Create an endpoint with client to schedule this workflow.</p>
</li>
<li><p>Trigger this endpoint. Boom, scheduled.</p>
</li>
</ol>
<h1 id="heading-asynchronous">Asynchronous</h1>
<p>You need to ensure everything is async, with the respect of whom. One workflow might async to another workflow, but dependent (previous need to be completed) to another. Every function written should support async function. For example, the api request, the db query, any process related to I/O cpu bound need to be async else it will be blocked and become sync.</p>
<p>And this is also to ensure we can implement Queue-Worker process, where you polling multiple workers that waiting for task to be queue and executed once queueing, that will speed up the process for every Workflows. Just ensure everything is async, and we good to go.</p>
]]></content:encoded></item><item><title><![CDATA[Async Programming: Do Not Waste Time]]></title><description><![CDATA[In a simple words, async’s philosophy is - while waiting, do something!
Async, or asynchronous is not as an asing things in programming. However, due to no real world use case for utilization of the concept, I tend to ignore it in my codes. Then it h...]]></description><link>https://mmarsaf.xyz/async-programming-do-not-waste-time</link><guid isPermaLink="true">https://mmarsaf.xyz/async-programming-do-not-waste-time</guid><category><![CDATA[asynchronous]]></category><category><![CDATA[Python]]></category><category><![CDATA[asyncio]]></category><category><![CDATA[speed]]></category><category><![CDATA[time]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Sun, 10 Aug 2025 11:23:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/y-XZf_TNRms/upload/30d6295198a910a1f31f875e292d50e8.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In a simple words, async’s philosophy is - <em>while waiting, do something!</em></p>
<p>Async, or asynchronous is not as an <em>asing</em> things in programming. However, due to no real world use case for utilization of the concept, I tend to ignore it in my codes. Then it has became my concerns in my current working project as it required me to build a vast and robust pipeline that is operated efficiently and relatively faster.</p>
<h1 id="heading-why-use">Why Use</h1>
<ul>
<li><p>Time is money</p>
</li>
<li><p>Speed</p>
</li>
<li><p>Optimization</p>
</li>
</ul>
<h1 id="heading-when-to-use">When to Use</h1>
<ol>
<li><p>Use it whenever you have a function that took so much time, yet you want other function to run int the background or while waiting the <em>slow guy</em> to complete.</p>
</li>
<li><p>Use it when you want to increase the efficiency of the code, increase the potential and speed of the operation by not blocking other function(s).</p>
</li>
</ol>
<h1 id="heading-the-burger-analogy">The Burger Analogy</h1>
<p><img src="https://images.unsplash.com/photo-1568901346375-23c9450c58cd?fm=jpg&amp;q=60&amp;w=3000&amp;ixlib=rb-4.1.0&amp;ixid=M3wxMjA3fDB8MHxzZWFyY2h8Mnx8YnVyZ2VyfGVufDB8fDB8fHww" alt="burger with lettuce and tomatoes" /></p>
<p>Below is the approaches to complete any process or operation, or any task in life. To understand this, imagine a situation when a man need to cook a burger in a restaurant. The man need to completed 10 set of burgers by following the common cooking process.</p>
<h3 id="heading-pure-sync">Pure Sync</h3>
<ul>
<li>A man cooking a burger sequentially (single thread)</li>
</ul>
<ol>
<li><p>Man cook a patty with no timer.</p>
</li>
<li><p>Man waiting until the patty cooks and cannot do the next step until the patty is cooked. (<strong>blocking</strong>)</p>
</li>
<li><p>Once cooked, man slice the bread.</p>
</li>
<li><p>Man then frying the fries with no timer features. Man waiting until fries is completely cooked. (<strong>blocking</strong>)</p>
</li>
<li><p>Man put lettuce and mayo on the bread and stack up with the patty.</p>
</li>
<li><p>Man put fries as side dish.</p>
</li>
<li><p>Man do step 1 to 4, until it completed 10 burgers.</p>
</li>
<li><p>Man tired.</p>
</li>
</ol>
<p><em>Took so so much time. :(</em></p>
<h3 id="heading-pure-async">Pure Async</h3>
<ul>
<li>A man cooking a burger (single thread)</li>
</ul>
<ol>
<li><p>Man cook a patty.</p>
</li>
<li><p>While waiting patty to cook, man slice a bread.</p>
</li>
<li><p>Man go flip the patty and set a timer for five minutes.</p>
</li>
<li><p>While waiting patty cook, man fry fries in a fryer with timer for 3 minutes.</p>
</li>
<li><p>Man put lettuce on the bread.</p>
</li>
<li><p>While waiting the patty cook, fry timer ended. Man take the french fries and put in the plate.</p>
</li>
<li><p>Patty cooked, man put patty on the stacked bread with lettuce.</p>
</li>
</ol>
<p><em>Fast and efficient.</em></p>
<h3 id="heading-pure-async-multithreading">Pure Async + Multithreading</h3>
<ul>
<li>4 men cooking a burger (4 threads)</li>
</ul>
<ol>
<li><p>Man-A cook a patty, Man-B slice bread, Man-C frying fries, Man-D arrange the lettuce.</p>
</li>
<li><p>While patty cook, Man-B take lettuce on bread, Man-C put the fries on the plate.</p>
</li>
<li><p>Patty cook, Man B took patty and stack on bread.</p>
</li>
<li><p>Complete.</p>
</li>
</ol>
<p><em>Faster, but more complex to control more men.</em></p>
<hr />
<h1 id="heading-coding-mindset">Coding Mindset</h1>
<ol>
<li><p>Do async function for function that potentially taking too much time.</p>
</li>
<li><p>Wrap the expression(s) in a function. Atomize it.</p>
</li>
<li><p>Prefix with <code>async</code> and <code>await</code> the async-ing function.</p>
</li>
</ol>
<h1 id="heading-async-code">Async Code</h1>
<p>In Python, we will handle the async function with <code>asyncio</code> Package and it will do all the magics behind it.</p>
<h2 id="heading-basics">Basics</h2>
<h3 id="heading-terms">Terms</h3>
<ul>
<li><strong>coroutine</strong> - when it is async, the function will be call as the coroutine object or function</li>
</ul>
<h3 id="heading-task">Task</h3>
<p>Task is fancy terms for the function you want to execute. Task is optional. You can explicitly create it with with <code>asyncio.create_task()</code> or, directly run it with <code>asyncio.run()</code> or <code>asyncio.gather()</code> + <code>asyncio.run()</code> for multiple async function.</p>
<ul>
<li><p><code>asyncio.create_task()</code> — create task immediately, can run later with await if you want, independent task, cancellable</p>
</li>
<li><p><code>asyncio.gather()</code> — gather all coroutine function together, don’t want run the function later, non cancellable, return list</p>
</li>
</ul>
<h3 id="heading-non-dependent-async-function">Non-dependent async function</h3>
<ul>
<li>simple coroutine functions with <a target="_blank" href="http://asyncio.run">asyncio.run</a>() and asyncio.gather()</li>
</ul>
<pre><code class="lang-python"><span class="hljs-keyword">async</span> function():
    asyncio.sleep(<span class="hljs-number">10</span>) <span class="hljs-comment"># just to simulate a time consuming function</span>
    <span class="hljs-keyword">return</span> <span class="hljs-string">"a"</span>
<span class="hljs-keyword">async</span> function()_1:
    asyncio.sleep(<span class="hljs-number">10</span>)
    <span class="hljs-keyword">return</span> <span class="hljs-string">"b"</span>
<span class="hljs-keyword">async</span> function()_2:
    asyncio.sleep(<span class="hljs-number">10</span>)
    <span class="hljs-keyword">return</span> <span class="hljs-string">"c"</span>
<span class="hljs-keyword">async</span> function()_3:
    asyncio.sleep(<span class="hljs-number">10</span>)
    <span class="hljs-keyword">return</span> <span class="hljs-string">"b"</span>


<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span>():</span>
    <span class="hljs-comment"># singlefunction</span>
    asyncio.run(function()) 

    <span class="hljs-comment"># multiple async function</span>
    asynction.gather(function_1(), function_2(), function_3())

<span class="hljs-comment"># run the corouting function</span>
asyncio.run(main())
</code></pre>
<h3 id="heading-dependent-function">Dependent function</h3>
<ul>
<li>function_a dependent on function_b to complete first. Hence the async is contagious.</li>
</ul>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> asyncio
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">do_things</span>():</span>
    print(<span class="hljs-string">"Currently doing things..."</span>)
    asyncio.sleep(<span class="hljs-number">100</span>)  <span class="hljs-comment"># fake a function that took so much time!</span>
    <span class="hljs-keyword">return</span> <span class="hljs-string">"yes"</span>

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">process_output</span>(<span class="hljs-params">out</span>):</span>
    <span class="hljs-keyword">if</span> out == <span class="hljs-string">"yes"</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-string">"completed"</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">check_something</span>():</span>
    out = <span class="hljs-keyword">await</span> do_things()
    process = <span class="hljs-keyword">await</span> process_output(out) <span class="hljs-comment"># need to await coz do_things took time to complete</span>
    <span class="hljs-keyword">return</span> process

asyncio.run(check_somoething)
<span class="hljs-comment"># await check_something() # notebook</span>
Output:
<span class="hljs-string">"yes"</span>
</code></pre>
<h3 id="heading-off-loading-blocking-tasks">Off-loading blocking tasks</h3>
<ul>
<li><p>There is sync function that will blocked the operation (legacy, or unsupported)</p>
<p>  <a target="_blank" href="http://asyncio.to"><code>asyncio.to</code></a><code>_thread()</code> | <a target="_blank" href="http://asyncio.loop.run"><code>asyncio.loop.run</code></a><code>_in_executor()</code></p>
</li>
</ul>
<pre><code class="lang-python">function():<span class="hljs-keyword">return</span> <span class="hljs-string">"a"</span> <span class="hljs-comment"># sync, legacy or unsupported for async</span>
<span class="hljs-keyword">async</span> function()_1:<span class="hljs-keyword">return</span> <span class="hljs-string">"b"</span>
<span class="hljs-keyword">async</span> function()_2:<span class="hljs-keyword">return</span> <span class="hljs-string">"c"</span>
<span class="hljs-keyword">async</span> function()_3:<span class="hljs-keyword">return</span> <span class="hljs-string">"b"</span>


<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span>():</span>
    <span class="hljs-comment"># singlefunction</span>
    asyncio.run(asyncio.to_thread(function())) <span class="hljs-comment"># or loop.run_in_executor()</span>

    <span class="hljs-comment"># multiple async function</span>
    asynction.gather(function_1(), function_2(), function_3())

<span class="hljs-comment"># run the corouting function</span>
asyncio.run(main())
</code></pre>
<h1 id="heading-potential-bugs">Potential Bugs</h1>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Issue</td><td>Potential Solution</td></tr>
</thead>
<tbody>
<tr>
<td><code>function</code> or expression is not awaited</td><td>check whether <code>function</code> has <code>async</code> or notwrap the expression as <code>async function</code> so that it can be awaited, although it does not consume time to return output</td></tr>
<tr>
<td>object <code>coroutine</code> is not iterable (list), hashable (dict)</td><td>check whether the function call which output is passed to variable is awaited or not</td></tr>
<tr>
<td><code>async def load_something(): return "complete" output = load_something() ❌ output = await load_something() ✅</code> <a target="_blank" href="http://asyncio.run"><code>asyncio.run</code></a><code>(load_somoething) ✅</code></td></tr>
</tbody>
</table>
</div><h1 id="heading-if-pure-async-approach-is-possible-why-there-is-blocking-function">If pure async approach is possible, why there is blocking function?</h1>
<ol>
<li><p>Legacy sync function.</p>
</li>
<li><p>Unsupported async feature in package.</p>
</li>
<li><p>Some function easily handled as sync.</p>
</li>
</ol>
<h1 id="heading-overwhelming-how-to-start">Overwhelming. How to start?</h1>
<ol>
<li><p>For time consuming function, make it async. Use <code>async</code> in front of <code>def</code>.</p>
</li>
<li><p>Calling async function require you to use <code>await</code>. Hence include it if it is called.</p>
</li>
<li><p>Start with <code>asyncio.run()</code> for easy execution of async function. Then can try <code>asyncio.gather([list of async function])</code> + <code>asyncio.run()</code> for multiple async functions.</p>
</li>
<li><p>Once comfortable, implement intermediate async feature, such async <em>time</em> base, <em>prioritization</em> base, and <em>queue</em>.</p>
</li>
</ol>
<h1 id="heading-conclusion">Conclusion</h1>
<p>I hope this will help the beginners or any level of programmer to understand the async concept. If you have any commenta, please leave the comment below. I appreciate it. Thank you.</p>
]]></content:encoded></item><item><title><![CDATA[First hello world ETL DE project]]></title><description><![CDATA[I just watched Zach video (the famous data engineer guy that has worked for Airbnb and Facebook) and want to build something with it. I am lacked with data engineer experience so I decided to build something while learning. Previously, I just felt th...]]></description><link>https://mmarsaf.xyz/first-hello-world-etl-de-project</link><guid isPermaLink="true">https://mmarsaf.xyz/first-hello-world-etl-de-project</guid><category><![CDATA[dataengineering]]></category><category><![CDATA[dbt]]></category><category><![CDATA[Prefect]]></category><category><![CDATA[Docker]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Fri, 18 Apr 2025 01:09:41 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/X-NAMq6uP3Q/upload/464717db4a19900fea0923390f63dfff.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I just watched Zach video (the famous data engineer guy that has worked for Airbnb and Facebook) and want to build something with it. I am lacked with data engineer experience so I decided to build something while learning. Previously, I just felt that data engineering is not that interesting. However, after watched his series, my perspective changed and I realized that maybe I just not digging enough in this topic because it is interesting. Something systematically sophisticated always dragged my attention and now I just almost complete the project.</p>
<p>I started to find any free API that provide a real time info. Talk about real time, Zach is true about how do you define the real time. Stakeholders almost knew nothing about it. Real time, near real time, batching, micro-batching will always be assumed the same. For them as long as it ‘quick’, then it can be real time. Why the understanding real time is important? Technically because of the complexity. The more it near to real time, the higher the complexity. I can’t say more about this, because the API that I just used is not actually a real-time API as it is updated every 30 seconds, however it has shown its complexity compare to my daily job that only require to fetch the data from database as per requirement.</p>
<p>I started with playing around with the <a target="_blank" href="https://developer.data.gov.my/realtime-api/gtfs-realtime">API</a>. Simply using Python you can fetch the information of the feeder bus in KL with certain information return such as the trip time, latitude, longitude, bearing, and speed. Then I decided to build an internal monitoring dashboard that can</p>
<ol>
<li><p>Monitor the behavior of the driver - safe, cautious and dangerous driving behavior</p>
</li>
<li><p>Monitor the condition of the bus - bus that has mileage more than 10,000 km that require service</p>
</li>
<li><p>Monitor the current location of the bus - observe the density bus movement</p>
</li>
</ol>
<h2 id="heading-first-draft">First draft</h2>
<p>To build this, I started by draw the first draft of data orchestration infrastructure.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739283605397/8e74159c-705e-4f35-b290-06124a5bf17d.jpeg" alt class="image--center mx-auto" /></p>
<p>(yea it is so bad, but I will provide the final draft at the end of this article by using excalidraw)</p>
<p>The first plan is to use Airflow, Dbt, Postgres, and Apache Superset, by containerize them. No reason of why I used Postgres as it is the common usage and previously used in my project. Airflow, Dbt and Apache Superset is new to me, but it is learnable.</p>
<h2 id="heading-database-and-dbt">Database and Dbt</h2>
<p>I started by setup the database first, then playing with SQL on Jupyter Notebook. The first problem that I faced is to ensure the data integrity of data insertion in the database. This is because I used change the json return from the request into dataframe before doing the insertion using Pandas <code>.to_sql()</code>. This method be able to change the schema of the database and <strong>would not</strong> be able to ensure the data type as of it just insert any kind of data format (including if it has different column name) into database. So I used the native SQL instead of using Pandas method.</p>
<p>Then I artificially normalized the data by adding bus and driver table. The bus is coming from the original data but the driver is generated. Then I write the script for recurring and cumulative table which will update daily for the monitoring. All of this SQL query is written following the Dbt methodology, where I can modularize the script, reuse and recall whenever I want. Personally, this is a good way for having version control especially for a potential scalable project that require many changes in the future. Other than modularization, Dbt has testing feature where I can ensure the data type and column name to be matched what is expected (good because I don’t need another external packages like Pydantic or Pytest itself).</p>
<h2 id="heading-orchestration">Orchestration</h2>
<p>My first plan on implementing data orchestration is using Airflow (of course after I watched Zach). The tools provided a complete data orchestration tool, however the size of the image is too heavy; at least for my local machine to endure. This is actually because it has a lot of battery include features which is in my case is overkill (what I want is just automation). Then, I found Prefect. Based on Reddit forum and tested myself, Prefect image is much lighter and this will allow me to develop the pipeline locally. The syntax is also much simpler, which require task and flow; just need to understand on how to test your flow locally as the docs is quite deviated for beginners use.</p>
<h2 id="heading-visualization">Visualization</h2>
<p>As you can see on the paper, it stated Apcahe Superset. I also changed my plan from using this, as of it is quite unstable in terms of container building where it has error of npm and build-essential. All the docker-compose provided surprisingly produced error (I found the workaround but that is after I implement the other alternative) and that makes me change to <a target="_blank" href="https://www.metabase.com/start/oss/">Metabase</a>. Also, much simpler, stable and easy to use. Just that it has only daily database sync, which is not what I want on the first plan where I want the visualization to update</p>
<h2 id="heading-progress">Progress</h2>
<p>The following is my final architecture for the project</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1749198181191/ad68e8d3-fe6c-4c7c-ad85-4a3e7bf9c4ef.png" alt class="image--center mx-auto" /></p>
<p>Instead of using MLFlow, I changed it Dagster with a smaller size image so I can run smoothly (RAM poor lol). I also use Metabase instead of Apache Superset, due to some image bug happened in Superset. The weakness of Metabase is it cannot established a near real time visualization as the quickest is one day.</p>
<p>While doing this project, I have discussed with my colleague where I got several input on the improvement. First and foremost, the API itself can’t be a real time due to its HTTP request feature. Instead, I need a web-hook API or implement PubSub method.</p>
<h1 id="heading-current">Current</h1>
<p>The project still not achieve my ultimate goals, but I learned a lot about Data Engineering with such a small project. Shout out to Zach the YT Data Engineer for the knowledge sharing (though he already hide the series) and myself.</p>
]]></content:encoded></item><item><title><![CDATA[Learn from the Yeetcode (p.1)]]></title><description><![CDATA[Meet again in the episode of I re-learn something that I don’t applied in my daily work task. Yeah, just want to learn it again and I hope this time I get the most of the understanding. I will push myself for this three months to re-learn DSA, before...]]></description><link>https://mmarsaf.xyz/learn-from-the-yeetcode-p1</link><guid isPermaLink="true">https://mmarsaf.xyz/learn-from-the-yeetcode-p1</guid><category><![CDATA[leetcode]]></category><category><![CDATA[linked list]]></category><category><![CDATA[DSA]]></category><category><![CDATA[datastructure]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Thu, 17 Apr 2025 16:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/ipuiM-36tAg/upload/c0bdf5238c88c55e78e8535e614a0873.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Meet again in the episode of I re-learn something that I don’t applied in my daily work task. Yeah, just want to learn it again and I hope this time I get the most of the understanding. I will push myself for this three months to re-learn DSA, before I get into the new job. Just wanna straight away write what I just realize during my attempt to solve the easy (said by Leetcode) problem which is <em>Add Two Numbers</em>.</p>
<h1 id="heading-linked-list">Linked List</h1>
<h2 id="heading-fundamental">Fundamental</h2>
<p>This problem require an understanding to the concept of Linked List. To be honest, I have watched some videos and read some articles on the internet but still failed to grasp the main concept of it. I guess I need to face the problem first then my brain can work 100% efficiently.</p>
<p>So, what I realized, the first thing you need to put in your mind while learning about Linked List is</p>
<blockquote>
<p>To remove the concept of common list that I understand, which a list that can be access by indices (index).</p>
</blockquote>
<p>Why? Because I realized the blockade that prevent me to understand the concept of linked list. The main concept of Linked List is the</p>
<ol>
<li><p>Node</p>
</li>
<li><p>Pointer</p>
</li>
</ol>
<p>Only this, then the manipulation of memory allocation. Reading the theory personally make me feels dizzy, so I straight away going to the code. The problem is, how do they thought on the way to create the Linked List is in this way?</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ListNode</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, val=<span class="hljs-number">0</span>, next=None</span>):</span>
            self.val = val
            self.next = next
</code></pre>
<p>Remember that, if you instantiate an object from a class, it will allocate the object (which variable also one of it) into the memory.</p>
<p>Hence, to utilize this feature, they write a single Node as an <em>object</em> in the <em>variable</em>.</p>
<p>From the code you can see there is 2 object attributes (<code>val</code> and <code>next</code>) which represents</p>
<ol>
<li><p><code>val</code> — value that we want to store in the <em>node</em></p>
</li>
<li><p><code>next</code> — an attribute that we use to manipulate the state of pointer</p>
</li>
</ol>
<p>By using this Class, we can create a Linked List and store the value in it. Let’s do some simple proves. To create a linked list, we use this function;</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">list_to_linked_list</span>(<span class="hljs-params">lst</span>):</span>
    dummy = ListNode() <span class="hljs-comment"># first node</span>
    temp = dummy

    <span class="hljs-comment"># for every, initially create new node, then create new node</span>
    <span class="hljs-comment"># after it</span>
    <span class="hljs-keyword">for</span> val <span class="hljs-keyword">in</span> lst:
        temp.next = ListNode(val)
        temp = temp.next
    <span class="hljs-keyword">return</span> dummy.next <span class="hljs-comment"># in the end it point to the head of the ll</span>
</code></pre>
<p>Pseudocode:</p>
<ol>
<li><p>We first instantiate the first node with <code>dummy</code></p>
</li>
<li><p>Then we copy the object to <code>temp</code></p>
</li>
<li><p>For every integer in the list, I will assign the <code>.next</code> value from <code>temp</code> a node with the integer value.</p>
</li>
<li><p>Then I will overwrite the <code>temp</code> with <code>temp.next</code> for the next iteration.</p>
</li>
<li><p>The next iteration, we actually create a node for <code>temp.next.next</code>.</p>
</li>
<li><p>Until the iteration end.</p>
</li>
<li><p>Then we point the pointer to the first node, which is <code>dummy</code></p>
</li>
</ol>
<p>Example:</p>
<pre><code class="lang-python">l1 = list_to_linked_list([<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>])

a = l1.next
b = a.next

print(l1.val, a.val, b.val)

<span class="hljs-comment">#### OUTPUT ######</span>
(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>)
</code></pre>
<p>This is actually similar to</p>
<pre><code class="lang-python">print(l1.val, l1.next.val, l1.next.next.val)

<span class="hljs-comment">#### OUTPUT ######</span>
(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>)
</code></pre>
<p>To visualize this,</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744942140354/120b5aa9-f255-4c7e-8d4c-80fede118946.png" alt class="image--center mx-auto" /></p>
<p>Okay that solved the Linked List part, not the problem yet. Honestly, I did not solved the problem, but I learned from the solution.</p>
<h2 id="heading-solution">Solution</h2>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Solution</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">addTwoNumbers</span>(<span class="hljs-params">self, l1: Optional[ListNode], l2: Optional[ListNode]</span>) -&gt; Optional[ListNode]:</span>
        <span class="hljs-comment"># Dummy node to start the new list</span>
        dummy = ListNode()
        temp = dummy
        carry = <span class="hljs-number">0</span>

        <span class="hljs-comment"># Loop until both lists are processed or there is a carry</span>
        <span class="hljs-keyword">while</span> l1 <span class="hljs-keyword">or</span> l2 <span class="hljs-keyword">or</span> carry:
            <span class="hljs-comment"># Get values from the current nodes or use 0 if the node is None</span>
            val1 = l1.val <span class="hljs-keyword">if</span> l1 <span class="hljs-keyword">else</span> <span class="hljs-number">0</span>
            val2 = l2.val <span class="hljs-keyword">if</span> l2 <span class="hljs-keyword">else</span> <span class="hljs-number">0</span>

            <span class="hljs-comment"># Calculate the sum and the new carry</span>
            <span class="hljs-comment"># carry - imagine standard written method,</span>
            <span class="hljs-comment"># where if the the summation is more than 10,</span>
            <span class="hljs-comment"># it will carry the 1 value to the next side opearation</span>
            total = val1 + val2 + carry
            carry = total // <span class="hljs-number">10</span>
            value = total % <span class="hljs-number">10</span>

            <span class="hljs-comment"># Create a new node with the current value and move the pointer</span>
            temp.next = ListNode(value)
            temp = temp.next

            <span class="hljs-comment"># Move to the next nodes in the input lists if they exist</span>
            <span class="hljs-keyword">if</span> l1:
                l1 = l1.next
            <span class="hljs-keyword">if</span> l2:
                l2 = l2.next

        <span class="hljs-comment"># Return the head of the new linked list</span>
        <span class="hljs-keyword">return</span> dummy.next
</code></pre>
<p>So, based on the code, we can see a similar code structure like the way we create the linked list above.</p>
<p>Common parts;</p>
<ol>
<li><p><code>ListNode()</code></p>
</li>
<li><p><code>dummy</code></p>
</li>
<li><p><code>temp</code></p>
</li>
<li><p><code>carry</code></p>
</li>
</ol>
<p>The extras is before we create the Node and store the value, we do something with the linked list. In this part, we need to imitate the elementary school standard operation procedure in addition, where if the operation of integer is more than 10, then we need to bring the 1 to the next position.</p>
<p>In Leetcode, they use the word <strong><em>traversing</em></strong> which simply means</p>
<blockquote>
<p>Iterate until there is no value, or simply said , while True</p>
</blockquote>
<ol>
<li><p>So, traversing into first and second linked list, we take the value and total it up. We check if there is a <em>carry</em> (more than 1 and take the value 1 to the next) and bring keep for the next iteration.</p>
</li>
<li><p>We then keep the total addition operation by doing modulo and keep it in a new node, and keep it in <code>temp</code>.</p>
</li>
<li><p>The current <code>temp</code> already has value, hence we <strong><em>overwrite</em></strong> it and create a new one.</p>
</li>
<li><p>Since <code>l1</code> and <code>l2</code> is already a Linked list, we can move to the next node for the next operation.</p>
</li>
<li><p>Finally, after the linked list creation complete, we point and skipped the dummy node.</p>
</li>
</ol>
<h1 id="heading-recap">Recap</h1>
<ol>
<li><p>To solve the linked list is to have the linked list mindset in mind (not the common Python list that I learned in the fundamental part).</p>
</li>
<li><p>Input linked list, output linked list.</p>
</li>
<li><p>Basic structure of linked list to have <em>value</em> and <em>pointer</em>.</p>
</li>
<li><p>Manipulate the pointer following to what the problem or stuffs you need to solve.</p>
</li>
<li><p>Common manipulation use <code>dummy</code> and <code>temp</code> in order to achieve the objective.</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Why Kaggle is So OP]]></title><description><![CDATA[Personally, Kaggle is sufficient enough for someone for data science starter, or even to delve deeper in data science field. This article was written after having a conversation with a Kaggle Master, listening to some Kaggle Grandmaster Podcast, and ...]]></description><link>https://mmarsaf.xyz/why-kaggle-is-so-op</link><guid isPermaLink="true">https://mmarsaf.xyz/why-kaggle-is-so-op</guid><category><![CDATA[kaggle]]></category><category><![CDATA[Python]]></category><category><![CDATA[Machine Learning]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Sun, 15 Sep 2024 04:38:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/qMKtGoO7V9A/upload/5fa3962b5a44f3759d61ecf6e44ba34f.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Personally, Kaggle is sufficient enough for someone for data science starter, or even to delve deeper in data science field. This article was written after having a conversation with a Kaggle Master, listening to some Kaggle Grandmaster Podcast, and try by myself on Kaggle. What I can conclude are;</p>
<ol>
<li><p><strong>Complete all the Kaggle mini-course</strong>. This mini-course is provided on Learn tab on Kaggle. Most of ml tutorial taught about the text book of DS, but this mini-course taught the <em>technique</em> which is what makes it priceless. Technique is what I feel I had lost comparing with all the expertise, especially on the feature creation and validation methodology where it is really useful for most of the cases.</p>
</li>
<li><p><strong>Read the Kaggle forum</strong>. This is the gold mine treasure where a pool of Kaggle master and grandmaster having fantastic discussion together. Hate to say that we are not getting some of the knowledge in article such Medium, because they just talked casually here. Other than question answering, the Kaggle discussion also shared their solution which is another precious diamond, with the title, <em>1st place solution</em>.</p>
</li>
<li><p><strong>Join competition.</strong> By joining competition, we will understand how Kaggle works. There is two type of competition which is code competition and submission competition. When I first knew about code competition, where we need to <em>turn off the internet</em>, it feels really weird. But that how the competition worked.</p>
</li>
<li><p><strong>Listen to the Kaggle master and grandmaster talk/podcast</strong>. My friend who are Kaggle master always did this to learn something new and implementing in his code. Last weekend, I listened to Giba, the NVIDIA Kaggle Grandmaster. As a novice, he taught a lot of very useful information, tips and technique that can be applied within the data science project or competition.</p>
</li>
</ol>
<p>There might be more. I will update the article soon or later. (Last update: 15-9-2024)</p>
]]></content:encoded></item><item><title><![CDATA[How to start Data Science]]></title><description><![CDATA[Start with learning Python. If you have previous experience on coding, that's good. Knowledge transfer. If not, just learn it. Learn from the basic until function definition is enough. Want to go extra? Learn until OOP.

Write the code on notebook. S...]]></description><link>https://mmarsaf.xyz/how-to-start-data-science</link><guid isPermaLink="true">https://mmarsaf.xyz/how-to-start-data-science</guid><category><![CDATA[Data Science]]></category><category><![CDATA[learning]]></category><category><![CDATA[malaysia]]></category><category><![CDATA[Python]]></category><category><![CDATA[pandas]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Sun, 04 Aug 2024 08:18:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/_1LvAexVWa8/upload/3f94ccd61d00fa2ac90c2108dba34a79.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<ol>
<li><p>Start with learning Python. If you have previous experience on coding, that's good. Knowledge transfer. If not, just learn it. Learn from the basic until function definition is enough. Want to go extra? Learn until OOP.</p>
</li>
<li><p>Write the code on notebook. Start with Jupyter Notebook. You can setup with Anaconda (get full package of everything), or small setup with Miniconda. Easy to use. Learn how to run python script after that.</p>
</li>
<li><p>Learn to use Pandas. Learn Pandas so that you can do all data manipulation in the notebook. So you don't need to open your Excel to do something. When I said manipulation, there are tons of manipulation stuff you can do.</p>
</li>
<li><p>Learn about modelling. Start with Scikit-learn. The package also has data manipulation feature too. From sklearn, learn about encoding, modelling (regression, classification), cross validation, kfold and so on. Here is the starting point of learning about machine learning.</p>
<p> Add your tool by learn deep learning too. Use Pytorch framework.</p>
</li>
<li><p>Learn Matplotlib and Seaborn. You can see and analyze better with visual.</p>
</li>
<li><p>Learn about hyperparameter tuning library such Optuna. Once you got the base model, automate the process of getting the best model with Optuna. Make coffee, sit down, train the model and let Optuna find the best model. Save and track the model with MLFlow. Best combo ever.</p>
</li>
<li><p>Learn about Shapley. It is a model interpretability method. If your boss or lecturer asking you why the model decided to choose the class, you can explain it smoothly.</p>
</li>
<li><p>Change your Googling style. Use Google dorking. Start seeking information from Kaggle. Here is the place where all grandmaster and people who crazy on machine learning gathered. Use <code>inurl:kaggle how to ...</code> while Googling.</p>
</li>
<li><p>Utilize Kaggle. Join Kaggle competition. Click the Competition, go to Community to start. Kaggle also provide free courses by chapter that we can enroll (located on Learn tab).</p>
</li>
<li><p>Keep learning.</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[How TDD Teach us to Become a Firm Programmer]]></title><description><![CDATA[I started my journey of coding by delving into data science, specifically using Python, Pandas and Jupyter-Notebook as my first environment. In this setup, while wrangling the dataset and manipulate it, a mind paradigm that I has developed was the it...]]></description><link>https://mmarsaf.xyz/how-tdd-teach-us-to-become-a-firm-programmer</link><guid isPermaLink="true">https://mmarsaf.xyz/how-tdd-teach-us-to-become-a-firm-programmer</guid><category><![CDATA[TDD (Test-driven development)]]></category><category><![CDATA[Data Science]]></category><category><![CDATA[Python]]></category><category><![CDATA[development]]></category><category><![CDATA[Mindset]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Mon, 08 Jul 2024 02:42:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/v2ogJh_Pbxg/upload/f515a4d4354145dbe6a0d1531facdd37.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I started my journey of coding by delving into data science, specifically using Python, Pandas and Jupyter-Notebook as my first environment. In this setup, while wrangling the dataset and manipulate it, a mind paradigm that I has developed was the iteration running of code and see the output. If the output is not meet my expectation, then I will change it until it followed what I want. This common practice has molded me personally to become a person who always <em>think later, run first</em> which is not wrong in a certain situation, but could ruin you in backend development.</p>
<p>Until I learned about test code, during the time I have been allocated a task which required myself to create an API, was my first encountered of learning the test code and <a target="_blank" href="https://www.browserstack.com/guide/what-is-test-driven-development">Test Driven Development</a> (TDD).</p>
<p>At that time, my current mind paradigm was challenged by a different idea, by needing to be firm first, then execute. At first, it is such irritating whenever I saw all the errors, due to the code test failure.</p>
<p>However, after a month development and slowly used with it, my way of thiunking has gradually changed, since during the development process, I will put my objective first, before start building the code. It make me a an objective-focus person in order to met the requirement and the test code as the benchmark of the truthfulness.</p>
<p>Not only that, sometimes if I saw that my <em>objective</em> (or test) has sligthly wrong, I need to decide whether to alter the test methodology (reducing the test strictness) or by doing the last choice - moving the goalpost. The later choice is not good practice, but in some situation, it is necessary. Imagine that you want to test the strength of a car. You have decide the shoot the car with M16. Logically it is not the best approach, instead the best way is by crashing car to the wall (according the real world case scenario). Sometimes, the test is wrong, but most of the time your code does not met what you really want.</p>
<p>While, this might be not useful during modelling, due to the nature of experimenting and validating in order to approve or reject the null hypothesis, but at least the process of building pipeline (feature engineering, cleaning, imputation, etc.) would be robust and not a <em>guessing game</em>.</p>
]]></content:encoded></item><item><title><![CDATA[Some Rust Learning Experience (pt. 1)]]></title><description><![CDATA[Starting with Python as the first programming language is good. The language is easy to use, focus on the main fundamental of programming, abstracting certain part of computer science components as they handled it on background; which make the beginn...]]></description><link>https://mmarsaf.xyz/some-rust-learning-experience-pt-1</link><guid isPermaLink="true">https://mmarsaf.xyz/some-rust-learning-experience-pt-1</guid><category><![CDATA[Rust]]></category><category><![CDATA[Python]]></category><category><![CDATA[learning]]></category><category><![CDATA[struct]]></category><category><![CDATA[ownership]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Sat, 29 Jun 2024 08:59:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/TcN2ucbpBQg/upload/c0a0df19bb938f093a6f9dbdc6eba7fd.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Starting with Python as the first programming language is good. The language is easy to use, focus on the main fundamental of programming, abstracting certain part of computer science components as they handled it on background; which make the beginners thought that coding is really easy.</p>
<p>However, due to this setting, Python learning process has removed certain important concept that is quite useful for beginners that I found out in - Rust.</p>
<p>My objective of learning Rust is actually simple. To learn a static typing programming language and taste the memory safety conceptual in coding (which actually I need to learn by enrolling computer science course). I am not sure that I might build something with Rust in the future or what people said <em>just to feel</em>, but I hope I can bring some paradigm that I learn in Rust during writing with Python in my daily task.</p>
<p>The first thing that I found giving some <em>culture shock</em> is the static typing itself. In Python, sometimes we never bother the parameter type hint and return type; due the nature of non-enforcement type hinting in the code. Type hinting is just to help the programmer in developing the project as it will pop-up associated method for the particular type of value in the VSCode. However in Rust, type hint, or what they called <em>types</em> are enforced and also being used by the compiler to do something. For example for casting (or converting) data type in Rust, the type that we put will be used by the compiler so it can know what kind of data type that we want to convert to.</p>
<p>Not only that, I observed that, by enforcing types, the code is much robust, readable and easy for hand-over process in work wise. Just to say that if you felt overwhelmed seeing this kind of heavy type include code, it just a skill issue - no, just kidding, it just you don't know like me and let's learn together. Having types make the code easier to read by other programmers, as they know what kind of types is the parameter, what kind of types return by the function. Simple types that does not existed in Python which is <code>u32</code> or unsigned 32-bytes integer, which referred to <em>no sign (negative) integer</em> which means, the number will always positive. It is small but somehow cool.</p>
<p>Rust compiler also doing an amazing job of checking the consistency of types and return a helpful stack-trace message for the user so we can check the error part. Another cool stuff of Rust, its compiler stack trace.</p>
<p>Besides, the mutability and ownership concept. In Python, at least in my experience of using Notebook, there is always a situation of what I called as <em>state-conflict</em> where I have no idea what value the variable is actually hold on too and conflicting with another code block; due to running multiple code block in no order, and changing the variable value on another code block, while sharing the same state. With mutability by default in Rust, all variable is immutable unless the <code>mut</code> syntax is implemented. There is no such thing in Python of having bother about mutability where ironically some of the compound data type itself can be manipulated even though it has been stated as immutable (tuple in Python) where there is work around to make it mutable. As per stated by default variable is immutable in Rust, we need to explicitly include <code>mut</code> if we want to enforce the mutability and also consider whether it is <em>growable</em> or not. For example, <code>str</code> is a string that is not growable (cannot add new char in it), while <code>String</code> is growable. Which bring to the next concept which is ownership.</p>
<p>Ownership stated that, a variable always an owner, every value has a single owner, owner will dropped once it is out of scope. A simple objective of implementing ownership is to somehow to avoid "copy"-ing value in order to utilize the memory, by deallocate it once it is out of scope. To be honest, it took me a times to understand this concept, because it is newly introduced to me (which no one care passing value and about memory allocation in Python) and it's quite daunting whenever it comes to <code>struct</code> and implementing the borrowing, as it is proned to error.</p>
<p>And because of the static typing paradigm (where it feels like living in a prison where everything is being observed), your "<em>freedom</em> of not including the type" is also required, within the Generic chapter. What I meant here is, there is a point where we don't want to explicitly put concrete types (<code>i32</code>, <code>String</code>) but we just want to make it <em>general</em>. Hence, to make it general, we need to explicitly tell Rust that we want to do this by using <code>T</code> type. It really feels like in concentration camps, but I kind like about this verbosity.</p>
<p>Rust also has OOP such Python that used <code>struct</code> and their own abstract base classes (ABC) that worked as contract by using <code>impl</code>. To compare both of this language almost has the same feature, however the thing that I loved in Rust is in the module part. In this part, we can explicitly declare the module to become public and private to be access by user by using the syntax <code>pub</code>. I know there is such thing in Python, where it used dunder method (underscore) to make it private and protected, but it seems kind implicit comparing to putting the syntax within the code explicitly. We can exactly see which part of the module, struct, method that can be access and not, making it much easier (I think) in building an the crate and import wise.(I am avoid on talking about Python unresolved parents/relative module import issue that has various kind of answers in Stack Overflow discussion).</p>
<p>If you are a C or Cpp user, I am apologize because all of this things has existed in your language. But I found that Rust has cool documentation and fantastic lesson written so I took the opportunity to learn from it. So far, this is what I felt while learning Rust. It somehow gave me some another point of view of coding that I might bring in my Python style (or if I do build with Rust later on). I still learning (if you found any of the facts are wrong or inaccurate, please do comment so I can correct it), and currently on chapter 10.</p>
<p>I might update this articles later or create new pages for the next updates.</p>
]]></content:encoded></item><item><title><![CDATA[Just start]]></title><description><![CDATA[Sometimes I just felt silly trapped in the hole of where to start and I don't want others suffer the same. Life is too short and all you need is to learn from a good teacher and resource.

If you want to learn Python, learn from Corey Chafer or Caleb...]]></description><link>https://mmarsaf.xyz/just-start</link><guid isPermaLink="true">https://mmarsaf.xyz/just-start</guid><category><![CDATA[learning]]></category><category><![CDATA[sharing]]></category><category><![CDATA[resources]]></category><category><![CDATA[Python]]></category><category><![CDATA[pytorch]]></category><category><![CDATA[TensorFlow]]></category><category><![CDATA[SQL]]></category><category><![CDATA[FastAPI]]></category><category><![CDATA[Linux]]></category><category><![CDATA[huggingface]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Thu, 30 May 2024 09:22:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/-iKd4K6CGB4/upload/6d3cf8c612d84fd22b2a1ecb054ce087.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Sometimes I just felt silly trapped in the hole of <em>where to start</em> and I don't want others suffer the same. Life is too short and all you need is to learn from a good teacher and resource.</p>
<ul>
<li><p>If you want to learn Python, learn from <a target="_blank" href="https://www.youtube.com/playlist?list=PL-osiE80TeTskrapNbzXhwoFUiLCjGgY7">Corey Chafer</a> or <a target="_blank" href="https://www.youtube.com/playlist?list=PL_c9BZzLwBRLrHc6MntpdrNPKoC2tJr0z">Caleb Curry</a>.</p>
</li>
<li><p>If you want to learn about Scikit-learn, here is the <a target="_blank" href="https://www.youtube.com/playlist?list=PL5-da3qGB5ID7YYAqireYEew2mWVvgmj6">series</a> from DataSchool.</p>
</li>
<li><p>If you want to learn Deep Learning, learn from Jared Howard (fast-ai) <a target="_blank" href="https://www.youtube.com/playlist?list=PLfYUBJiXbdtS2UQRzyrxmyVHoGW0gmLSM">Series 1</a>, and <a target="_blank" href="https://www.youtube.com/playlist?list=PLfYUBJiXbdtTttBGq-u2zeY1OTjs5e-Ia">Series 2</a></p>
</li>
<li><p>If you want to start a journey with <strong>Pytorch</strong>, learn from this <a target="_blank" href="https://www.youtube.com/playlist?list=PLCC34OHNcOtpcgR9LEYSdi9r7XIbpkpK1">series</a>. Good kickstart before rowing the boat yourself.</p>
</li>
<li><p>If you want to start a journey with <strong>Tensorflow</strong>, learn from this <a target="_blank" href="https://www.udemy.com/course/tensorflow-developer-certificate-machine-learning-zero-to-mastery/?couponCode=24T3MT53024">course</a>. Worth every pennies, rich resources.</p>
</li>
<li><p>If you want to start learning <strong>Huggingface</strong>, with all the big giga chad pretrained model, code along with this Transformers <a target="_blank" href="https://huggingface.co/docs/transformers/en/index">docs</a> towards the end.</p>
</li>
<li><p>If you want to learn <a target="_blank" href="https://www.udemy.com/course/tensorflow-developer-certificate-machine-learning-zero-to-mastery/?couponCode=24T3MT53024"><strong>FastAPI</strong></a>, learn directly (do hands-on, don't copy) from the <a target="_blank" href="https://fastapi.tiangolo.com/learn/">docs</a> written by Tiangolo.</p>
</li>
<li><p>If you want to learn about Linux (though it <em>just to feel</em>), setup your laptop with WSL by following this <a target="_blank" href="https://www.youtube.com/playlist?list=PLhfrWIlLOoKNMHhB39bh3XBpoLxV3f0V9">series</a> (pre-requisite before installing Docker).</p>
</li>
<li><p>If you want to learn Docker, learn from this <a target="_blank" href="https://docker-curriculum.com/">page</a>. And checkout this useful <a target="_blank" href="https://dockerlabs.collabnix.com/docker/cheatsheet/">cheatsheet</a> too.</p>
</li>
<li><p>If you want to learn about SQL, but lazy to setup the workbench and server, just use <a target="_blank" href="https://duckdb.org/docs/api/python/overview.html">DuckDb with Python</a>.</p>
</li>
<li><p>Or can just visit my <a target="_blank" href="https://github.com/Ammar-Azman/Data-Science-Materials">repo</a> where I dumped all useful resources.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[If you feel overwhelmed]]></title><description><![CDATA[This is a reminder for myself (and for everyone if it is useful) whenever I feel overwhelmed; when I started learning new language, when I started learning new framework, when I look at the 1000 lines of legacy code, when I feel everyone running so f...]]></description><link>https://mmarsaf.xyz/if-you-feel-overwhelmed</link><guid isPermaLink="true">https://mmarsaf.xyz/if-you-feel-overwhelmed</guid><category><![CDATA[Programming Blogs]]></category><category><![CDATA[reminder]]></category><category><![CDATA[self-help]]></category><category><![CDATA[self-improvement ]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Tue, 28 May 2024 12:09:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/K0A-EbR6Rus/upload/8766477757161de28de2106c22bc0e8d.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is a reminder for myself (and for everyone if it is useful) whenever I feel overwhelmed; when I started learning new language, when I started learning new framework, when I look at the 1000 lines of legacy code, when I feel everyone running so fast, when they will always new tech dropped everyday, and the list goes on;</p>
<ul>
<li><p>Every programmer started on the line 0.</p>
</li>
<li><p>Every programmer started with "hello world".</p>
</li>
<li><p>Every programmer started with a single variable, then function, then OOP (if they want to).</p>
</li>
<li><p>Every programmer faced the bugs.</p>
</li>
<li><p>Every programmer started with knew nothing.</p>
</li>
<li><p>Every programmer did a silly mistake.</p>
</li>
<li><p>Every programmer felt the impostor in them, while suffer from Dunning-Kruger effect.</p>
</li>
<li><p>Every programmer has a different pace and capability.</p>
</li>
<li><p>Every programmer started with a bad practice.</p>
</li>
<li><p>Every programmer learn new things everyday.</p>
</li>
</ul>
<p>What make them difference, they just persistent.</p>
]]></content:encoded></item><item><title><![CDATA[Ajar Diri Anda Pengaturcaraan selama 10 Tahun]]></title><description><![CDATA[Artikel asal: https://norvig.com/21-days.html
Penterjemah: Ammar Azman
Pembaca pruf: Ilham Nordin

Kenapa semua orang kelam-kabut?
Menapak ke mana-mana toko buku, anda akan lihat buku bertajuk How to Teach Yourself Java in 24 hours bersama lambakan b...]]></description><link>https://mmarsaf.xyz/ajar-diri-anda-pengaturcaraan-selama-10-tahun</link><guid isPermaLink="true">https://mmarsaf.xyz/ajar-diri-anda-pengaturcaraan-selama-10-tahun</guid><category><![CDATA[Programming Blogs]]></category><category><![CDATA[learning]]></category><category><![CDATA[coding]]></category><category><![CDATA[programming]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Sat, 03 Feb 2024 05:08:13 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/FZ0qzjVF_-c/upload/a91f21233468a793b8317c2dadaa63c1.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p><strong>Artikel asal: https://norvig.com/21-days.html</strong></p>
<p>Penterjemah: Ammar Azman</p>
<p>Pembaca pruf: Ilham Nordin</p>
</blockquote>
<h1 id="heading-kenapa-semua-orang-kelam-kabut"><strong>Kenapa semua orang kelam-kabut?</strong></h1>
<p>Menapak ke mana-mana toko buku, anda akan lihat buku bertajuk <em>How to Teach Yourself Java in 24 hours</em> bersama lambakan buku yang lain yang menawarkan pembelajaran dalam beberapa hari atau jam untuk C, SQL, Ruby, Algoritma, dan lain-lain. Carian canggih Amazon untuk [title: teach, yourself, hours, since: 2000] telah menjumpai sebanyak 512 buku. Dalam carta sepuluh teratas, sembilan daripadanya adalah buku-buku pengaturcaraan (sebuah lagi tentang pembukuan). Hasil carian yang sama juga terhasil dengan menukar kata kunci "teach yourself" kepada "learn" atau "hours" kepada "days".</p>
<p>Tuntasnya adalah, sama ada semua orang sedang kelam-kabut untuk belajar tentang pengaturcaraan, atau ilmu pengaturcaraan itu kadang-kadang kelihatan terlalu mudah untuk dituntut berbanding hal-hal yang lain. Felleisen <em>et al.</em> bersetuju dengan tren ini dalam buku mereka <em>How To Design Programs</em>, apabila mereka mengatakan, "Pengaturcaraan yang teruk itu mudah. Si bebal mampu mempelajarinya dalam masa 21 hari, walaupun mereka itu bodoh." Dalam komik Abstruse Goose juga mengatakan sedemikian.</p>
<p>Mari kita cerakin apa maksud yang boleh difahami melalui tajuk buku seperti <em>Teach Yourself C++ in 24 hours</em>:</p>
<ul>
<li><p><strong>Teach Yourself</strong>: Dalam masa 24 jam, anda tidak punya masa yang cukup untuk menulis beberapa program yang berkesan dan belajar sesuatu daripada kejayaan dan kegagalan anda melaluinya. Anda tidak punya masa untuk bekerja dengan pengatur cara yang berpengalaman, dan memahami bagaimana hidup dalam suasana dikelilingi C++. Pendek kata, anda tak akan belajar banyak dalam masa yang singkat. Maka, buku ini hanya mampu berbicara tentang perkara-perkara asas, bukannya sesuatu yang mendalam pemahamannya. Sepertimana yang dikatakan Alexander Pope, pelajaran yang singkat itu mengundang nahas.</p>
</li>
<li><p><strong>C++</strong> : Dalam masa 24 jam, anda mungkin mampu mempelajari beberapa sintaks C++ (jika anda telah pun mengetahui bahasa lain), namun anda tidak mampu untuk belajar bagaimana cara untuk menggunakan bahasa ini. Pendek kata, jika anda, misalnya, seorang pengatur cara <em>Basic</em>, anda boleh mempelajari untuk menulis program dalam langgam <em>Basic</em> menggunakan sintaks C++, namun anda tidak akan mampu belajar apakah kelebihan (dan kekurangan) C++ itu. Jadi, apa gunanya? Alan Perlis pernah menukilkan, "Sebuah bahasa yang tidak memberi impak langsung kepada cara kamu berfikir dalam pengaturcaraan, tidak berbaloi pun untuk kamu tahu." Mungkin anda kena mempelajari secubit C++ (ataupun sesuatu seperti Javascript atau Processing), kerana anda perlu meggunakan alat yang sudah tersedia untuk menyempurnakan tugas tertentu. Tetapi sayangnya, anda tidak belajar untuk mengatur cara, hanya belajar untuk menyelesaikan tugasan.</p>
</li>
<li><p><strong>in 24 Hours</strong>: Malang sekali, ini tidak memadai; sebagaimana yang diterangkan dalam bahagian seterusnya.</p>
</li>
</ul>
<h1 id="heading-ajar-diri-anda-pengaturcaraan-selama-sepuluh-tahun">Ajar Diri Anda Pengaturcaraan Selama Sepuluh Tahun</h1>
<p>Penyelidik (Bloom (1985), Bryan &amp; Harter (1998), Hayes (1989), Simmon &amp; Chase (1973)) telah membuktikan bahawa ia akan mengambil masa selama 10 tahun untuk membina seorang pakar dalam apa jua bidang, termasuklah bermain catur, komposisi muzik, operasi telegraf, mengecat, bermain piano, berenang, bermain tenis, dan penyelidikan dalam neuropsikologi, dan topologi. Kuncinya adalah, latihan secara berterusan yang bermatlamat: bukan hanya mengulang dan mengulang, namun mencabar diri dengan tugasan di luar nalar kemampuan, mencuba, menganalisa prestasi semasa dan selepas melakukannya, dan membetulkan kesilapan. Kemudian ulang. Dan ulang lagi. Sepertinya tiada jalan singkat: walaupun Mozart sendiri, seorang prodigi muzik seawal usia 4 tahun, memakan masa 13 tahun sebelum menghasilkan muzik berkelas dunia. Dalam genre lain, kumpulan Beatles seperti muncul secara tiba-tiba dengan sejumlah lagu bercarta #1, dan membuat kemunculan dalam rancangan Ed Sullivan pada tahun 1964. Namun sebelum itu, mereka telah membuat persembahan di kelab-kelab kecil di Liverpool dan Hamburg sejak 1957, dan meskipun mereka mendapat perhatian ramai sejak awal lagi, kejayaan besar mereka yang pertama, <em>Sgt. Peppers</em>, telah diluncurkan pada 1967.</p>
<p>Malcolm Gladwell telah mempopularkan idea ini, walaupun dia memberi penekanan pada 10,000 jam, bukan 10 tahun. Henri Cartier-Bresson (1980-2004) mempunyai metrik berbeza: "10,000 gambar pertama kamu adalah yang terburuk." (Beliau tidak menyangka bahawa dengan kamera digital, sesetengah orang mampu mencapai jumlah gambar tersebut dalam masa seminggu.) Kepakaran yang sebenar mungkin mengambil masa seumur hidup: Samuel Johnson (1709-1784) berkata "Kecemerlangan dalam mana-mana bidang hanya boleh dicapai dengan hasil kerja seumur hidup; ia tidak akan dapat dibeli pada harga yang lebih murah." Chaucer (1340-1400) pula mengeluh, "Hidup terlalu pendek, menjadi pakar mengambil waktu untuk dipelajari." Hippocrates (c. 400 sebelum masihi) dikenali dengan "ars longa, vita brevis" yang merupakan cebisan daripada madah "Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile", yang mana dalam Bahasa Melayu diterjemah sebagai, "Hidup pendek, belajar banyak, peluang sebentar, eksperimen berliku, penilaian sukar." Sudah tentu, tiada nombor tunggal yang boleh menjadi jawapan akhir: tidak munasabah untuk diandaikan bahawa semua kemahiran (misalnya, pengaturcaraan, bermain catur, bermain dam, bermain muzik) mampu digapai dengan jumlah waktu yang sama untuk menjadi mahir, atau diandaikan bahawa semua orang akan mengambil waktu yang sama untuk menggapainya. Sepertimana yang dikatakan Prof. K, Anders Ericsson, "Dalam kebanyakan domain, luar biasa benar, betapa banyak masa yang diperlukan untuk mencapai prestasi pencapaian tertinggi, walaupun oleh individu yang paling berbakat. Nombor 10,000 jam hanya memberi satu anggaran bahawa kita sedang berbicara tentang 10 hingga 20 jam seminggu, buat bertahun-tahun lamanya; tahun-tahun yang dikatakan perlu dicapai, meskipun mereka yang semula jadinya, paling berbakat."</p>
<h1 id="heading-jadi-anda-mahu-jadi-pengatur-cara">Jadi Anda Mahu Jadi Pengatur Cara</h1>
<p>Berikut adalah resepi saya dalam kejayaan pengaturcaraan:</p>
<ul>
<li><p>Harus ada <strong>minat</strong> dalam pengaturcaraan, juga buatlah sesetengahnya kerana rasa seronok. Pastikan ia kekal dan cukup seronok agar anda rela hati untuk berkorban selama 10 tahun/10,000 jam.</p>
</li>
<li><p><strong>Mengatur cara</strong>. Cara pembelajaran yang paling baik adalah belajar sambil buat. Secara teknikalnya, "Prestasi aras maksimum setiap individu dalam setiap domain tidak akan diperoleh secara automatik hasil daripada pengalaman yang panjang, namun aras prestasi boleh ditingkatkan, walaupun individu tersebut berpengalaman tinggi, hasil usaha yang bermatlamat untuk menambah baik." (p.366) dan "pembelajaran paling efektif memerlukan tugasan dengan definisi yang jelas bersama kesukaran yang bersesuaian untuk individu tertentu, maklum balas berinformasi, dan peluang untuk mengulangi dan membetulkan ralat." (p. 20-21). Buku <em>Cognition in Practice: Mind Mathematics, and Culture in Everyday Life</em> merupakan rujukan yang menarik untuk sudut pandang ini.</p>
</li>
<li><p><strong>Bercakap</strong> dengan pengatur cara lain; baca program orang lain. Ini lebih mustahak daripada membaca mana-mana buku atau kursus latihan.</p>
</li>
<li><p>Jika anda mahu, luangkan 4 tahun di <strong>kolej</strong> (atau lebih, di sebuah universiti). Ini akan memberikan anda akses kepada sesetengah pekerjaan yang memerlukan tauliah, dan ini akan memberikan anda pemahaman yang mendalam dalam bidang ini, namun, jika anda tidak menikmati sekolah, anda boleh (dengan sedikit dedikasi) mendapatkan pengalaman yang sama, secara sendiri atau dengan cara bekerja. Dalam apa jua keadaan, membaca buku tidak akan pernah memadai. "Pembelajaran sains komputer tidak akan menjadikan sesiapa pakar pengatur cara sebagaimana mempelajari berus dan pigmen tidak akan menjadikan seseorang pakar pelukis." kata Eric Raymond, penulis <em>The New Hacker's Dictionary</em>. Salah seorang pengatur cara terbaik yang pernah bekerja dengan saya hanya mempunyai lulusan sekolah menengah; dia telah menghasilkan pelbagai perisian yang baik, mempunyai kumpulan akhbarnya tersendiri, dan cukup berharta dengan stok saham untuk membeli kelab malamnya sendiri.</p>
</li>
<li><p>Ceburkan diri dalam <strong>projek</strong> dengan pengatur cara lain. Jadi pengatur cara terbaik dalam sesetengah projek, jadi yang paling teruk dalam sesetengah yang lain. Bila anda merupakan yang terbaik, anda mampu menguji kemampuan anda untuk mengetuai projek tersebut, dan menginspirasi orang lain dengan visi anda. Bila anda yang paling teruk, anda akan belajar apa yang dilakukan oleh mereka yang mahir, dan anda akan belajar apa yang mereka tidak suka lakukan (kerana mereka menyuruh anda lakukan perkara itu untuk mereka!)</p>
</li>
<li><p>Ceburkan diri dengan <strong>projek pasca</strong> pengatur cara lain. Fahamkan program yang ditulis oleh orang lain. Lihat bagaimana untuk memahami dan membaikinya apabila pengatur cara asal tidak berada di sekeliling. Fikir tentang bagaimana untuk menggubah program untuk menjadikan ia lebih mudah untuk mereka yang akan mengekalkannya selepas anda.</p>
</li>
<li><p>Belajar sekurang-kurangnya enam <strong>bahasa pengaturcaraan</strong>. Masukkan bahasa yang mementingkan pengabstrakan (seperti Java atau C++), satu yang mementingkan pengabstrakan fungsi (seperti Lisp, ML, atau Haskell), satu yang menyokong pengabstrakan sintaktik (seperti Lisp), satu yang menyokong spesifikasi deklaratif (seperti Prolog atau templat C++), dan satu yang mementingkan paralelisme (seperti Clojure atau Go).</p>
</li>
<li><p>Ingat bahawa adanya "<strong>komputer</strong>" dalam "sains komputer". Ketahui masa yang diambil untuk komputer anda menjalankan arahan, mendapatkan perkataan daripada memori (dengan dan tanpa <em>cache miss</em>), membaca perkataan berturutan daripada cakera, dan mencari lokasi baru pada cakera. (Jawapan <a target="_blank" href="https://docs.google.com/document/d/1OzzfMEuKEehSwfe8ZNde75nSLx039z8DY4ycikPTwLQ/edit#heading=h.jxn0j2lz3h49"><strong>disini</strong></a>)</p>
</li>
<li><p>Libatkan diri dengan usaha pempiawaian bahasa. Sama ada dengan jawatankuasa ANSI C++, atau menetapkan cara pengekodan anda mempunyai 2 atau 4 aras ruang perenggan. Dengan apa cara pun, anda akan belajar mengenai kegemaran orang lain dalam bahasa, sedalam mana perasaan mereka tentangnya, dan mungkin juga sedikit tentang sebab-sebab mereka rasa sedemikian.</p>
</li>
<li><p>Mempunyai firasat yang baik untuk keluar daripada usaha pempiawaian bahasa secepat mungkin.</p>
</li>
<li><p>Dengan segala yang di atas, sejauh mana anda mampu belajar hanya melalui buku menjadi sebuah keraguan. Sebelum kelahiran cahaya mata pertama saya, saya telah membaca kesemua buku <em>How To</em>, dan masih rasa seperti seorang pemula yang dangkal. 30 bulan kemudian, sementara menanti kelahiran cahaya mata kedua, adakah saya kembali kepada buku-buku tersebut sebagai ulang kaji? Tidak. Malah, saya bergantung pada pengalaman peribadi, yang terbukti lebih berguna dan lebih meyakinkan saya berbanding beribu muka surat tulisan pakar-pakar.</p>
</li>
</ul>
<p>Fred Brooks, dalam bukunya <em>No Silver Bullet</em> mengenal pasti rancangan 3 bahagian untuk mencari pereka perisian terbaik:</p>
<ol>
<li><p>Mengenal pasti pereka terbaik secara sistematik, seawal yang mampu.</p>
</li>
<li><p>Meletakkan seorang mentor karier yang bertanggungjawab membangunkan prospek dan menyimpan fail karier secara teliti.</p>
</li>
<li><p>Menyediakan peluang bagi pereka yang sedang bertumbuh untuk berinteraksi dan merangsang satu sama lain.</p>
</li>
</ol>
<p>Ini dengan andaian bahawa sesetengah orang telah pun mempunyai kualiti yang diperlukan untuk menjadi pereka yang baik, yang tinggal hanyalah memujuk mereka untuk kerja bersama. Alan Perlis mengatakannya dengan lebih ringkas, "Semua orang boleh diajar untuk mengukir: Michelangelo sepatutnya diajar bagaimana untuk tidak mengukir. Begitu jugalah dengan pengatur cara yang hebat." Perlis mengatakan yang kecemerlangan itu hadir daripada kualti dalaman yang terpancar dengan latihan. Namun, daripada manakah kualiti itu datang? Adakah secara semula jadi? Atau mereka membangunkannya dengan kerajinan? Sepertimana kata Auguste Gusteau (chef fiksyen dalam <em>Ratatouille</em>), "Semua orang boleh memasak, tetapi hanya yang berani akan cemerlang." Saya memandangnya lebih kepada kerelaan hati untuk menumpukan sebahagian besar kehidupan seseorang kepada latihan yang bermatlamat. Mungkin, <em>berani</em> adalah cara untuk mengatakannya dengan ringkas. Atau, seperti kata pengkritik Gusteau, Anton Ego: "Tidak semua orang boleh menjadi artis yang hebat, namun artis yang hebat boleh hadir daripada mana-mana."</p>
<p>Maka, pergilah beli buku Java/Ruby/Javascript/PHP itu; anda mungkin akan beroleh sedikit manfaat daripadanya. Namun, anda tidak akan mengubah hidup anda, atau keseluruhan kemahiran sebenar anda sebagai pengatur cara dalam masa 24 jam atau 21 hari. Bagaimana kalau anda bekerja keras dengan tekal untuk menambah baik selama 24 bulan? Mungkin lepas itu ada progres yang boleh dilihat.</p>
<hr />
<h1 id="heading-apendiks-pemilihan-bahasa">Apendiks: Pemilihan Bahasa</h1>
<p>Beberapa orang telah bertanya apakah bahasa pengaturcaraan yang mereka harus belajar dahulu. Tiada jawapan yang tetap, namun timbangkan hujah-hujah berikut:</p>
<ul>
<li><p><strong>Gunakan rakan anda</strong>. Apabila ditanya, “Apa sistem pengoperasian yang sepatutnya saya guna, Windows, Unix, atau Mac?” jawapan saya biasanya, “Guna apa sahaja yang rakan anda guna.” Kelebihan yang anda akan dapat dengan pembelajaran daripada rakan-rakan, akan membuatkan perbezaan intrinsik antara sistem operasi atau antara bahasa pengaturcaraan menjadi kecil. Juga pertimbangkan rakan-rakan anda di masa depan: komuniti pengatur cara yang anda akan turut bersama jika anda masih mengatur cara. Adakah anda memilih bahasa yang mempunyai komuniti yang berkembang, atau yang kecil dan sedang nazak? Adakah terdapat buku, laman sesawang, dan forum dalam talian untuk mendapatkan jawapan? Adakah anda suka orang-orang di dalam forum-forum tersebut?</p>
</li>
<li><p><strong>Ringkaskan</strong>. Bahasa pengaturcaraan seperti C++ dan Java direka untuk pembangunan professional oleh pengatur cara berpengalaman dalam sebuah kumpulan besar di mana mereka cakna mengenai kecekapan “run-time” dalam kod mereka. Hasilnya, bahasa-bahasa ini mempunyai bahagian-bahagian rumit yang direka khas untuk keadaan tertentu. Anda mahu mempelajari pengaturcaraan. Anda tidak perlukan kerumitan itu. Anda mahukan bahasa yang rekaannya mudah untuk dipelajari dan diingati oleh setiap pengatur cara baharu.</p>
</li>
<li><p><strong>Bermain</strong>. Cara mana yang anda mahu untuk pembelajaran piano, secara normal dan interaktif, di mana anda mendengar setiap not sejurus selepas anda menekan kekunci; atau mod "kumpulan", di mana anda hanya akan mendengar not selepas keseluruhan lagu tamat? Jelaslah, mod interaktif membuatkan pembelajaran lebih mudah untuk piano, dan juga pengaturcaraan. Pilih bahasa dengan mod interaktif dan gunakannya</p>
</li>
</ul>
<p>Berdasarkan kriteria ini, cadangan saya untuk bahasa pengaturcaraan pertama seharusnya Python atau Scheme. Pilihan lain adalah Javascript, bukan sebab ia direka dengan baik dan sempurna untuk pemula, tetapi kerana terdapat banyak tutorial dalam talian, seperti tutorial Khan Academy. Namun, situasi anda mungkin berbeza, dan terdapat pilihan lain yang lebih baik. Jika umur anda adalah nombor tunggal, anda mungkin lebih suka Alice atau Squeak atau Blockly (pelajar lama juga mungkin gemarkan yang ini). Paling utama adalah anda pilih, dan mula.</p>
<hr />
<h1 id="heading-apendiks-buku-dan-sumber-sumber-lain">Apendiks: Buku dan Sumber-sumber Lain</h1>
<p>Beberapa orang telah bertanya daripada buku dan laman sesawang apa yang mereka harus belajar. Saya ulang, “buku sahaja tidak mencukupi”, tapi saya akan mencadangkan berikut:</p>
<ul>
<li><p>Skema: <em>Structure and Interpretation of Computer Programs</em> (Abelson &amp; Sussman) berkemungkinan merupakan pengenalan terbaik untuk sains komputer, dan ia mengajarkan pengaturcaraan sebagai satu cara memahami sains komputer. Anda boleh lihat syarahan dalam talian tentang buku ini, dan juga teks lengkapnya. Buku ini mencabar dan akan menyingkirkan beberapa orang yang mungkin akan berjaya dengan pendekatan berbeza.</p>
</li>
<li><p>Skema: <em>How to Design Programs</em> (Felleisen et al.) adalah salah satu buku terbaik berkaitan perekaan atur cara dengan cara yang berfungsi dan anggun.</p>
</li>
<li><p>Python: <em>Python Programming: An Intro to CS</em> (Zelle) adalah bagus untuk pengenalan menggunakan Python.</p>
</li>
<li><p>Python: Beberapa tutorial dalam talian berada di <a target="_blank" href="http://python.org/"><strong>Python.org</strong></a>.</p>
</li>
<li><p>Oz: <em>Concepts, Techniques, and Models of Computer Programming</em> (Van Roy &amp; Haridi) dilihat oleh beberapa orang hari ini sebagai pengganti Abelson &amp; Sussman. Ia sebuah perjalanan menyusuri idea-idea besar pengaturcaraan, melingkupi julat yang lebih luas berbanding Abelson &amp; Sussman tetapi lebih mudah untuk dibaca dan diikuti. Ia menggunakan satu bahasa, Oz, yang tidak digunakan secara meluas namun menyediakan asas untuk mempelajari bahasa-bahasa lain.</p>
</li>
</ul>
<hr />
<h1 id="heading-nota">Nota</h1>
<p>T.Capey menyatakan yang muka Complete Problem Solver di Amazon sekarang mempunyai buku "<em>Teach Yourself Bengali in 21 days</em>" dan "<em>Teach Yourself Grammar and Style</em>" di bawah bahagian “pelanggan yang membeli barangan, juga membeli barangan ini”. Saya merasakan sebagian besar orang yang melihat buku itu datang daripada muka surat ini. Terima kasih Ross Cohen untuk bantuan bagi Hippocrates.</p>
]]></content:encoded></item><item><title><![CDATA[Implementasi REST API dengan FastAPI, Lambda dan API Gateway]]></title><description><![CDATA[Pendahuluan
Artikel ini ditulis dalam Bahasa Melayu bagi memudahkan pemahaman dalam masa yang sama mengekalkan beberapa perkataan Inggeris yang digunakan secara global.
Penulis telah terpanggil untuk menulis artikel ini dalam proses membuat REST API ...]]></description><link>https://mmarsaf.xyz/implementasi-rest-api-dengan-fastapi-lambda-dan-api-gateway</link><guid isPermaLink="true">https://mmarsaf.xyz/implementasi-rest-api-dengan-fastapi-lambda-dan-api-gateway</guid><category><![CDATA[mangum]]></category><category><![CDATA[AWS]]></category><category><![CDATA[aws lambda]]></category><category><![CDATA[Python]]></category><category><![CDATA[FastAPI]]></category><category><![CDATA[API Gateway]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Sat, 16 Dec 2023 11:53:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/dCgbRAQmTQA/upload/851d39a8248175a9d9b7b9e38308a52b.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-pendahuluan">Pendahuluan</h1>
<p>Artikel ini ditulis dalam Bahasa Melayu bagi memudahkan pemahaman dalam masa yang sama mengekalkan beberapa perkataan Inggeris yang digunakan secara global.</p>
<p>Penulis telah terpanggil untuk menulis artikel ini dalam proses membuat REST API <em>deployment</em> menggunakan servis AWS beberapa minggu lepas disebabkan hampir tiada atau kurang lengkap artikel yang menerangkan bagaimana cara untuk membuat <em>deployment</em> menggunakan trio - FastAPI, Lambda beserta API Gateway. Segala komen dan kritikan amatlah dihargai daripada para pembaca.</p>
<p>Dalam tutorial ini, penulis hanya memfokuskan langkah-langkah sahaja tanpa pergi terlalu <em>detail</em> kepada servis berkenaan.</p>
<h1 id="heading-metodologi">Metodologi</h1>
<h2 id="heading-fastapi">FastAPI</h2>
<h3 id="heading-langkah-langkah">Langkah-langkah</h3>
<ol>
<li><p>Cipta <em>virtual environment</em>, aktifkan kemudian <em>install</em> pakej <a target="_blank" href="https://fastapi.tiangolo.com/tutorial/#install-fastapi">FastAPI</a> dan <a target="_blank" href="https://mangum.io/">Mangum</a>.</p>
</li>
<li><p>Tulis kod menggunakan pakej FastAPI. Dibawah penulis sertakan contoh kod asas yang akan digunakan.</p>
</li>
</ol>
<pre><code class="lang-python"><span class="hljs-comment"># main.py</span>
<span class="hljs-keyword">import</span> os
<span class="hljs-keyword">from</span> fastapi <span class="hljs-keyword">import</span> FastAPI
<span class="hljs-keyword">from</span> mangum <span class="hljs-keyword">import</span> Mangum

stage = os.environ.get(<span class="hljs-string">"STAGE"</span>, <span class="hljs-literal">None</span>)
app = FastAPI(title=<span class="hljs-string">"My Cat API"</span>, 
                root_path=<span class="hljs-string">"/{stage}/"</span> <span class="hljs-keyword">if</span> stage <span class="hljs-keyword">else</span> <span class="hljs-string">"/"</span>),
                openapi_url = <span class="hljs-string">"/pet/openapi.json"</span>, 
                docs_url = <span class="hljs-string">"/pet/docs"</span>
    )

router = APIRouter(prefix=<span class="hljs-string">"/pet"</span>)

<span class="hljs-meta">@router.get("/")</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_root</span>():</span>
    <span class="hljs-keyword">return</span> {
        <span class="hljs-string">"author"</span>: <span class="hljs-string">"Ammar Azman"</span>, 
        <span class="hljs-string">"status"</span>: <span class="hljs-string">"succeed!"</span>
    }

<span class="hljs-meta">@router.get("/meow")</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">hungry</span>():</span>
    <span class="hljs-keyword">return</span> {
        <span class="hljs-string">"sound"</span>:<span class="hljs-string">"meow!"</span>
    }


app.include_router(router)

lambda_handler = Mangum(app)
</code></pre>
<h3 id="heading-keterangan-kod">Keterangan kod</h3>
<ul>
<li><p><em>Environment</em> diperlukan kerana dalam API Gateway terdapat bahagian Stage (yang wajib di-<em>setup</em>!) yang akan menjadikan <em>path</em> API kita mempunyai prefix <code>/dev</code> (berfungsi sebagai proxy). Kod di lokal tetap akan berfungsi (kerana tiada <code>.env</code>) dengan menggunakan logik diatas.</p>
</li>
<li><p>Prefix untuk setiap path ditambah menggunakan class <code>APIRouter</code>, oleh kerana dalam konfigurasi API Gateway, kita perlu cipta Resource (nama perlu sama, iaitu <code>/pet</code>) supaya API Gateway dapat <em>hit</em> path tersebut. Disebabkan itu juga, string untuk <code>openapi_url</code> dan <code>docs_url</code> juga perlu diubahsuai dengan menambah <code>/pet</code> dihadapan bagi membolehkan kita melihat dokumentasi API.</p>
</li>
<li><p>Mangum digunakan supaya kesemua API boleh di<em>wrap</em> menjadi <em>lambda function</em>, yang juga akan dipanggil semasa konfigurasi AWS Lambda.</p>
</li>
<li><p>Jalankan <em>command</em> dibawah dan uji API anda -</p>
</li>
</ul>
<pre><code class="lang-bash">uvicorn main:app --reload
</code></pre>
<ul>
<li>Uji kesemua API dengan membuat <em>request</em>. Jika okay, sambung ke proses seterusnya.</li>
</ul>
<h2 id="heading-aws-lambda">AWS Lambda</h2>
<blockquote>
<p>Nota: Sebelum anda <em>setup</em> Lambda, penulis menganggap bahawa anda telah mendapatkan segala <em>permission</em> untuk mencipta fungsi Lambda di AWS Lambda dan API Gateway.</p>
</blockquote>
<h3 id="heading-langkah-langkah-1">Langkah-langkah</h3>
<ol>
<li><p>Cipta fungsi Lambda baharu. Katakan nama fungsi adalah, <code>my_cat_lambda</code>.</p>
<p> <img src="https://lh7-us.googleusercontent.com/m5u14rijIG5Dr-lqcVRN4JZNSDnU2hB635F_dffgCGSej3liFpWbQVkSXIt46R64siw-hYBsi_3SE8DhwQ0FdJfAuzDYS9XCtrsGr2PkIkHCiT4QdgKc1pPGuV2Ls_hLxrT43a6sO6yvy0FV2qEEMPw" alt /></p>
</li>
<li><p>Pilih <em>runtime</em> versi Python yang merujuk kepada versi Python yang anda gunakan. (wajib sama!)</p>
</li>
<li><p>Setelah selesai, pergi kepada <strong>Configuration tab</strong> &gt;&gt; <strong>Edit</strong>.</p>
</li>
<li><p>Tambah <strong>Key</strong> - "STAGE" dan <strong>Value</strong> - "dev" dalam <strong>Environment Variable</strong>.</p>
</li>
<li><p>Kemudian, pada <strong><em>Code tab</em></strong>, ubah <em>handler</em> kepada <strong>app.main.lambda_handler</strong>.</p>
</li>
<li><p>Selesai ubah, muat naik fail zip yang mempunyai kod dan semua pakej ke S3, dan <em>pass</em> URL object tersebut. (pastikan kod berada dalam fail - bererti dalam format modul. Dalam tutorial ini, kod berada dalam direktori <code>/app</code>)</p>
</li>
<li><p>Tekan pautan yang diberikan Lambda.</p>
</li>
<li><p>Pastikan untuk tambah <code>/pet</code> diakhir URL (disebabkn <em>prefix</em> dalam router).</p>
</li>
<li><p>Anda akan lihat output dibawah pada skrin</p>
<pre><code class="lang-json"> {
         <span class="hljs-attr">"author"</span>: <span class="hljs-string">"Ammar Azman"</span>, 
         <span class="hljs-attr">"status"</span>: <span class="hljs-string">"succeed!"</span>
     }
</code></pre>
</li>
<li><p>Tambah lagi <code>/docs</code> pada hujung URL untuk melihat API docs. Pautan tersebut akan <strong>gagal</strong>. Akan tetapi, ini telah dijangka disebabkan terdapat "dev" dalam <em>environment.</em></p>
</li>
</ol>
<blockquote>
<p>Nota: Anda boleh <em>automate</em> proses (CI/CD) muat naik setiap kali mengemaskini kod baru dengan menggunakan <em>Git Action.</em></p>
</blockquote>
<h2 id="heading-api-gateway">API Gateway</h2>
<h3 id="heading-langkah-langkah-2">Langkah-langkah</h3>
<ol>
<li><p>Pada muka AWS Lambda, tekan <strong>Add trigger</strong>.</p>
</li>
<li><p>Pilih <strong>API Gateway</strong> dan <em>new api</em>.</p>
</li>
<li><p>Pilih <strong>REST API</strong>.</p>
</li>
<li><p>Tekan <em>Add</em>.</p>
</li>
<li><p>Pada <em>search bar</em>, cari servis <strong>API Gateway</strong> dan klik.</p>
</li>
<li><p>Cari nama fungsi Lambda anda (<code>my_cat_lambda</code>) dan klik. Anda akan dibawa ke muka dimana terdapat API Gateway untuk fungsi Lambda anda.</p>
</li>
<li><p>Pada <strong>Resource tab</strong>, klik <strong>Create Resource</strong>.</p>
<p> <img src="https://lh7-us.googleusercontent.com/hYk8ovrImOJvROJzf4_gJ6widabz3WlYoLiZhDFcX1j78UzhM8PqLC5m_PBpYE4baOOtZPhE-1CNnaFvQAeTy6sX7gitK6-aUKCxb3Rm19y5xzLPBD3QZWdaPZ_BBVm2UXfxOqdB7HFdDLGsy7qewYE" alt /></p>
</li>
<li><p>Setkan <em>Resource path</em> kepada <code>/</code> dan <em>Resource name</em> kepada nama prefix dalam kod (<code>pet</code>). Klik tanda pada <em>CORS</em> juga. Kemudian klik <strong>Create resource</strong>.</p>
</li>
<li><p>Langkah 8 akan diulang semula dengan <em>Resource path</em> kepada <code>/pet</code> dan <em>Resource name</em> kepada <code>{proxy+}</code>.</p>
</li>
<li><p>Setelah selesai, cipta Method untuk <code>/pet</code> dan <code>{proxy+}</code> dengan method <code>ANY</code>.</p>
</li>
<li><p>Kemudian, klik <strong>Deploy API</strong> dan pilih stage <code>dev</code> jika sudah dicipta pada <em>Stage</em>, atau jika belum, cipta satu <em>Stage</em> bernama <code>dev</code>.</p>
</li>
<li><p>Klik <strong>Deploy API</strong>.</p>
</li>
<li><p>Pergi semula kepada muka <strong>AWS Lambda</strong> anda, dan klik <strong>Configuration</strong> &gt;&gt; <strong>Trigger</strong>.</p>
</li>
<li><p>Klik URL yang diberikan API Gateway dan boleh cuba <em>request</em>.</p>
</li>
<li><p>Jika berjaya, tahniah, anda telah berjaya <em>deploy</em> API anda!</p>
</li>
</ol>
<h1 id="heading-konklusi">Konklusi</h1>
<p>Langkah diatas mungkin akan <em>obsolete</em> pada masa akan datang. Namun penulis berharap tutorial ini dapat memudahkan anda yang merancang untuk <em>deploy</em> API anda menggunakan servis AWS.</p>
<p>Sebarang komen penambah-baikan amatlah dialukan. Jika tutorial ini membantu, kongsikan pada rakan-rakan anda. Sampai jumpa lagi.</p>
]]></content:encoded></item><item><title><![CDATA[5 Cara Fikir Pengaturcara]]></title><description><![CDATA[Berikut merupakan beberapa cara fikir seorang pengaturcara yang baik; berdasarkan pengalaman, pembacaan dan sumber-sumber yang saya dapatkan yang mungkin berguna untuk kita praktikkan. Saya sertakan beberapa sumber yang anda boleh dapatkan dengan leb...]]></description><link>https://mmarsaf.xyz/5-cara-fikir-pengaturcara</link><guid isPermaLink="true">https://mmarsaf.xyz/5-cara-fikir-pengaturcara</guid><category><![CDATA[programmer]]></category><category><![CDATA[Mindset]]></category><category><![CDATA[Developer]]></category><category><![CDATA[Python]]></category><category><![CDATA[Thinking]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Sun, 26 Nov 2023 03:22:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/2RRq1BHPq4E/upload/9ea869d0e0e69bec93532a737df46765.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Berikut merupakan beberapa cara fikir seorang pengaturcara yang baik; berdasarkan pengalaman, pembacaan dan sumber-sumber yang saya dapatkan yang mungkin berguna untuk kita praktikkan. Saya sertakan beberapa sumber yang anda boleh dapatkan dengan lebih mendalam di bahagian akhir artikel.</p>
<h2 id="heading-mentaliti-progressive-overload-mula-daripada-kecil-dan-kiss">Mentaliti <em>Progressive Overload</em>, Mula daripada kecil, dan KISS</h2>
<p>Konsep ini saya ambil daripada konsep asal mengangkat beban di gimnasium, iaitu pendekatan <em>progressive overload</em>. Konsep <em>progressive overload</em> adalah dimana seseorang itu bermula mengangkat beban yang ringan, seterusnya beban ditambah dan ditambah yang akan melatih dan meningkatkan kekuatan dan daya tahan otot.</p>
<p>Konsep ini boleh diaplikasikan kepada seorang pengaturcara dalam fasa pembangunan kod. Hatta, dalam proses pembelajaran pun, kita semua bermula dengan "Hello World" dan bukan Object Oriented Programming! Kita semua bermula dengan asas, kemudian secara kumulatif kesukaran itu ditingkatkan dan ditingkatkan. Gunakan pendekatan Keep It Simple Stupid (KISS) sebelum menggubah kod kepada bentuk yang lebih sofistikated.</p>
<p>Mulakan dengan langkah kecil.</p>
<h2 id="heading-memecahkan-masalah-kepada-blok-kecil">Memecahkan Masalah kepada Blok Kecil</h2>
<p>80% kerja seorang pengaturcara adalah menyelesaikan masalah. Masalah boleh terjadi akibat daripada struktur kod, konsep fundamental, nyahpepijat dan lain-lain lagi. Dalam hal ini, ia tertakluk bagaimana seorang pengaturcara menghadapi masalah. Dengan cara yang betul, masalah boleh diselesaikan, walaupun mungkin bukan dalam jangka masa yang pantas sekalipun.</p>
<p>Kita boleh menyelesaikan masalah dengan cara memecahkannya kepada blok-blok yang lebih kecil. Umumnya, apabila kita menghadapi masalah, kita akan cenderung untuk berfikir lebih kehadapan dengan persoalan <em>what if</em> atau "Macam mana kalau...". Namun, praktis ini kurang baik kerana membuatkan kita menjadi seorang yang lewah fikir (over thinking) yang mana akhirnya tidak menyelesaikan masalah yang dihadapi.</p>
<p>Dengan memecahkan masalah menjadi lebih kecil, kita akan cuba mendalami setiap komponen masalah dengan lebih teliti dan sistematik. Teliti dengan makna kata, masalah mungkin berpunca daripada perkara fundamental seperti tidak membaca dokumentasi, tersilap pada konsep asas, atau perkara remeh yang kita tidak perasan. Sistematik pula adalah kita dapat mengesan satu persatu punca permasalahan tersebut dan merekod status masalah supaya tidak berlaku pengulangan masalah akibat daripada pendekatan yang tidak teratur dalam menyelesaikan masalah.</p>
<p>Penulis mencadangkan pembaca untuk cuba menggunakan Obsidian ataupun Notion untuk mengaplikasikan teknik ini.</p>
<h2 id="heading-mencari-kebenaran-tunggal-dan-mengesahkan-andaian">Mencari Kebenaran Tunggal dan Mengesahkan Andaian</h2>
<p>Salah satu proses pembelajaran adalah apabila kita yakin dengan kebenaran sesebuah fakta tersebut melalui bukti dan timbang tara dalam berfikir. Perkara ini normal, namun adakalanya sikap "yakin" ini terbawa-bawa kepada seorang pengaturcara apabila menghadapi pepijat dalam kod ataupun pandangan berbeza yang datang di kemudian hari. Ini tidak akan berlaku jika kita berada dalam skeptik yang terkawal dan tidak mudah-mudah menjadikan ia sebagai sebuah perkara tuntas.</p>
<p>Kita boleh skeptik dengan 2 cara iaitu dengan mengesahkan pengangan kita melalui bukti daripada sumber terpercaya yang menjadi kebenaran tunggal (iaitu dokumentasi) ataupun dengan cara mencabarnya dalam bentuk hipotesis. Hipotesis boleh kekal dalam bentuk hipotesis selagimana ia tidak disandarkan pada bukti, dan juga boleh runtuh jika dicabar dengan hipotesis yang lain yang disandarkan pada bukti. Dengan itu, kebenaran tadi tidak akan bersifat asbolut, terus disahkan, dan kita akan lebih fleksibel untuk menerima perkara baru.</p>
<p>Dalam aspek pengaturcaraan pula, kita boleh menggunakan <em>testing</em> sebagai alat untuk menguji kod yang telah ditulis supaya ia mengikut spesifikasi yang diharapkan (juga kebenaran tunggal). Disebabkan itu, pendekatan Test Driven Development (TDD) adalah sangat penting supaya kod yang kita hasilkan tidak tergelincir daripada objektif yang telah kita tetapkan lantas perasaan skeptik dalam diri kita dapat disucikan.</p>
<h2 id="heading-alat-adalah-alat-yang-penting-fungsinya">Alat adalah Alat, yang Penting Fungsinya</h2>
<p>Masalah yang selalu terjadi terutamanya kepada pemula adalah, terlalu kerap berfikir dan bertanya "Mana yang lebih baik?"</p>
<p>Sehinggakan akhirnya tidak mula bertindak dan berbuat apa-apa. Ini barangkali disebabkan lewah fikir, terlalu risau dan takut mengambil risiko (walaupun risiko masih dalam kawalan). Walhal apa yang dibandingkan itu mempunyai objektif akhir yang sama, namun disebabkan terlalu membanding-banding, akhirnya masa terbuang begitu sahaja tanpa apa apa tindakan.</p>
<p>Umpama kita ingin bergerak ke suatu destinasi dan dihadapan kita terdapat 2 buah basikal, iaitu basikal merah dan biru. Kedua-duanya mempunyai objektif yang sama iaitu membawa kita ke titik destinasi. Basikal merah dan biru mungkin mempunyai sedikit perbezaan namun tidaklah terlalu ketara. Namun, jika kita terlalu runsing memikirkan basikal mana yang lebih baik, yang lebih mudah, yang lebih lancar, tidak akan membuatkan kita jatuh ketanah dan terluka, akhirnya sampai esok tidak akan sampai ke destinasi akhir! Seolah-olah kita takut untuk jatuh daripada basikal tersebut, walaupun hakikatnya kita belum pun mula mengayuh lagi.</p>
<p>Jika anda mengalami masalah ini, penulis cadangkan berfikir dengan cara - <em>nothing to lose</em>. Mulalah dengan mana-mana alat sekalipun. Kalaupun kita silap memilih alat, kita telah mempelajari sesuatu daripada kesilapan tersebut. Setelah membuat silap, kita bergerak dan cari solusi yang lain. Hidup ini memang begitu, tak semua yang kita harapkan menjadi, maka kita belajar.</p>
<h2 id="heading-tetap-belajar">Tetap Belajar</h2>
<p>Dalam dunia teknologi yang bergerak semakin pantas, kita tidak ada pilihan lain untuk tetap belajar dan belajar. Semangat ini penting atas beberapa sebab yang saya rasakan amat mustahak untuk dinyatakan.</p>
<p>Pertama, tetap belajar mengasah skil menyelesaikan masalah. Semakin banyak kita belajar, semakin banyak kita buat silap, semakin tinggi daya dan kebolehan kita untuk menghasilkan jalan penyelesaian sama ada pendek atau panjang.</p>
<p>Kedua, tetap belajar menjadikan kita manusia yang tidak mudah selesa dengan sesuatu. Mempelajari sesuatu bermakna kita juga perlu menghadapi cabaran-cabaran yang baharu. Cabaran ini membuatkan kita tidak selesa namun dalam konotasi yang positif. Proses "tidak selesa" bermakna otak sedang mencerna sesuatu. Seperti kita melihat pupa rama-rama yang bersungguh-sunggu melepaskan diri daripada kongkongan pupa, yang akhirnya di akhir proses tersebut menjadikan ia seekor rama-rama yang indah, seperti itulah kita akan mencapai tahap "Ohh..." dimana kefahaman tercapai.</p>
<p>Akhir sekali, tetap belajar menjadikan kita lebih merendah diri dalam apa-apa bidang sekalipun. Biasa kita mendengar ungkapan "Semakin kita belajar, semakin banyak yang kita tidak tahu." (Dunning-Kruger Effect). Sikap rendah diri ini menyebabkan kita akan lebih laparkan ilmu pengetahuan dan terus menerus memperbaiki diri semasa ke semasa.</p>
<h1 id="heading-kesimpulan">Kesimpulan</h1>
<p>Cara fikir yang dinyatakan diatas tidak mampu dibentuk dalam masa sehari. Ia memerlukan proses, yang mungkin memakan masa berbulan mahupun bertahun. Namun penting untuk kita fikirkan dan tanam dalam diri supaya ia dapat membantu kita menjadi seorang pengaturcara yang lebih baik, suatu hari nanti.</p>
<h1 id="heading-sumber">Sumber</h1>
<ol>
<li><p>The Pragmatic Programmer - Andrew Hunt &amp; David Thomas</p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=THE1ktA3G6s&amp;ab_channel=ArjanCodes">5 Ways First Principle Thinking Helps You Code Better - ArjanCodes Channel</a></p>
</li>
<li><p><a target="_blank" href="https://obsidian.md/">Obisidian</a></p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Kod di Khalayak: Malu Tanya Sesat Jalan]]></title><description><![CDATA[Kod di khalayak atau code in public adalah salah satu teknik yang sangat membantu buat pengaturcara pemula, lebih-lebih lagi kepada mereka yang tidak mempunyai latar belakang dalam bidang pengaturcaraan. Cara ini membuatkan anda untuk terus belajar, ...]]></description><link>https://mmarsaf.xyz/kod-di-khalayak-malu-tanya-sesat-jalan</link><guid isPermaLink="true">https://mmarsaf.xyz/kod-di-khalayak-malu-tanya-sesat-jalan</guid><category><![CDATA[Python]]></category><category><![CDATA[coding]]></category><category><![CDATA[learning]]></category><category><![CDATA[Learning Journey]]></category><category><![CDATA[#learning-in-public]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Sun, 30 Jul 2023 07:32:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/_UIVmIBB3JU/upload/7be0ce74e05fa169c27659b0297624e0.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Kod di khalayak atau <em>code in public</em> adalah salah satu teknik yang sangat membantu buat pengaturcara pemula, lebih-lebih lagi kepada mereka yang tidak mempunyai latar belakang dalam bidang pengaturcaraan. Cara ini membuatkan anda untuk terus belajar, namun jarang dipraktikkan oleh sebab tertentu. Barangkali mungkin rasa malu atau tidak yakin atau tidak berani untuk menerima komen atau kritikan daripada <em>stranger</em>. Dengan belajar secara terbuka, ia juga membawa maksud anda mampu untuk melakukan kesilapan secara terbuka dan "terbuka" menerima segala kritikan dan jawapan.</p>
<p>Setahun selepas penulis memulakan perjalanan dalam arena pengaturcaran dan cuba mengamalkan pendekatan ini, banyak yang penulis telah pelajari. Bukan sahaja dapat belajar perkara baharu, tetapi juga berkenalan dengan mereka yang lebih berpengalaman, mengorek ilmu pengetahuan mereka sekaligus meningkatkan mutu kod dan pengetahuan. Beberapa cara yang telah penulis lakukan sewaktu mengamalkan pendekatan kod di khalayak.</p>
<h2 id="heading-komuniti">Komuniti</h2>
<p>Untuk sesetengah manusia, mungkin bertanya adalah sesuatu yang berat, sesuatu yang memerlukan kekuatan. Tetapi dengan hanya bertanya, dengan sebuah soalan, ia menjadi pintu kepada sebuah perjalanan dan pengalaman baharu. Dengan wujudnya komuniti, anda tidak perlu lagi khuatir kerana disini anda akan jumpa dengan ramai pengaturcara untuk mendapatkan sokongan dan bantuan.</p>
<p>Penulis mempunyai beberapa tempat yang biasanya digunakan bagi menyelesaikan masalah kod atau <em>debug</em>.</p>
<p>Biasanya penulis akan mulakan dengan <strong>Stack Overflow</strong>. Disini tempat dimana berkumpulnya soalan-soalan daripada segenap pelusuk dunia. Masalah dalam pengaturcaraan biasanya dialami oleh pengaturcara lain. Masalah yang anda hadapi berkemungkinan besar telah dihadapi dan telah diselesaikan oleh orang lain. Namun, jika anda telah mencari sepuasnya di Internet, mahupun di Stack Overflow tetapi tidak menjumpai, maka anda boleh mula untuk bertanya disana.</p>
<p>Pastikan anda menulis konteks persoalan atau masalah yang telah berlaku dengan jelas. Jika ada, sediakan tangkap layar atau sebahagian baris daripada kod dan juga mesej ralat yang terhasil. Ini bagi memudahkan pengguna lain yang mempunyai jawapan untuk menjawab soalan yang ditanyakan.</p>
<p>Jika masalah tidak juga dapat diselesaikan, maka anda boleh cuba untuk bertanya dalam kumpulan komuniti dalam talian. Contohnya adalah komuniti di Telegram, Discord dan Slack. Kumpulan dalam talian juga adalah tempat dimana pakar, pengaturcara senior, junior, pemula berkumpul dan membincangkan hal-hal yang berkaitan dengan teknologi dan pengaturcaraan.</p>
<h2 id="heading-sumber-terbuka">Sumber Terbuka</h2>
<p>Dengan sumber terbuka, anda boleh memilih sama ada untuk menulis projek anda sendiri ataupun menyumbang kepada projek orang lain.</p>
<p>Menulis projek sendiri memberikan pengalaman untuk merasai pengalaman membuat sebuah aplikasi. Anda adalah laksamana dalam kapal anda. Anda yang menetapkan objektif projek, bahasa pengaturcaran, pengkalan data, tabung awan dan sebagainya.</p>
<p>Apabila ia dinamakan projek sumber terbuka, maka ia terbuka kepada sesiapa yang mahu menyumbang kepada projek ini. Maka daripada sini, budaya perbincangan, persoalan, cadangan penambahbaikan akan bercambah sekaligus mempercepatkan pembangunan projek menuju kepada objektif yang telah ditetapkan.</p>
<p>Jika tidak ingin menulis projek sendiri, menyumbang kepada projek sumber terbuka juga adalah salah satu cara untuk belajar daripada kesilapan. Anda boleh menyumbang apa jua jenis pertolongan kepada projek terbuka daripada sekecil-kecil membetulkan kesalahan ejaan dalam dokumentasi, sehingga sebesar-besar pemfaktoran (jika diterima haha!).</p>
<p>Apa yang lebih penting sebenarnya adalah bagaimana anda mampu mencipta masalah dan menawarkan solusi yang mana menjadi salah satu proses untuk terus belajar dan belajar.</p>
<p>Jika anda berminat untuk menyumbang kepada sumber terbuka, beberapa perkara yang anda harus ketahui iaitu:</p>
<ol>
<li><p>Git</p>
</li>
<li><p>Github</p>
</li>
</ol>
<p>Selepas anda mempelajari kedua perkara ini, anda boleh melayari laman sesawang <a target="_blank" href="https://freexp.dev/">Free-XP</a> iaitu sebuah laman sesawang yang menyenaraikan senarai projek terbuka di Github. Anda boleh memilih mana-mana projek yang anda minati dan mulakan perjalanan kod di khalayak pertama anda!</p>
<h2 id="heading-media-sosial">Media Sosial</h2>
<p>Penulis mendaikan anda pastinya mempunyai media sosial, samada Facebook, Instagram mahupun Twitter. Disini juga anda boleh mempraktikkan kod di khalayak dengan bertanyakan soalan ataupun menjawab pertanyaan orang lain.</p>
<p>Media sosial bukan sahaja tempat anda bersosial, malah bertemu dengan professional. Maka gunakan media sosial dengan sewajarnya supaya anda dapat mempelajari sesuatu dan memudahkan proses pembelajaran anda ke peringkat seterusnya.</p>
<p>Ada juga sesetengah pengaturcara yang menulis kod secara siaran langsung dengan menggukan aplikasi Twitch mahupun Tiktok. Orang ramai dapat melihat secara langsung proses penulisan kod dan (barangkali) dapat melatih anda untuk menghadapi tekanan semasa menulis kod sambil diperhatikan.</p>
<h2 id="heading-kesimpulan">Kesimpulan</h2>
<p>Tuntasnya, kod di khalayak mampu menjadi <em>catalyst</em> untuk anda terus belajar dengan lebih efektif dan pantas. Menyimpan masalah anda seorang diri adalah tidak digalakkan kerana akan membantutkan lengkung pembalajaran anda.</p>
<p>Sekian artikel kali ini, sampai jumpa!</p>
]]></content:encoded></item><item><title><![CDATA[Setup Github Repo properly for Collaboration Projects]]></title><description><![CDATA[Setup a Github repository for collaboration in a team is important. By having a systematical setup, we can avoid any accidental issue that might be happened whether it comes from the junior dev or senior dev.
As on 11th May 2023, 9:32 AM, these are s...]]></description><link>https://mmarsaf.xyz/setup-github-repo-properly-for-collaboration-projects</link><guid isPermaLink="true">https://mmarsaf.xyz/setup-github-repo-properly-for-collaboration-projects</guid><category><![CDATA[GitHub]]></category><category><![CDATA[repository]]></category><category><![CDATA[Collaboration]]></category><category><![CDATA[projects]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Sun, 28 May 2023 06:56:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/0gkw_9fy0eQ/upload/7cb549e6928daa91b52010146e3274f3.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Setup a Github repository for collaboration in a team is important. By having a systematical setup, we can avoid any accidental issue that might be happened whether it comes from the junior dev or senior dev.</p>
<p>As on 11th May 2023, 9:32 AM, these are some of the setups that I found might be useful for a small project.</p>
<ol>
<li><p>Decide who is the admin and maintainer. Both have different access in the repo.</p>
</li>
<li><p>Plan how the project would be built based on the branch that would be created.</p>
<ol>
<li><p>You can decide whether to preserve the<code>main</code> branch code as it is without doing any commit on it or make it a branch that you will add a new feature (or patch) for the <code>dev_branch</code>.</p>
</li>
<li><p>You can create a branch for deployment as it becomes the <strong>base branch</strong> (other than <code>main</code>) to become the core source for <code>dev</code> branch.</p>
</li>
<li><p>For debugging or adding a simple feature, you can create a branch from the base branch (might be the dev branch where bugs exist) and apply <strong>fast-forward merge</strong> to solve it.</p>
</li>
</ol>
</li>
<li><p>Create <strong>branch rule</strong>.</p>
<p> This is crucially important to strictly prohibit the flow of merging the code to the <code>main</code> or base branch. In branch rules;</p>
<ol>
<li><p>At least 1 or 2 people to review the Pull Request before proceeding to merge.</p>
</li>
<li><p>Prevent force pushing.</p>
</li>
<li><p><strong>Restrict who can push to matching branches — restricting</strong> certain people who can push directly to the base branch. Other than the allowed person, they can make a PR but are not allowed to merge in PR.</p>
</li>
</ol>
</li>
<li><p>Required status checks.</p>
<ol>
<li><p>Checking one by one the commit in the PR — checks using Github Action</p>
<p> <a target="_blank" href="https://github.com/marketplace/actions/easy-coding-standard-action">https://github.com/marketplace/actions/easy-coding-standard-action</a></p>
</li>
<li><p>Unit test</p>
</li>
</ol>
</li>
<li><p>Define CODEOWNERS</p>
<ul>
<li>define the specific reviewers; ie expertise</li>
</ul>
</li>
</ol>
<p>This writing might be updated soon or future whenever found new advice or suggestion.</p>
]]></content:encoded></item><item><title><![CDATA[Pull Request: Bagaimana Merge berlaku di Github]]></title><description><![CDATA[Pengenalan
Merge adalah sebuah tindakan dimana git akan menggabungkan commit yang telah dibuat menjadi satu commit yang baharu pada hujung (tip) sesebuah git history.

Jika di lokal, kita boleh melakukan git merge untuk mencantumkankan commit daripad...]]></description><link>https://mmarsaf.xyz/pull-request-bagaimana-merge-berlaku-di-github</link><guid isPermaLink="true">https://mmarsaf.xyz/pull-request-bagaimana-merge-berlaku-di-github</guid><category><![CDATA[GitHub]]></category><category><![CDATA[merge]]></category><category><![CDATA[Pull Requests]]></category><category><![CDATA[Git]]></category><category><![CDATA[commit]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Sun, 28 May 2023 06:24:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/L_UjmeJcWoY/upload/79091b0ef4b1654b66dfc758ea6c1c9f.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-pengenalan">Pengenalan</h1>
<p><code>Merge</code> adalah sebuah tindakan dimana <code>git</code> akan menggabungkan <code>commit</code> yang telah dibuat menjadi satu <code>commit</code> yang baharu pada hujung (tip) sesebuah <em>git history</em>.</p>
<p><img src="https://wac-cdn.atlassian.com/dam/jcr:c6db91c1-1343-4d45-8c93-bdba910b9506/02%20Branch-1%20kopiera.png?cdnVersion=1031" alt="Git Merge | Atlassian Git Tutorial" /></p>
<p>Jika di lokal, kita boleh melakukan <code>git merge</code> untuk mencantumkankan <code>commit</code> daripada <code>feature_branch</code> kepada <code>main_branch</code>. Namun, ia sedikit berbeza apabila kita ingin melakukannya pada penyedia <em>cloud hosting</em> seperti <strong>Github</strong>.</p>
<p>Terdapat dua keadaan yang membezakan cara untuk <code>merge commit</code> di Github.</p>
<ol>
<li><p>Keadaan <em>Branch</em> tidak dilindungi</p>
</li>
<li><p>Keadaan <em>Branch</em> dilindungi</p>
</li>
</ol>
<h2 id="heading-branch-tidak-dilindungi"><em>Branch</em> tidak dilindungi</h2>
<p>Sebuah <em>branch</em> yang tidak dilinduingi bermaksud <em>branch</em> tersebut tidak termaktub kepada peraturan-peraturan tertentu yang boleh di buat pada Github. Misalnya <em>branch</em> ini membenarkkan sesiapa sahaja untuk di- <code>merge</code> kepada dan juga daripada mana-mana <em>feature branch</em> yang ada.</p>
<p>Untuk <em>branch</em> jenis ini, kita boleh sahaja membuat <em>commit</em> dan <em>merging</em> seperti biasa di lokal kemudian <em>push</em> ke Github.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># pastikan berada di main branch </span>
$ git checkout main
<span class="hljs-comment"># commit sesuatu perubahan </span>
$ git checkout -b feature_1 
$ git add . 
$ git commit -m <span class="hljs-string">"commit pertama"</span>

<span class="hljs-comment"># push branch ke remote</span>
$ git push --set-upstream feature_1 origin 

<span class="hljs-comment"># proses merge</span>
$ git checkout main
$ git merge feature_1 

<span class="hljs-comment"># push ke remote github</span>
$ git push
</code></pre>
<p>Selepas menjalankan <em>command</em> diatas, kita akan mendapati <code>main</code> <em>branch</em> pada <em>remote</em> telah dikemaskini daripada <code>feature_1</code> <em>branch.</em> Proses <code>merging</code> telah berjaya tanpa melibatkan penggunaan UI di Github (iaitu Pull Request atau PR)</p>
<h2 id="heading-branch-dilindungi"><em>Branch</em> dilindungi</h2>
<p>Sebaliknya, jika <em>branch</em> tersebut dilindungi; yakni terdapat peraturan yang telah ditetapkan supaya pengaturcara tidak boleh sewenang-wenangnya <code>merge</code> dan <code>push</code> daripada <em>branch lain</em> seperti yang berlaku keadaan <em>branch</em> tidak dilindungi. Disebabkan ia dilindungi, maka cara yang ditunjukkan pada keadaan pertama tidak dapat dilakukukan.</p>
<p>Ini keraana atas sebab peraturan yang telah ditetapkan, Github akan <strong>menghalang</strong> daripada pengguna untuk <code>push</code> <em>commit</em> tersebut melaikan ia melepasi pertaturan yang telah ditetapkan.</p>
<p>Kebiasaannya <em>branch</em> dilindungi akan mempunyai lapisan dibawah</p>
<ol>
<li><p>Code review — kod akan disemak oleh ahli projek dan menunggu untuk <em>approval</em></p>
</li>
<li><p><em>Code testing —</em> Kod akan melalui <em>testing</em> (unit test, etc) yang telah ditetapkan dalam Git Actions.</p>
</li>
</ol>
<p>Maka, apakah langkah untuk melakukan <code>merge</code> kepada <code>main</code> <em>branch</em> supaya anda boleh mengemaskini/menambah kod baru kepada projek anda untuk keadaan ini?</p>
<p>Kita perlu melakukan apa yang dinamakan sebagai <strong>Pull Request.</strong></p>
<h3 id="heading-pull-request">Pull Request</h3>
<p>Proses Pull Request (PR) adalah seperti berikut:</p>
<ol>
<li>Buat <em>commit seperti biasa</em></li>
</ol>
<pre><code class="lang-bash"><span class="hljs-comment"># Cipta branch baharu</span>
$ git checkout -b my_branch 
$ git push --set-upstream my_branch origin 
$ git add . 
$ git commit -m <span class="hljs-string">"menambah sesuatu"</span>
</code></pre>
<ol>
<li><p>Github akan mengeluarkan notifikasi mengenai <em>commit</em> yang telah berlaku dengan butang <em>pull request</em>. Tekan butang <em>pull request</em> tersebut.</p>
<p> (Jika tidak ada notifikasi tekan <em>pull request</em> pada projek repo anda di Github dan tekan <em>Create new pull request.</em>)</p>
</li>
<li><p>Setelah menekan <em>Pull request,</em> Github akan memaparkan <strong>Compare change</strong> dan kita perlu memilih</p>
<ul>
<li><p>Compare branch (<em>feature branch</em>)</p>
</li>
<li><p>Base branch (<em>main branch</em>)</p>
</li>
</ul>
</li>
<li><p>Pilih <code>my_branch</code> sebagai <strong><em>compare</em></strong>, dan <code>main</code> sebagai <strong><em>base</em></strong> untuk kita <em>merge</em> <code>my_branch</code> kepada <code>main</code>.</p>
</li>
<li><p>Selepas itu Github akan memaparkan seksyen dimana jika kod anda melepasi <em>testing</em> dan juga kod anda perlu melalui <strong><em>code review</em></strong> (<em>approval</em> boleh dibuat oleh sesiapa sahaja yang terlibat dalam projek, atau orang tertentu.)</p>
</li>
<li><p>Selepas <em>Approve</em> dan <em>Submit review</em> diberikan oleh pengaturcara lain, maka kod anda telah bersedia untuk dicantukan kepada <em>base branch</em> yang telah ditetapkan.</p>
</li>
<li><p>Tekan <em>Merge pull request</em> dan kod akan dicantumkan. Siap!</p>
</li>
</ol>
<h2 id="heading-mengapa-perlu-sedemikian">Mengapa perlu sedemikian?</h2>
<p>Anda sedia maklum bahawa penggunaan Git dapat membantu projek yang besar dan melibatkan ramai pengaturcara. Github telah menjadi sebuah tempat dimana sumber kod disimpan dan digunakan untuk tujuan <em>deployment</em>. Maka amat mustahak kod-kod ini dijaga dan dilindungi daripada sebarang kesilapan dan masalah yang boleh menyebabkan kod-kod legasi tadi mengalami ralat.</p>
<p>PR secara tidak langsung mencipta satu lapisan (boleh jadi beberapa lapisan) yang menjadi penghalang sebelum sesebuah <em>feature</em> atau penambahan berlaku ke dalam kod yang asal.</p>
<p>Dalam <em>code review</em>, pengaturcara lain boleh menyemak struktur kod tersebut samada boleh diterima, tidak baik atau memerlukan penambah baikan. Disini juga pengaturcara boleh mengkritik mengenai kod yang ditulis sekaligus menjadi tempat perbincangan.</p>
<p><em>Code testing</em> pula boleh di <em>setup</em> bagi memeriksa kod yang ditulis seperti, memenuhi kriteria cara penulisan kod untuk projek tersebut, atau menyemak samada kod tersebut tidak terdedah kepada penyelewengan dan sebagainya.</p>
<p>Anda boleh menetapkan peraturan-peraturan sesebuah <em>branch</em> di <em>Setting</em> dan pilih <em>Branch</em> untuk menentukan bagaimana <em>branch</em> tersebut dilindungi.</p>
<p>Sekian itu saja daripada saya. Cuba lakukan PR anda sendiri dan komen jika artiken ini membantu. Selamat mencuba.</p>
<h1 id="heading-sumber">Sumber</h1>
<ol>
<li>Rajah: <a target="_blank" href="https://wac-cdn.atlassian.com/dam/jcr:c6db91c1-1343-4d45-8c93-bdba910b9506/02%20Branch-1%20kopiera.png?cdnVersion=1031">https://wac-cdn.atlassian.com/dam/jcr:c6db91c1-1343-4d45-8c93-bdba910b9506/02%20Branch-1%20kopiera.png?cdnVersion=1031</a></li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Perwarisan, Pengkapsulan dan Polimorfism dalam OOP: Sebuah Pendekatan]]></title><description><![CDATA[Revisi OOP
Object-oriented programming (OOP) adalah sebuah pendekatan dalam pengaturcaraan yang menjadikan objek sebagai rujukan akses kepada metod (fungsi) tertentu. Dalam Python, OOP diprogram menggunakan katakunci Class.
Dalam Class, anda boleh ra...]]></description><link>https://mmarsaf.xyz/perwarisan-pengkapsulan-dan-polimorfism-dalam-oop</link><guid isPermaLink="true">https://mmarsaf.xyz/perwarisan-pengkapsulan-dan-polimorfism-dalam-oop</guid><category><![CDATA[Python]]></category><category><![CDATA[inheritance]]></category><category><![CDATA[encapsulation]]></category><category><![CDATA[polymorphism]]></category><category><![CDATA[class]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Sun, 04 Dec 2022 08:33:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1670143196143/1MTPFo0os.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-revisi-oop">Revisi OOP</h1>
<p><em>Object-oriented programming</em> (OOP) adalah sebuah pendekatan dalam pengaturcaraan yang menjadikan <strong>objek</strong> sebagai rujukan akses kepada metod (fungsi) tertentu. Dalam Python, OOP diprogram menggunakan katakunci <code>Class</code>.</p>
<p>Dalam <code>Class</code>, anda boleh rangkumkan beberapa metod atau operasi yang mempunyai perkatainan antara satu sama lain. Misalanya jika kita mencipta <code>Class</code> operasi matematik, dalam <code>Class</code> tersebut seharusnua terdapat metod penambahan, penolakan, pembahagian dan lain-lain lagi, bergantung kepada pengaturcara itu sendiri. Anda juga boleh mencipta atribut (seperti pemboleh ubah jika diluar Class) yang dapat digunakan oleh metod <code>Class</code> tersebut.</p>
<p>Dalam membangunakan OOP, terdapat beberapa konsep atau pendekatan tertentu yang biasa dipraktikkan.</p>
<p>Antara pendekatan yang biasa digunakan adalah:</p>
<ol>
<li><p>Perwarisan (<em>Inheritance</em>)</p>
</li>
<li><p>Pengkapsulan (<em>Encapsulation</em>)</p>
</li>
<li><p>Polimorphism (<em>Polymorphism</em>)</p>
</li>
</ol>
<blockquote>
<p>Nota:</p>
<p>Jika anda belum terbiasa dengan konsep OOP, penulis menyarankan anda untuk berkenalan dengan OOP dahulu sebelum meneruskan pembacaan artikel ini.</p>
</blockquote>
<h2 id="heading-perwarisan">Perwarisan</h2>
<p>Seperti namanya, perwarisan boleh dianalogikan seperti ibubapa yang mewariskan genetik mereka pada si anak. </p>
<p>Dalam konteks Python, terdapat Class ibubapa dan Class anak. </p>
<p>Class anak akan mewarisi Class ibu bapa, seperti mana anak yang mewarisi ciri ibu bapanya.</p>
<p><img src="https://cdn.pixabay.com/photo/2012/03/04/01/01/father-22194_960_720.jpg" alt="Free photos of Father" /></p>
<p>Mari kita lihat bagaimana caranya untuk menggunakan Perwarisan dalam Class.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, height, animal_type</span>):</span>
        self.size = height
        self.animal_type = animal_type

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_height</span>(<span class="hljs-params">self</span>):</span>
        print(self.height)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_animal_type</span>(<span class="hljs-params">self</span>):</span>
        print(self.animal_type)

<span class="hljs-comment"># perwarisan</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ExtendAnimal</span>(<span class="hljs-params">Animal</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">init</span>(<span class="hljs-params">self, height, weight, animal_type, movement</span>):</span>
        self.height = height
        self.weight = weight
        self.animal_type = animal_type
        self.movement = movement
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_height_weight</span>(<span class="hljs-params">self</span>):</span>
        self.get_height()
        print(self.weight) <span class="hljs-comment"># extension</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_type_movement</span>(<span class="hljs-params">self</span>):</span>
        self.get_animal_type()
        print(self.movement) <span class="hljs-comment"># extension</span>


fish = ExtendAnimal(<span class="hljs-number">5</span>, <span class="hljs-number">10</span>, <span class="hljs-string">'Amphibian'</span>, <span class="hljs-string">'Swimming'</span>)
fish.get_height_weight()
fish.get_type_movement()
</code></pre>
<pre><code class="lang-python">Output:
<span class="hljs-number">5</span>
<span class="hljs-number">10</span>
Amphibian
Swimming
</code></pre>
<p>Contoh kod diatas adalah contoh perwarisan Class.</p>
<p><code>Class</code> yang pertama iaitu <code>Animal</code> adalah <code>Class</code> yang memaparkan ciri haiwan iaitu <code>height</code> dan <code>animal_type</code>.</p>
<p><code>Class</code> yang kedua iaitu <code>ExtendAnimal</code> telah mewarisi (<code>class ExtendAnimal(Animal)</code>) daripada Class yang pertama dan telah menambah keupayaan <code>Class</code> pertama jika dilihat pada metodnya.</p>
<p>Kita dapat melihat bagaimana Perwarisan dapat menambah lagi fungsi Class pada metod <code>get_height_weight()</code>yang mengeluarkan output <code>height</code>  yang diwariskan daripada <code>Class Animal</code>. Metod ini juga adalah <em>extension</em> daripada metod <code>get_height</code> daripada class <code>Animal</code> yang mana ia mengoutput <code>weight</code> dalam masa yang sama.</p>
<p>Dengan mewarisi Class ibubapa, Class anak mempunyai keupayaan tertentu hasil daripada perwarisan tadi. Antaranya;</p>
<blockquote>
<ol>
<li><p>Class anak mempunyai ciri yang sama daripada Class ibu bapa.</p>
</li>
<li><p>Class anak boleh ditambah kemampuan kegunaan metodnya.</p>
</li>
<li><p>Class anak boleh dikemasikini (*<em>update</em>*) tanpa mengganggu kod asal daripada Class ibubapa.</p>
</li>
<li><p>Atribut dan method dalam Class anak boleh mengatasi (*<em>override*</em>) Class ibubapa.</p>
</li>
<li><p>Class ibubapa boleh berkongsi atribut kepada Class anak.</p>
</li>
<li><p>Mencipta heirarki Class berturutan daripada Class ibubapa kepada Class anak.</p>
</li>
</ol>
</blockquote>
<p>Jadi apa kebaikan jika kita menggunakan pendekatan ini?</p>
<blockquote>
<ol>
<li><p>Pengaturcara mampu menambah baik kod asal tanpa mengubahsuai struktur kod tersebut.</p>
</li>
<li><p>Class anak boleh mewarisi keseluruhan ciri Class ibubapa, atau mewarisi sebahagian sahaja daripada ciri Class ibubapa. Ini memberi kawalan yang baik kepada pengaturcara untuk menambah baik Class ibubapa dengan had tertentu.</p>
</li>
</ol>
</blockquote>
<h2 id="heading-pengkapsulan">Pengkapsulan</h2>
<p>Pengkapsulan adalah sebuah pendekatan dimana metod-metod dirangkumkan dalam satu unit.</p>
<blockquote>
<p>Penggunaan Class dalam Python itu sendiri adalah sebuah pengkapsulan.</p>
</blockquote>
<p><img src="https://cdn.pixabay.com/photo/2015/12/06/18/28/capsules-1079838__340.jpg" alt="Free photos of Capsules" class="image--center mx-auto" /></p>
<p>Pengkapsulan dapat menyekat akses kepada atribut dan metod dalam Class (<em>underscore variable</em> dan penggunaan metod yang hanya diketahui oleh pencipta kod tersebut) yang dapat mengelakkan daripada data diubahsuai daripada kod atau pengguna luar.</p>
<p>Andaikan anda ingin mencipta sebuah Class yang mengandungi maklumat rahsia ejen peribadi. Tentu sahaja anda tidak mahu informasi ini dimanipulasi atau diubahsuai oleh kod atau pengguna luar.</p>
<p>Maka untuk menjadikan atribut tersebut peribadi, gunakan 2 <em>underscore</em> seperti kod dibawah;</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ClassifiedInfo</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">init</span>(<span class="hljs-params">self, name, height, weight, country, gender</span>):</span>
        self.name = name
        self.__height = height
        self.__weight = weight
        self.__country = country
        self.__gender = gender
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_agent_information</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">f'<span class="hljs-subst">{self.name}</span> information:\
        \nGender: <span class="hljs-subst">{self.__gender}</span>, \
        \nCountry: <span class="hljs-subst">{self.__country}</span>,'</span>)
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_agent_height</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">f'Height: <span class="hljs-subst">{self.__height}</span>'</span>)

agent_1 = ClassifiedInfo(<span class="hljs-string">"Jack"</span>, <span class="hljs-number">178</span>, <span class="hljs-number">89</span>, <span class="hljs-string">"Brazil"</span>, <span class="hljs-string">"Male"</span>)\
agent_1.get_agent_information()
agent_1.__height
</code></pre>
<pre><code class="lang-python">Output:

Jack information:
Gender: Male,
Country: Brazil,
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[<span class="hljs-number">34</span>], line <span class="hljs-number">20</span>
<span class="hljs-number">17</span> agent_1 = ClassifiedInfo(<span class="hljs-string">"Jack"</span>, <span class="hljs-number">78</span>, <span class="hljs-number">189</span>, <span class="hljs-string">"Brazil"</span>, <span class="hljs-string">"Male"</span>)\
<span class="hljs-number">19</span> agent_1.get_agent_information()
---&gt; <span class="hljs-number">20</span> agent_1.__height
AttributeError: <span class="hljs-string">'ClassifiedInfo'</span> object has no attribute <span class="hljs-string">'__height'</span>
</code></pre>
<p>Jika diperhatikan, output daripada <code>agent_1.__height</code> adalah <mark>ralat atribut</mark>. Ini bermakna maklumat <code>height</code> tidak mampu diakses sewenenang-wenangnya.</p>
<p>Dengan menggunakan dua <em>underscore</em>, ia boleh melindungi atribut dalam Class daripada dimanipulasi oleh kod atau pengguna luar.</p>
<p>Jadi bagaimana caranya untuk mengakses atribut peribadi ini? Dengan mencipta metod yang dapat diaksesnya. Dalam kod diatas, penulis telah mencipta sebuah metod <code>get_agent_height</code> yang mana metod ini akan mengeluarkan output maklumat ketinggian agent ini.</p>
<p>Ini bermakna, pengguna luar tidak berupaya untuk mengakses atribut peribadi dalam sesebuah kod, dan hanya pembangun kod sahaja yang mampu mengakses data tersebut dengan menggunakan metod yang dia ciptakan.</p>
<p>Dalam kod diatas, penulis telah mencipta metod <code>get_agent_height()</code> untuk mengakses maklumat atribut <code>height</code> .</p>
<pre><code class="lang-python"><span class="hljs-comment"># mengakses atribut peribadi</span>
agent_1.get_agent_height()
</code></pre>
<pre><code class="lang-python">Output:

Height: <span class="hljs-number">178</span>
</code></pre>
<p>Maklumat <code>height</code> telah <strong>berjaya</strong> diakses.</p>
<p>Kebaikan menggunakan pengkapsulan adalah;</p>
<blockquote>
<ol>
<li><p>Punca ralat dapat dikenalpasti dengan merujuk nama Class dan metod.</p>
</li>
<li><p>Pengaturcara dapat melindungi data tertentu daripada diubahsuai oleh pengguna luar.</p>
</li>
</ol>
</blockquote>
<h2 id="heading-polimorfism">Polimorfism</h2>
<p>Polimorfism berasal daripada bahasa Greek, bermakna sesuatu yang wujud dalam bentuk (morfo) yang pelbagai (poli).</p>
<p><img src="https://cdn.pixabay.com/photo/2017/09/07/16/50/acropolis-2725918__340.jpg" alt="Free photos of Acropolis" class="image--center mx-auto" /></p>
<p>Dalam konteks OOP, Class akan yang sama akan dicipta dalam pelbagai bentuk.</p>
<p>Konsep polimorfism telah digunakapakai secara meluas dalam pengaturcaraan. Antara contoh polimorfism dalam Python adalah simbol tambah (+) itu sendiri.</p>
<pre><code class="lang-python"><span class="hljs-comment"># penambahan nombor</span>
value_a = <span class="hljs-number">12</span>
value_b = <span class="hljs-number">5</span>
print(a+b)
<span class="hljs-comment"># penggabungan string</span>
string_1 = “Hello”
space = “ “
string_2 = “World!”
print( string_1 + space + string_2)
</code></pre>
<pre><code class="lang-python">Output:
<span class="hljs-number">17</span>
Hello World!
</code></pre>
<p>Dalam Python, jika simbol tambah digunakan pada nombor (<em>interger</em>), ia akan menambahkan nilai nombor tersebut. Manakala jika digunakan pada perkataan (<em>string</em>), perkataan tersebut akan digabungkan. Maka simbol tambah ini bergantung kepada input apa yang diberikan. Ia simbol yang sama, tapi boleh wujud dalam kegunaan berbeza.</p>
<p>Mari kita lihat bagaimana anda boleh mengaplikasikan polimorfism pada Class dalam Python.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Jack</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">init</span>(<span class="hljs-params">self, age, gender, address</span>):</span>
    self.age = age
    self.gender  = gender
    self.address = address

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_age</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">f'Age: <span class="hljs-subst">{self.age}</span>'</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_gender</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">f'Gender: <span class="hljs-subst">{self.gender}</span>'</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_address</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">f'Address: <span class="hljs-subst">{self.address}</span>'</span>)

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Jenny</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, age, gender, address</span>):</span>
        self.age = age
        self.gender  = gender
        self.address = address

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_age</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">f'Age: <span class="hljs-subst">{self.age}</span>'</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_gender</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">f'Gender: <span class="hljs-subst">{self.gender}</span>'</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_address</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">f'Address: <span class="hljs-subst">{self.address}</span>'</span>)

jack = Jack(<span class="hljs-number">19</span>, <span class="hljs-string">'male'</span>,<span class="hljs-string">'USA'</span>)
jenny = Jenny(<span class="hljs-number">21</span>, <span class="hljs-string">'female'</span>, <span class="hljs-string">'Colombia'</span>)
</code></pre>
<p>Dalam kod diatas, <code>Class Jack</code> and <code>Jenny</code> mempunyai struktur yang sama; dengan nama metod yang sama tetapi bentuk (nama Class) yang berbeza. Ini adalah konsep polimorfism.</p>
<p>Daripada objek diatas, anda boleh menggunakan kesemua metod untuk mendapatkan output dengan cara berikut:</p>
<ol>
<li>Menggunakan <code>for loop</code></li>
</ol>
<pre><code class="lang-python"><span class="hljs-keyword">for</span> info <span class="hljs-keyword">in</span> (jack, jenny):
    info.get_age()
    info.get_gender()
    info.get_address()
</code></pre>
<ol>
<li>atau; Menggunakan class atau function lain</li>
</ol>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Extract</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_info</span>(<span class="hljs-params">self, object_class</span>):</span>
        object_class.get_age()
        object_class.get_gender()
        object_class.get_address()

extract = Extract()
extract.get_info(jack)
extract.get_info(jenny)
</code></pre>
<p>Kedua dua cara di atas akan menghasilkan output yang sama.</p>
<pre><code class="lang-python">Output:

Age: <span class="hljs-number">19</span>
Gender: male
Address: USA
Age: <span class="hljs-number">21</span>
Gender: female
Address: Colombia
</code></pre>
<h2 id="heading-gabungan-konsep">Gabungan konsep</h2>
<p>Ketiga-tiga pendekatan diatas boleh digunakan secara bersendirian. Namun ini tidak bermakna kita tidak boleh menggabungkannya ataupun menggunakan satu pendekatan untuk mencipta pendekatan yang lain.</p>
<p>Contohnya:</p>
<blockquote>
<ol>
<li><p>Perwarisan dan Polimorfism boleh digunakan untuk mencipta class yang mampu untuk <em>overriding atribut dari Class sebelumnya.</em></p>
</li>
<li><p>Dalam pengkapsulan boleh ada sebuah perwarisan (antara subclass)</p>
</li>
</ol>
</blockquote>
<h1 id="heading-penutup">Penutup</h1>
<p>Bentuk-bentuk ini bergantung kepada kesesuaian keadaan dan bagaimana seorang pengaturcara untuk menyelesaikan masalah yang dihadapinya semasa membangunakan sesebuah kod.</p>
<p>Idea untuk menentukan pendekatan yang mana lebih baik tidak hadir dalam masa yang singkat. Pengalaman yang ditambah secara konsisten dalam pengaturcaraan dan kaedah cubajaya dapat membantu pengaturcara untuk menentukan konsep yang terbaik.</p>
<p>Sampai disini sahaja artikel kali ini. Jangan lupa untuk cipta Class anda selepas ini menggunakan konsep-konsep diatas. Jika terdapat kekeliruan ataupun persoalan atau penambahbaikan, penulis mengalu-alukan komen pembaca pada ruangan dibawah.</p>
<p>Sampai jumpa, salam!</p>
]]></content:encoded></item><item><title><![CDATA[Persekitaran Maya dalam Python]]></title><description><![CDATA[Pengenalan
Apabila kita menulis kod, kebanyakan masanya kita akan menggunakan pakej atau pustaka untuk tujuan tertentu. Misalnya meggunakan pakej Sklearn untuk mesin pembelajaran, Pandas untuk mengendalikan data dan juga pelbagai pakej lain yang ada....]]></description><link>https://mmarsaf.xyz/persekitaran-maya-dalam-python</link><guid isPermaLink="true">https://mmarsaf.xyz/persekitaran-maya-dalam-python</guid><category><![CDATA[virtual environment]]></category><category><![CDATA[Python]]></category><category><![CDATA[Python 3]]></category><category><![CDATA[python beginner]]></category><category><![CDATA[Data Science]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Sat, 30 Jul 2022 07:27:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1659165323494/VkFpnG9x8.jfif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-pengenalan">Pengenalan</h1>
<p>Apabila kita menulis kod, kebanyakan masanya kita akan menggunakan pakej atau pustaka untuk tujuan tertentu. Misalnya meggunakan pakej Sklearn untuk mesin pembelajaran, Pandas untuk mengendalikan data dan juga pelbagai pakej lain yang ada.</p>
<p>Untuk menggunakan pustaka ini, anda perlu muat turun ia terlebih dahulu. Pakej-pakej tadi akan disimpan terus ke dalam fail dimana pelaksana Python disimpan. Ini bermakna ia disimpan secara global. 🌎</p>
<p>Makna global disini adalah sistem yang menjadi panduan atau rujukan bagi keseluruhan komputer.</p>
<p>Namun, bagaimana jika projek yang kita sedang jalankan itu adalah sebuah projek yang menggunakan pakej yang mempunyai versi yang spesifik, sama ada yang lebih rendah (contoh Pandas 1.3.5) atau tinggi (Pandas 1.4.3) berbanding dengan apa yang telah kita muat turun tadi? </p>
<p>Apakah kita perlu menurunkan gred versi pakej itu semata-mata bagi memenuhi kehendak projek yang kita jalankan? Jika kita menurunkan gred pakej tersebut, bagaimana nanti jika kita ada projek yang menggunakan versi pakej yang lebih tinggi? Adakah kita perlu buang dan muat turun semula? 🤔</p>
<p>Masalah ini sebenarnya mampu diselesaikan dengan persekitaran maya (<em>virtual environment</em>). Dapat dilihat tanpa persekitaran maya, perjalanan projek kita akan menjadi kucar-kacir. Jadi, ayuh berkenalan dengan apa itu persekitaran maya.</p>
<h1 id="heading-persekitaran-maya">Persekitaran Maya</h1>
<p>Persekitaran maya adalah satu persekitaran terasing (berbentuk folder); dimana pelaksana Python, pustaka dan skrip berada di dalamnya. Dengan keberadaan folder ini, anda boleh melaksanakan projek tanpa bergantung dengan pelaksana dan fail luar.</p>
<p>Kata kunci penting disini adalah </p>
<blockquote>
<p>terasing.</p>
</blockquote>
<p>Bayangkan sebuah bekas kosong. Kita letakkan barang-barang di dalamnya. Maka Barang-barang tersebut telah berada dalam lingkungan bekas tersebut dan terhindar daripada perkara-perkara yang tidak diingini.</p>
<p><img src="https://cdn.pixabay.com/photo/2013/07/12/17/46/box-152428_960_720.png" alt="Bekas" /></p>
<p>Begitu juga persekitaran maya.</p>
<p>Persekitaran maya mencipta satu ruang terasing dimana fail Python tersebut hanya tertakluk apa yang ada dalam persekitaran ini sahaja. </p>
<p>Misalnya, jika terdapat Python versi 3.8 dalamnya, pelaksana itu yang digunakan untuk melaksanakan fail py dan bukan pelaksana Python global. Begitu juga dengan pakej dan pustaka. Segala pakej dan pustaka harus dimuat turun dalam persekitaran ini, dan dengan itu tidak menggunakan pakej yang dimuat turun secara global. Ini dapat membantu mengelakkan pencemaran global apabila segalanya tertakluk hanya dalam linkungan persekitaran.</p>
<p>Jadi bagaimana kita mahu mencipta persekitaran?</p>
<p>Mari kita mula mengekod! 👩‍💻</p>
<h2 id="heading-kod">Kod</h2>
<p>Pertama sekali anda perlu mengetahui asas baris perintah (<em>command line</em>) untuk menggunakan <em>Command Prompt</em> (CMD).</p>
<p>Baris perintahnya adalah: </p>
<ol>
<li><code>mkdir</code></li>
<li><code>cd</code></li>
<li><code>cd ..</code></li>
</ol>
<p>Ini asas yang harus diketahui oleh anda setakat ini. </p>
<p><code>mkdir</code> : mencipta folder (make directory)</p>
<p><code>cd</code>: menukar folder ke hadapan (forward change directory)</p>
<p><code>cd ..</code> : menukar folder ke belakang (backward change directory)</p>
<p>Sekarang, pergi ke skrin desktop anda dan cipta folder baru. Namakan folder itu sebagai <strong>projek_abc</strong>. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1659163667013/fzX3lzFGY.png" alt="Screenshot 2022-07-30 140037.png" /></p>
<p>Kemudian, buka CMD anda. Boleh cari menggunakan fungsi Search di Taskbar.</p>
<p>Pada CMD tersebut pastikan ia berada dalam laluan (<em>path</em>) D. Kebiasaanya Dekstop berada dalam pemacu D. Tapi ada juga yang berada dalam pemacu C (C <em>drive</em>). Anda perlu semak sendiri dimana Desktop anda tersimpan. </p>
<p>Untuk penulis, Desktop berada dalam pemacu D. Jadi penulis menulis <code>D:</code> supaya ia dapat menukar daripada pemacu C kepada pemacu D. </p>
<p>Selepas itu, beri arahan <code>cd Desktop</code> dan tekan <em>Enter</em>. CMD sekarang berada pada Desktop. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1659164033500/84R5cENac.png" alt="cd desktop.png" /></p>
<p>Kemudian beri arahan <code>cd projek_abc</code>. Sekarang CMD berada dalam folder projek_abc. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1659164091377/ouSk1o3d3.png" alt="cd projek_abc.png" /></p>
<p>Sekarang barulah kita boleh mencipta persekitran maya tadi. Cara untuk mencipta persekitaran ini adalah dengan baris perintah berikut</p>
<p><code>python -m venv venvMyproject</code></p>
<p><strong>venvMyproject</strong> adalah nama persekitaran maya anda. Anda boleh memilih apa-apa nama sepeti venvMain, venvProject mengikut apa yang anda inginkan. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1659164134386/l9hQt7Ave.png" alt="create venv.png" /></p>
<p>Setelah menekan <em>Enter</em>, anda akan lihat satu folder  akan muncul dalam folder projek_abc. Itu bermakna anda telah berjaya mencipta persekitaran tersebut. Terbaik! 🙌</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1659164183597/SIomrdDQQ.png" alt="click projek_abc.png" /></p>
<p>Jika anda tekan fail tersebut, anda dapat melihat beberapa fail di dalamnya termasuk Lib. Lib adalah fail untuk penyimpanan pakej atau pustaka yang anda telah muat turun di dalam persekitaran.</p>
<p>Dengan keberadaan folder Lib, boleh memuat turun apa apa pakej dalam persekitaran tanpa masuk campur atau menggangu pakej yang berada di luar persekitaran ini. 🤯</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1659164210437/me6zZHt99.png" alt="click venvmyProject.png" /></p>
<p>Sekarang, bagaimana kita ingin menggunakan persekitaran ini?</p>
<p>Mari kita pergi ke bahagian seterusnya. </p>
<h2 id="heading-penggunaan">Penggunaan</h2>
<h3 id="heading-muat-turun-pustaka-dalam-persekitaran-maya">Muat turun pustaka dalam persekitaran maya</h3>
<p>Pertama sekali, buka mana mana IDE kesukaan anda. Untuk permulaan, saya cadangkan IDE yang boleh <strong>menggunakan script*</strong> dan <strong>bukan notebook</strong>. Penulis menggunakan IDE Visual Code Studio atau VS Code.</p>
<p>Cipta satu fail py. Kemudian simpan fail tersebut dalam venvMyproject. Sekarang fail py anda telah berada dalam folder venvMyproject. Tetapi persekitaran ini tidak akan dipakai, melainkan setelah anda mengaktifkan persekitaran ini dahulu. </p>
<p>Cara untuk mengaktifkannya mudah sahaja. </p>
<p>Buka CMD dalam terminal VS Code (bahagian terminal). Pastikan CMD anda berada pada direktori venvMyproject. Kemudian tulis baris perintah di bawah;</p>
<p><code>venvMyproject\Scripts\activate.bat</code></p>
<p>Setelah anda menekan <em>Enter</em>, anda akan perhatikan pada hujung kiri CMD ada terpapar</p>
<p> <code>(venvMyproject)</code> yang membawa maksud persekitaran anda telah diaktifkan!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1659164283742/3Xq8wo-j-.png" alt="vccode.png" /></p>
<p>Apabila persekitaran anda telah diaktifkan, anda boleh mula memuat turun pustaka yang anda inginkan. Seperti biasa dengan arahan <code>pip install &lt;library&gt;</code>. </p>
<pre><code>Nota tambahan: Anda boleh memuat turun pustaka dengan versi spesifik.

Contohnya untuk Pandas versi <span class="hljs-number">1.3</span><span class="hljs-number">.5</span>. 

Apa yang dimaksudkan dengan <span class="hljs-number">1.3</span><span class="hljs-number">.5</span>?

<span class="hljs-number">1</span> <span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">&gt;</span> nombor merujuk kepada versi Major

<span class="hljs-number">3</span> <span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">&gt;</span> nombor merujuk kepada versi versi Minor

<span class="hljs-number">5</span> <span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">&gt;</span> nombor merujuk kepada versi versi Patch
</code></pre><h3 id="heading-run-fail-py-dalam-persekitaran-maya"><em>Run</em> fail py dalam persekitaran maya</h3>
<p>Selain perlu mengaktifkan untuk memuat turun pustaka, anda juga perlu mengaktifkan persekitaran maya ini dalam IDE anda supaya projek anda dapat dilaksanakan dalam persekitaran yang telah dicipta.</p>
<p>Dalam Visual Code Studio, caranya adalah dengan menekan versi Python pada bawah kanan skrin. Anda perlu mencari fail Python.exe dalam folder Scripts; yang berada di dalam folder venvMyproject. Jika telah diaktifkan, ia akan berubah kepada <strong>('vevMyproject':venv)</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1659164737122/qYjw6Pjyp.png" alt="vccode (2).png" /></p>
<p>Apabila persekitaran sudah aktif dalam IDE, barulah fail Python anda akan merujuk kepada komponen yang berada di dalam persekitaran venvMyproject.</p>
<h1 id="heading-penutup">Penutup</h1>
<p>Persekitaran maya adalah sebuah praktis yang sangat baik sebelum kita memulakan apa-apa projek. Antara kelebihannya adalah:</p>
<ol>
<li><p>Konfigurasi sistem terjaga daripada komponen-komponen global. </p>
</li>
<li><p>Mampu menaikkan atau menurunkan versi pakej tanpa memberi kesan pada pustaka global. </p>
</li>
<li><p>Boleh menyenaraikan versi pustaka yang digunakan, supaya jika ada orang lain yang ingin membantu projek ini dapat memuat turun versi pustaka yang sama yang digunakan.</p>
</li>
</ol>
<p>Penulis berharap artikel ini bermanfaat untuk anda dalam meningkatkan pengetahuan dalam bidang pengaturcaraan. Setakat ini sahaja artikel untuk kali ini. Jika anda ada punya soalan, cadangan, atau komen, boleh kemukakan dibahagian bawah. 😎</p>
<p>Salam jumpa, ciao! 👋</p>
]]></content:encoded></item><item><title><![CDATA[Kecerdasan Buatan: Batu Loncatan Kemajuan]]></title><description><![CDATA[Pengenalan
Kemajuan kecerdasan buatan saban hari meningkat secara eksponen. Lebih ramai pakar  mahupun orang awam yang telah melibatkan diri dalam menyumbang kepada teknologi kecerdasan buatan yang menjadikan kadar kemajuannya semakin pantas. 
Namun,...]]></description><link>https://mmarsaf.xyz/kecerdasan-buatan-batu-loncatan-kemajuan</link><guid isPermaLink="true">https://mmarsaf.xyz/kecerdasan-buatan-batu-loncatan-kemajuan</guid><category><![CDATA[Artificial Intelligence]]></category><category><![CDATA[Machine Learning]]></category><category><![CDATA[Python 3]]></category><category><![CDATA[python beginner]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Sat, 04 Jun 2022 02:37:05 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/2EJCSULRwC8/upload/v1654304467211/zDHvWtmPV.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-pengenalan">Pengenalan</h1>
<p>Kemajuan kecerdasan buatan saban hari meningkat secara eksponen. Lebih ramai pakar  mahupun orang awam yang telah melibatkan diri dalam menyumbang kepada teknologi kecerdasan buatan yang menjadikan kadar kemajuannya semakin pantas. </p>
<p>Namun, sayang sekali kesedaran mengenai kecerdasan buatan tidaklah terlalu menggalakkan dalam negara ini. Jarang sekali kita berborak soal ini seperti mana kita berborak isu-isu Sains yang lain seperti Fizik (yang masyhur seperti lubang hitam, teori relativiti dan Fizik kuantum), Sains politik (yang seharusnya menjadi topik hangat), bola sepak dan lain-lain lagi. </p>
<p>Kecerdasan buatan belum kelihatan lagi seksi di mata kita. 😶</p>
<p>Tetapi, tahukah anda, pada hari ini, kecerdasan buatan sudah memeluk pelbagai bidang? Ini termasuklah ekonomi, Sains, sejarah, politik, mata wang dan pelbagai lagi. Anda pasti tertanya-tanya, bagaimana kecerdasan buatan menyumbang 'kepintarannya' dalam semua bidang ini. </p>
<p>Ayuh kita bedah satu persatu!</p>
<h1 id="heading-sejarah">Sejarah</h1>
<p>Ilmu statistik adalah sebuah ilmu yang sudah bermula sejak sekian lamanya. Dikatakan, ia telah bermula dari abad ke 17 lagi. Namun pada masa itu, penggunaanya tidak meluas seperti hari ini. Cabang ini berkembang maju apabila memasuki abad ke 19, apabila ia mula digunakan dalam bidang ekonomi dan pengiraan populasi, disebabkan kemampuannya dalam menganalisis. </p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/84/Sir_William_Petty.jpg/300px-Sir_William_Petty.jpg" alt class="image--center mx-auto" /></p>
<blockquote>
<p>William Petty seorang ahli ekonomi yang menggunakan statistik untuk menganalisis data demografik.</p>
</blockquote>
<p>Mungkin, anda pernah merasakan mempelajari Statistik di sekolah adalah sesuatu yang tidak berguna. Mengapa kita harus mengira mod, median dan julat? Mengapa kita harus membuat graf itu dan ini? Mengapa kita mengetahui jenis-jenis taburan?</p>
<p>Namun sebenarnya, ilmu Statistiklah yang menjadi batu asas kepada pembinaan  teknologi pada tahap yang seterusnya iaitu kecerdasan buatan. </p>
<p>Apa itu kecerdasan buatan?</p>
<h1 id="heading-kecerdasan-buatan">Kecerdasan Buatan</h1>
<p>Kecerdasan buatan adalah sebuah algoritma (susunan kod-kod yang memberi makna sesuatu) yang mempunyai kemampuan untuk melakukan sesuatu yang mampu dilakukan manusia sejagat seperti berfikir dan mengenalisis, melihat dan membaca. </p>
<p>Ha? </p>
<p><img src="https://c.tenor.com/sI36VHyzYeAAAAAC/wtf-what.gif" alt class="image--center mx-auto" /></p>
<p>Ya, kecerdasan buatan mampu untuk melakukan semua ini, menggunakan dasar ilmu pengetahuan yang saya telah sebutkan tadi iaitu Statistik. </p>
<p>Bagaimana kecerdasan buatan mampu berfikir dan menganalisis?</p>
<p>Mari kita bedah dengan lebih lanjut. </p>
<h2 id="heading-berfikir-dan-menganalisis">Berfikir dan menganalisis</h2>
<p>Manusia cenderung untuk melihat corak (<strong>pattern</strong>) apabila melihat sesuatu perkara. Kadangkala bila kita melihat awan, secara tiba-tiba kita merasakan awan itu berbentuk beruang yang sedang memeluk bantal. </p>
<p><img src="https://i.pinimg.com/originals/aa/96/97/aa9697a3f7a61389675b8dc109518753.gif" alt="image.png" class="image--center mx-auto" /></p>
<p><img src="https://i.imgflip.com/5ynwf5.gif" alt="image.png" class="image--center mx-auto" /></p>
<p>Ataupun pada setiap minggu, kita mampu mengagak keputusan perlawanan pasukan Manchester United berdasarkan keputusan permainan mereka daripada permainan sebelum ini. </p>
<blockquote>
<p>Inilah yang dipanggil sebagai <strong>corak</strong>. </p>
</blockquote>
<p>Daripada pemerhatian kita terhadap corak-corak ini, kita akan mula menyambung titik-titik tersebut bagi menatijahkan konklusi akhir. </p>
<p>Dalam kecerdasan buatan, terdapat sebuah teknologi yang dikenali sebagai mesin pembelajaran; yang mengaplikasikan pola fikir analisis ini. Bezanya, pola pemikiran ini mempunyai disiplinnya yang tersendiri supaya konklusi yang dicipta pada akhirnya nanti menepati objektif yang telah ditapkan. </p>
<h2 id="heading-model">Model</h2>
<p>Mari kita lihat satu contoh bagaimana mesin pembelajaran mampu melakukan semua ini. Terdapat sejenis mesin pembelajaran yang menggunakan asas statistik dan salah satunya dikenali sebagai <em>model regresi</em> (<em>regression model</em>). </p>
<p>Model regresi adalah sebuah model yang mampu melihat keterkaitan antara satu ciri pemboleh ubah bersandar dengan satu ciri akibat daripada pemboleh ubah tersebut. Model ini menggunakan garisan lurus sebagai panduan kepada corak data tersebut. </p>
<p>Contoh eksperimen mudah adalah melihat sama ada berat tikus dan saiz matanya adalah berkadar langsung dengan tinggi tikus. </p>
<p><img src="https://c.tenor.com/LJ2LWBtL6wUAAAAC/dancing-mice-dancing-mouse.gif" alt class="image--center mx-auto" /></p>
<p>Kemudian, mari kita bina satu algoritma mesin pembelajaran model regresi. Model ditulis dengan menggunakan bahasa pengaturcaraan Python. </p>
<p>Berikut contoh kod;</p>
<pre><code><span class="hljs-string">from</span> <span class="hljs-string">sklearn.linear_model</span> <span class="hljs-string">import</span> <span class="hljs-string">LinearRegression</span>

<span class="hljs-string">berat_dan_saiz_mata</span> <span class="hljs-string">=</span> [[<span class="hljs-number">1</span>, <span class="hljs-number">3</span>], [<span class="hljs-number">4</span>, <span class="hljs-number">5</span>], [<span class="hljs-number">6</span>, <span class="hljs-number">10</span>]] 
<span class="hljs-string">tinggi</span> <span class="hljs-string">=</span> [<span class="hljs-number">1</span>,<span class="hljs-number">6</span>,<span class="hljs-number">8</span>] 

<span class="hljs-string">reg</span> <span class="hljs-string">=</span> <span class="hljs-string">LinearRegression()</span>

<span class="hljs-string">reg.fit(berat_dan_saiz_mata,</span> <span class="hljs-string">tinggi)</span>

<span class="hljs-string">x_new</span> <span class="hljs-string">=</span> [[<span class="hljs-number">1</span>, <span class="hljs-number">4</span>], [<span class="hljs-number">4</span>, <span class="hljs-number">2</span>], [<span class="hljs-number">6</span>, <span class="hljs-number">11</span>]]
<span class="hljs-string">y_pred</span> <span class="hljs-string">=</span> <span class="hljs-string">reg.predict(x_new)</span>

<span class="hljs-string">print(y_pred)</span>
</code></pre><p>Output:</p>
<pre><code>[<span class="hljs-number">0.63636364</span> <span class="hljs-number">7.09090909</span> <span class="hljs-number">7.63636364</span>]
</code></pre><h3 id="heading-penerangan-kod">Penerangan kod</h3>
<h4 id="heading-ciri-x">- Ciri-X</h4>
<p>Ciri  x merujuk kepada data yang digunakan untuk meramal ciri sasaran iaitu ciri y. Dalam hal ini diwakili berat dan saiz mata seekor tikus. Dengan menggunakan 3 ekor tikus, kita telah merekod berat dan saiz mata mereka, untuk digunakan sebagai data kepada model mesin. </p>
<h4 id="heading-ciri-y">- Ciri-y</h4>
<p>Data y pula merujuk kepada nilai sasaran yang kita tentukan untuk diramal. Dalam hal ini, diwakili oleh tinggi tikus tersebut. Data ini juga diberikan pada model mesin supaya 'beliau' mampu mengenalpasti corak daripada data ini, menggunakan 'pola fikir' model ini iaitu regresi. </p>
<h4 id="heading-modelfitx-y">- model.fit(X, y)</h4>
<p>Kita akan menggunakan metod <code>fit</code> untuk mengarahkan mode yang telah kita pilih untuk mempelajari data.</p>
<h4 id="heading-modelpredictdatabaru">- model.predict(data_baru)</h4>
<p>Menggunakan metod <code>predict</code>, kita boleh meramal tinggi tikus tikus lain dengan menyediakan data berat dan saiz mata tikus yang baharu hanya dengan kod semudah ini! 😎</p>
<h4 id="heading-output">- Output</h4>
<p>Output yang telah dihasilkan adalah nilai ramalan tinggi tikus setelah kita memasukkan data baharu.</p>
<p>Jadi, bayangkan jika anda sedang membuat satu ekperimen yang kompleks berskala besar. </p>
<p><img src="https://media1.giphy.com/media/AQ2tIhLp4cBa/giphy.gif" alt class="image--center mx-auto" /></p>
<p>Data anda adalah bersandar kepada data yang satu lagi. Maka, dengan menyediakan data anda yang lengkap, anda dengan mudah dapat meramal output yang baharu dengan mengaplikasikan model mesin pembelajaran ini! (kod di atas adalah eksperimen mudah, terdapat pelbagai lagi perkara lain yang harus  ditimbang tara).</p>
<p>Sheeessh! 🤯</p>
<h2 id="heading-melihat">Melihat</h2>
<p>Pada hari ini, mesin pembelajaran sudah sampai kesebuah tahap mereka mampu 'melihat' seperti manusia. Teknologi ini dipanggil sebagai Pengesanan Karakter secara Optikal. </p>
<p>Melalui teknologi ini, mesin akan 'melihat' sesebuah objek dan mengekstrak info yang berguna seperti nama, umur, dan sebagainya. Sebagai contoh, jika kita memberikan salinan kad pengenalan kita kepada mesin, mesin akan mengetahui dimanakah posisi nama, alamat, agama, dan gambar kad pengenalan! 😮</p>
<p><img src="https://media.istockphoto.com/vectors/fingerprint-identification-concept-polygonal-vector-illustration-of-vector-id1338393625?k=20&amp;m=1338393625&amp;s=612x612&amp;w=0&amp;h=oZr3BT1txPN3SX0zj-VEfHQf4vbWYUor7Q8wcGKJZdQ=" alt class="image--center mx-auto" /></p>
<p>Bayangkan kerja harian manusia akan menjadi bertambah mudah jika kita dapat mengaplikasikan dan mengembangkan teknologi ini. </p>
<h2 id="heading-membaca">Membaca</h2>
<p>Selain itu, terdapat juga mesin yang dipanggil sebagai Pemprosesan Bahasa Alami (PBA) atau lebih biasa dikenali sebagai <em>Natural Language Processing (NLP)</em>. </p>
<p>NLP mempunyai fungsi untuk mengesan makna disebalik struktur ayat percakapan seharian kita. Contohnya, sebagai manusia, kita semestinya faham jika seseorang berkata, </p>
<p><img src="https://media0.giphy.com/media/oH9EpHYhOtlIZipqpk/giphy.gif" alt class="image--center mx-auto" /></p>
<ol>
<li><p>"Saya sangat gembira dengan pencapaian kamu."</p>
</li>
<li><p>"Saya sudah tak mampu untuk melihat gambarnya lagi."</p>
</li>
<li><p>"Saya sayang kerajaan saya, kerana ia bebas daripada rasuah."</p>
</li>
</ol>
<p>Frasa pertama menunjukkan frasa yang gembira. Frasa kedua menunjukkan perasaan yang sedih. Frasa ketiga lebih kepada sarkastik, skeptik dan tidak percaya. </p>
<p>Sebagai manusia, umumnya kita akan memahami konteks sesebuah ayat itu berdasarkan pengalaman kita berkomunikasi dalam seharian.</p>
<p>Tetapi, bagaiamana mesin pembelajaran memahami semua ini? Mereka menggunakan alat yang dipanggil sebagai Alatan Bahasa Alami atau lebih biasa dikenali sebagai <em>Natural Language Toolkits</em> atau <em>NLTK</em>. </p>
<p>Menggunakan NLTK, alat ini mampu memecah-beraikan frasa ayat, mengesan perkataan yang berulang, mencari perkataan akar (untuk perkataan berimbuhan) dan lain-lain lagi. </p>
<p>Daripada itu, kita boleh meramal konteks frasa ini dengan menggunakan mesin pembelajaran klasik, dengan cara kita melatih data (dipanggil sebagai korpus). Menggunakan korpus, mesin dapat mempelajari, apakah yang dimaksudkan dengan gembira, apakah yang dimaksudkan dengan sedih, apakah yang dimaksudkan dengan sarkastik, dan lain-lain lagi. </p>
<h1 id="heading-kesimpulan">Kesimpulan</h1>
<p>Begitulah antara contoh mesin pembelajaran yang menjadi komponen kecerdasan buatan pada hari ini.  Cool kan? 😛</p>
<p><img src="https://media2.giphy.com/media/xTiTngBQncyTMceuXK/giphy.gif" alt class="image--center mx-auto" /></p>
<p>Terdapat banyak lagi model atau mesin pembelajaran yang wujud, namun tidak muat jika ingin dihimpunkan ke dalam satu artikel. Tetapi jangan risau, waktu demi waktu, saya akan cuba memilih model mesin pembelajaran untuk dikupas secara konseptual untuk artikel seterusnya. </p>
<p>Jika anda punya apa-apa komen,  pembetulan, soalan atau cadangan, jangan malu atau segan untuk terus menulisnya dibahagian komen. Sampai disini sahaja artikel kali ini.</p>
<p>Selamat berhujung minggu, dan selamat berkoding! 💻</p>
<p>Anneyong! 👋</p>
]]></content:encoded></item><item><title><![CDATA[PEP8: Amalan Penulisan dalam Python]]></title><description><![CDATA[Pengenalan
Menulis adalah sebuah seni. Menulis esei, pantun, sajak, puisi, gurindam dan sebagainya adalah sebuah seni yang indah. Seni tidak terbatas dalam ruang lingkup atau peraturan yang ketat tetapi, ada di antaranya yang mempunyai aturan dan dis...]]></description><link>https://mmarsaf.xyz/pep8-amalan-penulisan-dalam-python</link><guid isPermaLink="true">https://mmarsaf.xyz/pep8-amalan-penulisan-dalam-python</guid><category><![CDATA[Python]]></category><category><![CDATA[Python 3]]></category><category><![CDATA[python beginner]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[programmer]]></category><dc:creator><![CDATA[Ammar]]></dc:creator><pubDate>Tue, 12 Apr 2022 03:31:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/mfB1B1s4sMc/upload/v1649733195610/kbIjPEY6N.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-pengenalan">Pengenalan</h1>
<p>Menulis adalah sebuah seni. Menulis esei, pantun, sajak, puisi, gurindam dan sebagainya adalah sebuah seni yang indah. Seni tidak terbatas dalam ruang lingkup atau peraturan yang ketat tetapi, ada di antaranya yang mempunyai aturan dan disiplin tersendiri. </p>
<p>Pantun harus mempunyai rima, sajak dan puisi lebih bebas penulisannya, dan pelbagai lagi peraturan dalam mencipta seni penulisan.</p>
<p>Seperti juga Python, bahasa pengaturcaraan ini juga mempunyai amalan ataupun praktis yang terbaik dalam menulis kod. </p>
<p>Salah seorang jurutera perisian yang juga merangkap perintis Python, Tim Peters telah menulis 20 prinsip Python berbentuk pujangga.  Ia telah dikenali sebagai <strong>Zen of Python</strong> (nama formalnya ialah PEP20).</p>
<h3 id="heading-zen-of-python"><em>Zen of Python</em></h3>
<blockquote>
<p>Beautiful is better than ugly. </p>
<p>Explicit is better than implicit.</p>
<p>Simple is better than complex.</p>
<p>Complex is better than complicated.</p>
<p>Flat is better than nested.</p>
<p>Sparse is better than dense.</p>
<p>Readability counts.</p>
<p>Special cases aren't special enough to break the rules.</p>
<p>Although practicality beats purity.</p>
<p>Errors should never pass silently.</p>
<p>Unless explicitly silenced.</p>
<p>In the face of ambiguity, refuse the temptation to guess.</p>
<p>There should be one-- and preferably only one --obvious way to do it.</p>
<p>Although that way may not be obvious at first unless you're Dutch.</p>
<p>Now is better than never.</p>
<p>Although never is often better than <em>right</em> now.</p>
<p>If the implementation is hard to explain, it's a bad idea.</p>
<p>If the implementation is easy to explain, it may be a good idea.</p>
<p>Namespaces are one honking great idea -- let's do more of those!</p>
</blockquote>
<p>Daripada Zen of Python ini barulah muncul PEP8, sebuah dokumentasi Python yang menerangkan panduan gaya penulisan Python yang disarankan oleh penemu bahasa pengaturcaraan ini, Guido Von Rossum. </p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/e/e2/Guido-portrait-2014-drc.jpg" alt="Guido Von Rossum" /></p>
<p>Guido berkata, </p>
<blockquote>
<p>Dalam kebanyakan masa, kita lebih banyak membaca kod daripada menulis kod.</p>
</blockquote>
<p>Justeru itu, kod seharusnya mempunyai ciri kebolehbacaan. Selaras dengan salah satu Zen dalam Zen of Python ;- </p>
<p><code>Readability counts.</code></p>
<p>Jadi, bagaimana kita boleh menulis kod Python dengan gaya penulisan yang menepati ciri kebolehbacaan sekaligus menulis kod dengan lebih baik?</p>
<p>Berikut saya sertakan 5 amalan yang disarankan kepada pengaturcara Python untuk dipraktik daripada dokumen PEP8. </p>
<p>(nota: Penulis mengandaikan pembaca sudah mempunyai sedikit asas Python sebelum membaca artikel ini.)</p>
<h2 id="heading-1-menggunakan-perenggan-untuk-membezakan-sesuatu">1.  Menggunakan perenggan untuk membezakan sesuatu.</h2>
<p>Perenggan adalah antara identiti utama Python. Perenggan digunakan dalam penyata bersyarat, fungsi,<em>class</em> dan lingkaran. </p>
<p>Oleh sebab itu, PEP8 telah menyelaraskan beberapa cara yang terbaik bagi menggunakan perenggan. Misalnya, jika kita menulis sebuah fungsi yang mempunyai beberapa argumen di dalamnya, cara yang baik ✅ adalah seperti berikut; </p>
<pre><code><span class="hljs-attribute">my_func</span> = nama_fungsi_panjang(arg_<span class="hljs-number">1</span>, arg_<span class="hljs-number">2</span>, 
                              <span class="hljs-attribute">arg_3</span>, arg_<span class="hljs-number">4</span>)
</code></pre><p>Ini adalah cara menggunakan perenggan supaya kod kelihatan kemas dan mudah untuk dibezakan antara fungsi dan argumen. Cara penulisan yang kurang baik ❌adalah seperti berikut;</p>
<pre><code><span class="hljs-attribute">my_func</span> = nama_fungsi_panjang(arg_<span class="hljs-number">1</span>, arg_<span class="hljs-number">2</span>, 
          <span class="hljs-attribute">arg_3</span>, arg_<span class="hljs-number">4</span>)
</code></pre><p>Ini juga boleh digunakan untuk  menulis <em>list</em> atau <em>dictionary</em> seperti contoh berikut;</p>
<pre><code><span class="hljs-string">my_list</span> <span class="hljs-string">=</span> [
           <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, 
           <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, 
           <span class="hljs-number">7</span>, <span class="hljs-number">8</span>, <span class="hljs-number">9</span>
    ]

<span class="hljs-string">my_dictionary</span> <span class="hljs-string">=</span> { 
                  <span class="hljs-attr">1:</span> <span class="hljs-string">"Isnin"</span>, 
                  <span class="hljs-attr">2:</span> <span class="hljs-string">"Selasa"</span>,
                  <span class="hljs-attr">3:</span> <span class="hljs-string">"Rabu
        }</span>
</code></pre><p>Elemen di dalam <em>list</em> dapat dilihat dengan jelas dan tersusun.</p>
<p>Menulis dengan menggunakan perenggan dengan betul dapat memudahkan pembaca (pengaturcara) untuk membaca kod, lebih-lebih lagi  jika kita ingin membaca kod yang ditulis oleh orang lain dan sebaliknya.</p>
<h2 id="heading-2-maksimum-character-untuk-satu-barisan">2. Maksimum <em>character</em>  untuk satu barisan.</h2>
<p>Bagi mengelakkan kod ditulis terlalu panjang, PEP8 telah menghadkan supaya maksimum karakter  yang ditulis untuk satu barisan iaitu <strong>79 karakter</strong>.</p>
<p>Anda tak perlulah mengira satu persatu huruf pada kod, tetapi anda boleh agak-agak panjang kod anda dalam sebaris itu supaya tidak terlalu panjang dan meleweh-leweh. Jika kod anda mempunya koma, sambung ke barisan yang seterusnya.</p>
<p>Selain daripada memudahkan tujuan pembacaan, ini juga membantu pengaturcara yang ingin membuka dua buah skrip kod sekaligus bersebelahan membaca kod kedua-dua skrip.</p>
<h2 id="heading-3-menggunkan-satu-jenis-pembuka-kata">3. Menggunkan satu jenis pembuka kata.</h2>
<p>Jika anda perhatikan di papan kekunci, terdapat dua jenis pembuka kata iaitu pembuka kata jenis tunggal <code>' '</code> dan jenis ganda <code>" "</code>. </p>
<p>PEP8 menyarankan pengaturcara untuk membiasakan diri dengan menggunakan salah satu sahaja antara dua jenis pembuka kata ini, bagi menjamin konsistensi penulisan kod</p>
<p>Konsistensi akan menjadikan kod lebih kemas dan tidak bercampur baur. </p>
<h2 id="heading-4-pemilihan-dan-gaya-penulisan-nama">4. Pemilihan dan gaya penulisan nama.</h2>
<p>Pilih nama yang mempunyai kaitan dengan isi kandungan fungsi, pemboleh  ubah atau <em>class</em> tersebut. Ini bagi memudahkan anda untuk merujuk semula kod tersebut sama ada untuk menyerunya ke dalam fungsi atau mengoutputkannya.</p>
<p>Contoh yang baik ✅</p>
<pre><code><span class="hljs-string">senarai_nom</span> <span class="hljs-string">=</span> [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>,<span class="hljs-number">6</span>]

<span class="hljs-string">def</span> <span class="hljs-string">filter_func(num):</span>
      <span class="hljs-attr">for val in num:</span>
          <span class="hljs-string">if</span> <span class="hljs-string">val</span> <span class="hljs-string">&lt;</span> <span class="hljs-attr">3:</span>
                <span class="hljs-string">print("Nilai</span> <span class="hljs-string">lebih</span> <span class="hljs-string">rendah</span> <span class="hljs-string">daripada</span> <span class="hljs-number">3</span><span class="hljs-string">.")</span>
          <span class="hljs-attr">else:</span>
                <span class="hljs-string">print("Nilai</span> <span class="hljs-string">lebih</span> <span class="hljs-string">tinggi</span> <span class="hljs-string">daripada</span> <span class="hljs-number">3</span><span class="hljs-string">.")</span>
</code></pre><p>Contoh yang kurang baik ❌</p>
<pre><code><span class="hljs-string">a</span> <span class="hljs-string">=</span> [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>,<span class="hljs-number">6</span>]

<span class="hljs-string">def</span> <span class="hljs-string">my_func(x):</span>
      <span class="hljs-attr">for i in x:</span>
          <span class="hljs-string">if</span> <span class="hljs-string">i</span> <span class="hljs-string">&lt;</span> <span class="hljs-attr">3:</span>
                <span class="hljs-string">print("Nilai</span> <span class="hljs-string">lebih</span> <span class="hljs-string">rendah</span> <span class="hljs-string">daripada</span> <span class="hljs-number">3</span><span class="hljs-string">.")</span>
          <span class="hljs-attr">else:</span>
                <span class="hljs-string">print("Nilai</span> <span class="hljs-string">lebih</span> <span class="hljs-string">tinggi</span> <span class="hljs-string">daripada</span> <span class="hljs-number">3</span><span class="hljs-string">.")</span>
</code></pre><p>Kedua-dua kod di atas mempunyai tujuan yang sama, tetapi pemilihan nama yang berbeza. Kod yang pertama lebih jelas dan mudah dibaca kerana pemilihan nama yang mempunyai kaitan, manakala kod kedua hanya menggunakan huruf sahaja yang jelas tidak menerangkan konteks kod.</p>
<p>Gaya penulisan nama juga mempunyai cara yang tersendiri. Jika ingin menulis fungsi atau pemboleh ubah, nama fungsi seharusnya berhuruf kecil, dengan nama yang disambung menggunakan <em>underscore</em> bagi meningkatkan kebolehbacaan. </p>
<p>Contoh yang baik ✅</p>
<pre><code><span class="hljs-comment"># dengan underscore</span>
senarai_nom_ganjil = [<span class="hljs-number">1</span>,<span class="hljs-number">3</span>,<span class="hljs-number">5</span>]
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">fungsi_nombor</span>(<span class="hljs-params">senarai</span>):</span>
        print(senarai)

fungsi_nombor(senarai_nombor_ganjil)
</code></pre><p>Contoh kurang baik ❌</p>
<pre><code><span class="hljs-comment"># tanpa underscore</span>
senarainomganjil = [<span class="hljs-number">1</span>,<span class="hljs-number">3</span>,<span class="hljs-number">5</span>]
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">fungsinombor</span>(<span class="hljs-params">senarai</span>):</span>
        print(senarai)

fungsinombor(senarainomborganjil)
</code></pre><p>Anda boleh menilai sendiri penggunaan nama yang mana satu yang sedap mata memandang dan mudah dibaca.</p>
<p>Antara cadangan gaya penulisan lain adalah;</p>
<ul>
<li>nama pemboleh ubah malar -&gt; SEMUA HURUF BESAR</li>
</ul>
<p>Contoh:</p>
<pre><code><span class="hljs-attr">PI_VALUE</span> = <span class="hljs-number">3.14159</span>
<span class="hljs-attr">BETA_VALUE</span> = <span class="hljs-number">12</span>
</code></pre><ul>
<li>nama <em>class</em> -&gt; Huruf Besar Di Awal Setiap Nama</li>
</ul>
<p>Contoh:</p>
<pre><code>class MyDog:
       def __init__(<span class="hljs-built_in">self</span>, name, age):
              <span class="hljs-built_in">self</span>.<span class="hljs-built_in">name</span> <span class="hljs-operator">=</span> name
              <span class="hljs-built_in">self</span>.age <span class="hljs-operator">=</span> age
</code></pre><h2 id="heading-5-cara-menulis-komen">5. Cara menulis komen.</h2>
<p>Seperti yang telah dibincangkan dalam artikel sebelum ini, terdapat 2 cara untuk kita menulis komen di dalam kod, iaitu </p>
<ol>
<li>Menggunakan tanda pagar, # </li>
<li>3 pembuka dan penutup kata (atau dikenali sebagai <em>docstring</em> jika tidak disabitkan pada mana-mana fungsi)</li>
</ol>
<p>Menulis komen juga terdapat 2 cara penulisan iaitu,</p>
<ul>
<li>Secara blok</li>
<li>Secara didalam satu barisan yang sama. </li>
</ul>
<p>Cara blok adalah seperti berikut;</p>
<pre><code><span class="hljs-comment">#semak sama ada harga melebih atau tidak</span>
<span class="hljs-attribute">harga_ikan</span> = <span class="hljs-number">10</span>
<span class="hljs-attribute">if</span> harga_ikan &gt; <span class="hljs-number">10</span>:
       <span class="hljs-attribute">print</span>(<span class="hljs-string">"Harga terlalu mahal"</span>)
</code></pre><p>Cara menulis dalam satu barisan;</p>
<pre><code>harga_ikan = <span class="hljs-number">10</span>           <span class="hljs-comment">#semak sama ada harga melebih atau tidak</span>
<span class="hljs-keyword">if</span> harga_ikan &gt; <span class="hljs-number">10</span>:
       print(<span class="hljs-string">"Harga terlalu mahal"</span>)
</code></pre><p>Disarankan untuk diperenggankan dengan beberapa <em>tab</em> sebelum menulis komen bagi cara menulis komen atas barisan yang sama.</p>
<p>Bagi menggunakan 3 pembuka dan penutup kata bagi tujuan komen atau <em>docstring</em> pula, jika komen tersebut hanya mempunyai satu barisan, maka pembuka dan penutup kata adalah di atas barisan yang sama dengan karakter. </p>
<p>Contoh;</p>
<pre><code><span class="hljs-string">'''Ini adalah nota kecil tentang kod berikut.'''</span>
</code></pre><p>Tetapi, jika komen terdiri daripada beberapa barisan, hanya pembuka sahaja di atas barisan yang sama pada barisan pertama, tetapi penutup kata harus berada satu barisan dibawah barisan terakhir. </p>
<p>Contoh;</p>
<pre><code><span class="hljs-string">'''Fungsi ini berkenaan sebuah operasi matematik.

Fungsi ini masih belum lengkap.
'''</span>
</code></pre><h1 id="heading-kesimpulan">Kesimpulan</h1>
<p>Begitulah sedikit sebanyak rumusan daripada PEP8 yang harus anda tahu. </p>
<p>Mulakan menulis kod dengan disiplin yang betul adalah sebuah tabiat yang baik daripada mebiasakan diri dengan penulisan yang kurang baik.</p>
<p>Namun, jika anda sudah berpengalaman dalam Python dan terdapat beberapa cara penulisan anda yang bercanggah dengan PEP8, maka masih punya masa untuk memperbetulkannya dan menulis kod Python dengan lebih kemas dan menarik.</p>
<p>Anda boleh baca dengan lebih lanjut lagi pada pautan yang saya telah sertakan dibawah pada bahagian sumber.</p>
<p>Sampai disini sahaja artikel kali ini. Saya berharap artikel ini bermanfaat untuk para pembaca sekalian. Sampai jumpa lagi, salam! 👋</p>
<p>Sumber:</p>
<ol>
<li>PEP20: https://peps.python.org/pep-0020/</li>
<li>PEP8: https://peps.python.org/pep-0008/</li>
<li>PEP257: https://peps.python.org/pep-0257/</li>
</ol>
]]></content:encoded></item></channel></rss>