<?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" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Eincode - Medium]]></title>
        <description><![CDATA[High-quality content and programming concepts explained on real-life projects are fields where Eincode shines! - Medium]]></description>
        <link>https://medium.com/eincode?source=rss----96930c935cba---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Eincode - Medium</title>
            <link>https://medium.com/eincode?source=rss----96930c935cba---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 24 May 2026 02:28:09 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/eincode" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Exploring Sui and Its Most Exciting Projects for Developers]]></title>
            <link>https://medium.com/eincode/exploring-sui-and-its-most-exciting-protocols-for-developers-8d1427fe1504?source=rss----96930c935cba---4</link>
            <guid isPermaLink="false">https://medium.com/p/8d1427fe1504</guid>
            <category><![CDATA[dapps]]></category>
            <category><![CDATA[web3]]></category>
            <category><![CDATA[blockchain]]></category>
            <category><![CDATA[sui]]></category>
            <category><![CDATA[move]]></category>
            <dc:creator><![CDATA[Filip Jerga]]></dc:creator>
            <pubDate>Wed, 19 Feb 2025 15:20:25 GMT</pubDate>
            <atom:updated>2025-02-19T18:23:31.723Z</atom:updated>
            <content:encoded><![CDATA[<h4>Unleashing Innovation: Exploring Sui’s High-Performance Blockchain and Its Most Exciting Developer-Focused Projects</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5_iD7nG7zeTiNAsJJYw6jg.jpeg" /></figure><p>The Sui blockchain is redefining the standards of decentralized application development with its high scalability, low latency, and developer-friendly ecosystem. Built by Mysten Labs, Sui leverages a Directed Acyclic Graph (DAG)-based consensus mechanism that enables parallel transaction execution, making it one of the fastest and most efficient Layer 1 blockchains available.</p><h3>Why Developers Choose Sui</h3><p>Sui’s architecture is designed to overcome the limitations of traditional blockchains, such as congestion and high fees. Its ability to process independent transactions simultaneously ensures unmatched throughput and cost efficiency. For developers, Sui offers a fertile ground for building innovative decentralized applications (dApps) with minimal friction.</p><h3>Resources</h3><p><em>If you want to learn Move and Sui in-depth, check out my full course on building real projects with Move and React: </em><a href="https://academy.eincode.com/courses/sui-dapps-with-move-react-build-real-projects"><strong><em>academy.eincode.com</em></strong></a><strong><em>.</em></strong></p><h3>Key Strengths of Sui:</h3><ul><li><strong>Scalability</strong>: Horizontal scaling allows the network to handle increasing workloads seamlessly.</li><li><strong>Low Latency</strong>: Transactions achieve sub-second finality, ideal for high-performance applications.</li><li><strong>Developer-Friendly Tools</strong>: A robust set of APIs and frameworks simplifies the dApp development process.</li></ul><h3>Move Programming Language: A Developer’s Ally</h3><p>At the core of Sui’s developer ecosystem is the Move programming language. Designed specifically for blockchain use cases, Move emphasizes security and flexibility, making it an ideal choice for building smart contracts.</p><h3>Why Move Stands Out:</h3><ul><li><strong>Resource-Oriented Design</strong>: Prevents common vulnerabilities like reentrancy attacks by treating assets as resources that cannot be duplicated or destroyed.</li><li><strong>Customizability</strong>: Allows developers to create tailored assets and logic for their applications.</li><li><strong>Efficiency</strong>: Lightweight and optimized for Sui’s high-speed infrastructure.</li></ul><p>Move not only enhances security but also reduces complexity in building robust dApps, making it a favorite among developers.</p><h3>Top Protocols on Sui That Developers Should Know</h3><p>Sui’s ecosystem is rapidly expanding with innovative protocols that leverage its technical strengths. Here are some standout projects that offer exciting opportunities for developers:</p><h3>1. DeepBook Protocol</h3><p><a href="https://docs.sui.io/standards/deepbook">https://docs.sui.io/standards/deepbook</a></p><p>DeepBook is a decentralized Central Limit Order Book (CLOB) designed to provide efficient and transparent trading on the blockchain. Unlike Automated Market Makers (AMMs), DeepBook enables traders to place buy and sell orders directly on-chain, ensuring precise price discovery.</p><ul><li><strong>Developer Opportunities:</strong></li><li>Integrate DeepBook as a liquidity source for DeFi applications.</li><li>Build advanced trading tools such as algorithmic trading bots or market-making strategies.</li><li><strong>Technical Highlights:</strong></li><li>Leverages Sui’s parallel transaction processing for high-frequency trading.</li><li>Supports market and limit orders with sub-second settlement speeds.</li></ul><h3>2. Bluefin</h3><p><a href="https://learn.bluefin.io/bluefin">https://learn.bluefin.io/bluefin</a></p><p>Bluefin is a decentralized exchange (DEX) specializing in derivatives trading, including perpetual futures. It combines the user experience of centralized exchanges with the transparency and security of decentralized platforms.</p><ul><li><strong>Developer Opportunities:</strong></li><li>Create custom trading interfaces or analytics tools using Bluefin’s API.</li><li>Build financial products like delta-neutral strategies or staking mechanisms around Bluefin’s $BLUE token.</li><li><strong>Technical Highlights:</strong></li><li>Achieves sub-second transaction finality using Sui’s high-performance infrastructure.</li><li>Features zkLogin for seamless user onboarding without requiring wallets.</li></ul><h3>3. NAVI Protocol</h3><p><a href="https://naviprotocol.gitbook.io/navi-protocol-docs">https://naviprotocol.gitbook.io/navi-protocol-docs</a></p><p>NAVI is a decentralized liquidity protocol focused on lending and borrowing. It offers dynamic interest rates based on market conditions, making it an essential component of Sui’s DeFi ecosystem.</p><ul><li><strong>Developer Opportunities:</strong></li><li>Build dApps that integrate NAVI’s lending pools to offer users passive income opportunities.</li><li>Leverage NAVI’s composability to create interconnected financial solutions.</li><li><strong>Technical Highlights:</strong></li><li>Fully audited smart contracts ensure security and reliability.</li><li>Optimized for low-latency operations on the Sui blockchain.</li></ul><h3>4. Suilend</h3><p><a href="https://docs.suilend.fi/">https://docs.suilend.fi/</a></p><p>Suilend is another leading DeFi protocol offering decentralized lending and borrowing services. It features dual lending pools — main pools for stable assets and isolated pools for riskier tokens.</p><ul><li><strong>Developer Opportunities:</strong></li><li>Integrate lending functionalities into multi-purpose DeFi platforms.</li><li>Use its swap feature to enhance user experience in financial dApps.</li><li><strong>Technical Highlights:</strong></li><li>Built with Move for enhanced security and flexibility.</li><li>Utilizes Sui’s scalability for fast and cost-effective transactions.</li></ul><h3>5. Cetus Protocol</h3><p><a href="https://cetus-1.gitbook.io/cetus-docs">https://cetus-1.gitbook.io/cetus-docs</a></p><p>Cetus is a DEX that uses a Concentrated Liquidity Market Maker (CLMM) model, enabling liquidity providers to allocate capital efficiently within specific price ranges.</p><ul><li><strong>Developer Opportunities:</strong></li><li>Build advanced trading tools using Cetus’ SDK.</li><li>Develop automated strategies like range orders or limit orders leveraging Cetus’ programmable liquidity features.</li><li><strong>Technical Highlights:</strong></li><li>High composability with other DeFi protocols on Sui.</li><li>Double-token model (CETUS and xCETUS) incentivizes participation sustainably.</li></ul><h3>6. Axelar</h3><p><a href="https://docs.axelar.dev/">https://docs.axelar.dev/</a></p><p>Axelar brings cross-chain interoperability to Sui, enabling seamless communication between different blockchains. Developers can build applications that interact with multiple ecosystems without complex bridging mechanisms.</p><ul><li><strong>Developer Opportunities:</strong></li><li>Create multi-chain dApps that leverage assets or data from other blockchains.</li><li>Build cross-chain DeFi platforms or NFT marketplaces with ease.</li><li><strong>Technical Highlights:</strong></li><li>Fully interoperable with major blockchain networks like Ethereum and Solana.</li><li>Simplifies cross-chain asset transfers through its unified API.</li></ul><h3>7. Wormhole</h3><p><a href="https://wormhole.com/docs/">https://wormhole.com/docs/</a></p><p>Wormhole is another cross-chain protocol integrated with Sui, enabling asset transfers and communication across blockchains. Its focus on interoperability makes it an invaluable tool for developers building multi-chain applications.</p><ul><li><strong>Developer Opportunities:</strong></li><li>Enable users to move tokens seamlessly between ecosystems while leveraging Sui’s performance advantages.</li><li>Build applications that utilize data or functionality from other chains through Wormhole integration.</li><li><strong>Technical Highlights:</strong></li><li>Supports a wide range of blockchain networks, enhancing versatility.</li><li>Offers low-latency operations thanks to its integration with Sui.</li></ul><h3>Conclusion</h3><p>The combination of Sui’s high-performance infrastructure, the secure Move programming language, and a growing ecosystem of innovative protocols creates an unparalleled environment for developers. Projects like DeepBook, Bluefin, NAVI Protocol, Cetus, Axelar, Wormhole, and Suilend showcase the vast opportunities available on this blockchain. Whether you’re interested in DeFi, cross-chain interoperability, or building entirely new use cases, Sui provides all the tools you need to succeed in today’s competitive blockchain landscape.</p><p>For developers eager to shape the future of Web3, there has never been a better time to start building on Sui!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8d1427fe1504" width="1" height="1" alt=""><hr><p><a href="https://medium.com/eincode/exploring-sui-and-its-most-exciting-protocols-for-developers-8d1427fe1504">Exploring Sui and Its Most Exciting Projects for Developers</a> was originally published in <a href="https://medium.com/eincode">Eincode</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Demystifying Coin Locking in Move on Sui: A Deep Dive]]></title>
            <link>https://medium.com/eincode/demystifying-coin-locking-in-move-on-sui-a-deep-dive-33b96d27eb72?source=rss----96930c935cba---4</link>
            <guid isPermaLink="false">https://medium.com/p/33b96d27eb72</guid>
            <category><![CDATA[sui]]></category>
            <category><![CDATA[move]]></category>
            <category><![CDATA[blockchain]]></category>
            <category><![CDATA[smart-contracts]]></category>
            <category><![CDATA[web3]]></category>
            <dc:creator><![CDATA[Filip Jerga]]></dc:creator>
            <pubDate>Tue, 11 Feb 2025 17:00:38 GMT</pubDate>
            <atom:updated>2025-02-11T17:00:38.717Z</atom:updated>
            <content:encoded><![CDATA[<h4>Unlock the Power of Secure Coin Management on Sui with Move’s Time-Locking Mechanism.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*THQ5wxZk0nzFJNrpLnsdDw.jpeg" /></figure><p>In this article, we’ll explore how to implement <strong>time-locked coins</strong> on the Sui blockchain using the Move programming language. Time-locked coins are a crucial primitive for building secure and transparent applications, enabling functionality like vesting schedules, rewards, or governance systems. This guide focuses exclusively on the <strong>locking and unlocking mechanism</strong>, breaking it down line-by-line to ensure you fully understand the implementation.</p><h3>Resources</h3><p><em>If you want to learn Move and Sui in-depth, check out my full course on building real projects with Move and React: </em><a href="https://academy.eincode.com/courses/sui-dapps-with-move-react-build-real-projects"><strong><em>academy.eincode.com</em></strong></a><strong><em>.</em></strong></p><p><strong><em>Full Contract Code:</em></strong><em> </em><a href="https://github.com/Jerga99/sui-jelo-coin/blob/main/contracts/jelo_coin/sources/jelo_coin.move"><em>https://github.com/Jerga99/sui-jelo-coin/blob/main/contracts/jelo_coin/sources/jelo_coin.move</em></a></p><h3>1. The Locker Object — Your Time-Locked Container</h3><p>To enable time-locking, we need a specialized object that securely holds coins until they are eligible for release. Enter the Locker object:</p><pre>public struct Locker has key, store {<br> id: UID,<br> unlock_date: u64,<br> balance: Balance&lt;JELO&gt;,<br>}</pre><h3>Key Fields and Attributes:</h3><ul><li><strong>key:</strong> This is an “ability” in Move that enforces the addition of an id field in the struct. The id acts as a unique identifier, ensuring that the object can be stored on the blockchain.</li><li><strong>store:</strong> This ability allows the struct to be stored within another struct, making it suitable for hierarchical or compositional object designs.</li><li><strong>id</strong>: The UID field provides the Locker with a unique identifier, ensuring it is distinguishable as an independent object. This unique identifier allows the Locker to be stored and tracked on the blockchain.</li><li><strong>unlock_date</strong>: This field is a Unix timestamp (in milliseconds) that specifies when the coins inside the Locker can be accessed.</li><li><strong>balance</strong>: Instead of using Coin, we use Balance for efficient storage. Balance acts as a container for locked funds that can later be converted back to a spendable Coin.</li></ul><h3>Why Use Balance Instead of Coin?</h3><ul><li><strong>Coin</strong>: Represents a spendable coin, optimized for immediate transactions.</li><li><strong>Balance</strong>: Optimized for storage and used in scenarios where the coins are not immediately accessible, such as time-locking.</li></ul><h3>2. Minting Locked Coins</h3><p>The mint_locked function handles the minting of new coin and encapsulates it in a Locker object before sending it to the recipient. Here&#39;s the implementation:</p><pre>public fun mint_locked(<br>    mint_cap: &amp;mut MintCapability,<br>    amount: u64,<br>    recipient: address,<br>    duration: u64,<br>    clock: &amp;Clock,<br>    ctx: &amp;mut TxContext<br>) {<br>    // 1. Mint coin<br>    let coin = mint_internal(mint_cap, amount, ctx);<br>    <br>    // 2. Calculate unlock time<br>    let start_date = clock.timestamp_ms();<br>    let unlock_date = start_date + duration;<br><br>    // 3. Create locked container<br>    let locker = Locker {<br>        id: object::new(ctx),<br>        unlock_date,<br>        balance: coin::into_balance(coin) // Convert Coin → Balance<br>    };<br><br>    // 4. Send Locker to recipient<br>    transfer::public_transfer(locker, recipient);<br>}</pre><h3>Key Steps Explained:</h3><ol><li><strong>Mint Coin</strong>: The mint_internal function creates coins in the form of a Coin object. It ensures the minted amount does not exceed the defined supply limits for the coin.</li><li><strong>Calculate Unlock Time</strong>: The current timestamp is obtained from Sui’s decentralized Clock object. Adding the specified duration to this timestamp gives us the unlock_date.</li><li><strong>Create the Locker</strong>:</li></ol><ul><li>A new Locker object is created, with its id generated using the object::new() function.</li><li>The Coin object is converted into a Balance using coin::into_balance(). This makes the coins storable in the Locker.</li></ul><p>4. <strong>Transfer the Locker</strong>: Finally, the Locker object is transferred to the specified recipient, effectively locking the coins in their account until the unlock date.</p><h3>3. Withdrawing Locked Funds</h3><p>The withdraw_locked function enables users to retrieve their locked coins once the specified time has passed. Here’s how it works:</p><pre>entry fun withdraw_locked(locker: Locker, clock: &amp;Clock, ctx: &amp;mut TxContext): u64 {<br>    // Unwrap Locker object<br>    let Locker { id, mut balance, unlock_date } = locker;<br><br>    // 1. Check lock expiration<br>    assert!(clock.timestamp_ms() &gt;= unlock_date, ETokenLocked);<br><br>    // 2. Convert Balance → Coin<br>    let locked_balance_value = balance.value();<br>    transfer::public_transfer(<br>        coin::take(&amp;mut balance, locked_balance_value, ctx), // Magic happens here<br>        ctx.sender()<br>    );<br><br>    // 3. Cleanup empty Balance<br>    balance.destroy_zero();<br>    object::delete(id);<br><br>    // Return withdrawn amount<br>    locked_balance_value<br>}</pre><h3>Key Steps and Security Measures:</h3><ol><li><strong>Validate Unlock Time</strong>:</li></ol><ul><li>The function first checks whether the current timestamp (from the Clock) is greater than or equal to the unlock_date. If not, it throws an error (ETokenLocked), preventing premature access.</li></ul><p>2. <strong>Convert Balance to Spendable Coin</strong>:</p><ul><li>The coin::take() function extracts the full value of the Balance and converts it into a spendable Coin.</li><li>This Coin is then transferred to the sender’s account (ctx.sender()).</li></ul><p>3. <strong>Clean Up Resources</strong>:</p><ul><li>The destroy_zero() function ensures that the Balance is empty after the transfer, preventing any residual values.</li><li>The Locker’s unique ID is deleted using object::delete(), removing it from the system entirely.</li></ul><h3>Key Concepts Explained</h3><h3>Why Use Balance for Locked Funds?</h3><ul><li><strong>Efficiency</strong>: Balance is designed for storage, making it ideal for coins that are not immediately accessible.</li><li><strong>Security</strong>: By separating locked funds from spendable assets, it ensures strict enforcement of access restrictions.</li></ul><h3>Decentralized Clock</h3><ul><li>Sui’s Clock object provides a globally agreed-upon timestamp, ensuring users cannot manipulate local time to unlock coins prematurely.</li></ul><h3>Safety Mechanisms</h3><ul><li><strong>destroy_zero</strong>: Ensures no residual value remains in the Balance after withdrawal.</li><li><strong>Object Deletion</strong>: Prevents reuse or duplication of the Locker object, maintaining system integrity.</li><li><strong>entry Modifier</strong>: Exposes the function as a transaction endpoint, allowing users to call it directly via transactions.</li></ul><h3>Visualizing the Flow</h3><p>Here’s a high-level summary of the process:</p><ol><li><strong>Mint Tokens</strong>: Create coins using standard minting procedures.</li><li><strong>Convert to Balance</strong>: Prepare the coins for storage by converting them into a non-spendable Balance.</li><li><strong>Lock in Container</strong>: Store the Balance in a Locker with an unlock date.</li><li><strong>Wait for Unlock Date</strong>: The Locker remains inaccessible until the specified time passes.</li><li><strong>Validate and Unlock</strong>: Once the unlock date is reached, validate the time and convert the Balance back into spendable Coin.</li></ol><h3>Why This Matters</h3><p>Time-locked coins are a versatile building block for decentralized applications. Here are some real-world use cases:</p><ul><li><strong>Vesting Schedules</strong>: Founders’ coins allocations can be locked to ensure long-term commitment.</li><li><strong>Time-Locked Rewards</strong>: GameFi platforms can use this mechanism to reward users after achieving milestones.</li><li><strong>DAO Governance</strong>: Voting power can be time-locked to prevent sudden sell-offs or manipulation.</li></ul><p>By leveraging Move’s strict type system and Sui’s decentralized architecture, this pattern ensures <strong>secure and flexible asset management</strong>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=33b96d27eb72" width="1" height="1" alt=""><hr><p><a href="https://medium.com/eincode/demystifying-coin-locking-in-move-on-sui-a-deep-dive-33b96d27eb72">Demystifying Coin Locking in Move on Sui: A Deep Dive</a> was originally published in <a href="https://medium.com/eincode">Eincode</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Creating a Meme Coin on Sui Blockchain: Simplicity Meets Power]]></title>
            <link>https://medium.com/eincode/creating-a-meme-coin-on-sui-blockchain-simplicity-meets-power-f7d1dc1118cd?source=rss----96930c935cba---4</link>
            <guid isPermaLink="false">https://medium.com/p/f7d1dc1118cd</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[dapps]]></category>
            <category><![CDATA[sui]]></category>
            <category><![CDATA[blockchain]]></category>
            <category><![CDATA[move]]></category>
            <dc:creator><![CDATA[Filip Jerga]]></dc:creator>
            <pubDate>Fri, 07 Feb 2025 15:41:55 GMT</pubDate>
            <atom:updated>2025-02-07T15:41:54.919Z</atom:updated>
            <content:encoded><![CDATA[<p>Learn how to harness Sui’s unique features to launch your own digital currency effortlessly.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0NWbqdt8wtp2296CrjcfyQ.jpeg" /></figure><p>In this tutorial, we’ll break down how to create your own meme coin on Sui using Move — the blockchain’s native smart contract language. Sui’s object-centric model and developer-friendly approach make it special, and we’ll demonstrate this with actual code. By the end, you’ll understand why Sui is becoming a favorite for Web3 projects.</p><h3>Complete Meme Coin Code</h3><p>Full Project: <a href="https://github.com/Jerga99/sui-jelo-coin">https://github.com/Jerga99/sui-jelo-coin</a></p><pre>module jelo_coin::jelo;<br>use sui::coin::{Self, TreasuryCap};<br>use sui::url::new_unsafe_from_bytes;<br><br>public struct JELO has drop {}<br><br>const TOTAL_SUPPLY: u64 = 1_000_000_000_000_000_000;<br><br>fun init(otw: JELO, ctx: &amp;mut TxContext) {<br>    let (mut treasury, metadata) = coin::create_currency(<br>        otw,<br>        9,<br>        b&quot;JELO&quot;,<br>        b&quot;JELO&quot;,<br>        b&quot;Meet JELO the cutest jellyfish meme coin...&quot;,<br>        option::some(new_unsafe_from_bytes(b&quot;data:image/jpeg;base64,...&quot;)),<br>        ctx<br>    );<br>    mint(&amp;mut treasury, TOTAL_SUPPLY, ctx.sender(), ctx);<br>    transfer::public_freeze_object(metadata);<br>    transfer::public_freeze_object(treasury);<br>}<br><br>public fun mint(<br>    treasury_cap: &amp;mut TreasuryCap&lt;JELO&gt;,<br>    amount: u64,<br>    recipient: address,<br>    ctx: &amp;mut TxContext<br>) {<br>    let coin = coin::mint(treasury_cap, amount, ctx);<br>    transfer::public_transfer(coin, recipient);<br>}</pre><h3>Key Components Explained</h3><h3>1. Module Initialization</h3><pre>module jelo_coin::jelo;<br>use sui::coin::{Self, TreasuryCap};</pre><ul><li><strong>Package Structure:</strong> The jelo_coin package contains the jelo module, where the logic for creating and managing the meme coin resides.</li><li><strong>Core Imports:</strong> The module uses Sui’s built-in coin module for token standards, simplifying development and ensuring compatibility with the Sui ecosystem.</li></ul><h3>2. Coin Configuration</h3><pre>public struct JELO has drop {}<br>const TOTAL_SUPPLY: u64 = 1_000_000_000_000_000_000;</pre><ul><li><strong>Purpose</strong>:<br>The JELO struct serves as the core identifier for the JELO coin. It represents the unique resource associated with the token.</li><li><strong>drop Ability</strong>:<br>The drop ability allows instances of JELO to be destroyed or discarded without requiring explicit handling, such as transferring or unpacking. This simplifies the logic for managing the resource in certain scenarios. However, in this context, the JELO struct is primarily used as a type marker for the coin and isn&#39;t directly dropped during normal operations.</li><li><strong>Supply Clarification</strong>:<br>While the supply is represented as 1 quintillion <strong>(1_000_000_000_000_000_000)</strong> base units, the human-readable total supply is 1 billion<strong> (1_000_000_000)</strong> JELO due to the 9 decimal places defined for precision. Each JELO is divisible into 1 billion base units, meaning 1 JELO = 1 billion base units. This design follows a common pattern in meme coins, allowing for small transaction values and mimicking fiat currency subdivisions, such as cents.</li></ul><h3>3. Smart Initialization</h3><pre>fun init(otw: JELO, ctx: &amp;mut TxContext) {<br>  let (mut treasury, metadata) = coin::create_currency(<br>    otw, // One-time witness<br>    9,   // Decimals<br>    b&quot;JELO&quot;, // Symbol<br>    b&quot;JELO&quot;, // Name<br>    b&quot;Description...&quot;, // Description<br>    option::some(image_url), // Base64 image<br>    ctx<br>  );</pre><ul><li><strong>coin::create_currency</strong>:<br>This function abstracts the complex process of creating a token by:</li><li>Managing <strong>metadata</strong> (name, symbol, description, and logo).</li><li>Configuring <strong>decimal precision</strong>, allowing transactions in fractional amounts.</li><li>Ensuring the token’s properties (like its name and symbol) are immutable after initialization.</li><li><strong>One-Time Witness (OTW) Pattern</strong>:<br>The otw parameter ensures that the initialization function is executed only once. This prevents unauthorized creation of duplicate currencies.</li><li><strong>Freezing Objects</strong>:<br>Freezing the metadata and treasury ensures that they cannot be altered post-deployment, adding security and trustworthiness to the token.</li></ul><h3>4. Supply Management</h3><pre>mint(&amp;mut treasury, TOTAL_SUPPLY, ctx.sender(), ctx);<br>transfer::public_freeze_object(metadata);<br>transfer::public_freeze_object(treasury);</pre><ul><li><strong>Initial Minting</strong>:<br>The entire token supply is minted at the time of deployment and sent to the creator’s wallet. This is a common pattern for meme coins, allowing the creator to control initial distribution.</li><li><strong>Post-Deployment Immutability</strong>:<br>By freezing the metadata and treasury, the token’s core properties and minting authority cannot be altered, providing assurance to users and investors that the maximum supply can ever be 1 billion coins, ensuring scarcity and value retention over time.</li></ul><h3>5. Mint Function</h3><pre>public fun mint(<br>    treasury_cap: &amp;mut TreasuryCap&lt;JELO&gt;,<br>    amount: u64,<br>    recipient: address,<br>    ctx: &amp;mut TxContext<br>) {<br>    let coin = coin::mint(treasury_cap, amount, ctx);<br>    transfer::public_transfer(coin, recipient);<br>}</pre><ul><li><strong>Controlled Minting</strong>:<br>The mint function requires the TreasuryCap, which acts as the authority for minting and burning. This function is called initially in the init process, and once the treasury is frozen, it cannot be called again, preventing unauthorized inflation by ensuring no additional tokens can be created.</li><li><strong>Native Transfers</strong>:<br>Transfers use Sui’s built-in transfer system, ensuring secure and gas-efficient token movement.</li></ul><h3>Why This Matters for Developers</h3><h4>Battery-Included Design</h4><p>Sui provides robust, built-in modules and standards, making token creation straightforward:</p><ul><li>No need to write custom token standards like ERC-20.</li><li>Automatic metadata handling, so developers don’t have to manage JSON-based metadata manually.</li><li>Built-in support for decimals, making fractional transactions seamless.</li></ul><h4>Object Security Model</h4><ul><li><strong>TreasuryCap</strong>: Controls minting and burning, reducing the risk of unauthorized inflation.</li><li><strong>Frozen Objects</strong>: Prevent changes to critical components like metadata and supply settings.</li><li><strong>Ownership Rules</strong>: Enforced at the protocol level to enhance security and reduce bugs.</li></ul><h4>Gas Efficiency</h4><ul><li>Token initialization requires only a single transaction, reducing deployment costs.</li><li>Transactions can be batched, allowing multiple operations within a single block.</li><li>Sui’s predictable fee structure ensures consistent and low costs.</li></ul><h3>From Code to Production</h3><p>While this shows core token creation, real-world projects need:</p><ol><li>Tokenomics strategies</li><li>Liquidity pool integration</li><li>Frontend with React.js (or other lib)</li><li>Unit testing &amp; security audits</li><li>Mainnet deployment</li></ol><p><strong>Want to master these aspects?</strong> My Udemy course <a href="https://academy.eincode.com/courses/sui-dapps-with-move-react-build-real-projects"><strong>Sui Blockchain with Move &amp; React.js — The Complete Guide</strong></a> covers:</p><p>✅ Full-stack dApp development<br>✅ Advanced tokenomics design<br>✅ Voting systems with shared objects<br>✅ React frontend integration<br>✅ Testnet/Devnet/Local deployment<br>✅ Real-world project</p><pre>// Enroll today and bootstrap your career<br>module education::sui_development;<br><br>public fun launch_career(student: &amp;mut Developer) {<br>    student.skill_level = Level::Professional;<br>}</pre><p>Sui’s combination of Move’s safety and React’s flexibility creates perfect conditions for blockchain developers. Whether you’re building the next viral meme coin or enterprise-grade dApps, these tools provide the foundation you need.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f7d1dc1118cd" width="1" height="1" alt=""><hr><p><a href="https://medium.com/eincode/creating-a-meme-coin-on-sui-blockchain-simplicity-meets-power-f7d1dc1118cd">Creating a Meme Coin on Sui Blockchain: Simplicity Meets Power</a> was originally published in <a href="https://medium.com/eincode">Eincode</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Learn Move for Sui: 11 Key Concepts Explained Simply]]></title>
            <link>https://medium.com/eincode/learn-move-for-sui-11-key-concepts-explained-simply-39299763959c?source=rss----96930c935cba---4</link>
            <guid isPermaLink="false">https://medium.com/p/39299763959c</guid>
            <category><![CDATA[move]]></category>
            <category><![CDATA[dapps]]></category>
            <category><![CDATA[blockchain]]></category>
            <category><![CDATA[sui]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Filip Jerga]]></dc:creator>
            <pubDate>Tue, 28 Jan 2025 16:44:57 GMT</pubDate>
            <atom:updated>2025-01-28T16:44:57.093Z</atom:updated>
            <content:encoded><![CDATA[<h4>A Practical Guide for Aspiring Sui Developers</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*w23PknWIBIqbdTD0TexwAQ.png" /></figure><p>Move is a powerful and secure programming language designed specifically for building on blockchain platforms like Sui. If you’re eager to start developing on Sui, understanding Move is absolutely essential. This guide covers 11 fundamental concepts that will give you a solid foundation in Move and set you on the path to building your own Sui dApps. We’ll explain each topic concisely with practical examples.</p><h3><strong>Additional Resources</strong></h3><p>Docs: <a href="https://move-language.github.io/move/">https://move-language.github.io/move/</a></p><p>Full Course: <a href="https://academy.eincode.com/courses/sui-dapps-with-move-react-build-real-projects">https://academy.eincode.com/courses/sui-dapps-with-move-react-build-real-projects</a></p><h3>1. Modules: Organizing Your Code</h3><p>Every Move source file <em>must</em> start with a module declaration. Modules are fundamental to how Move code is organized, acting like containers or namespaces. They help structure your project and prevent naming collisions.</p><pre>module voting_system::game;<br><br>use std::string::String;<br><br>...rest of code</pre><p>module voting_system::game; declares the module. voting_system is the <em>package name</em> (the on-chain address after deployment), and game is the <em>module name</em>. The combination voting_system::game uniquely identifies your code on the Sui network. The use statements import code from other modules, making it available in your module. Modules are essential for organizing your Move code and managing dependencies.</p><h3>2. Structs: Defining Your Data</h3><p>Structs are used to define the structure of your data. Think of them as blueprints for creating objects.</p><pre>public struct Player{<br>    name: String,<br>    health: u64,<br>    strength: u64,<br>    hasWeapon: bool,<br>}</pre><p>This defines a Player struct with a name, health, strength and hasWeapon.</p><p>To create an instance of a struct, you write:</p><pre>let player = Player {<br>    name: b&quot;Filip&quot;.to_string(),<br>    health: 100,<br>    strength: 2,<br>    hasWeapon: false,<br>}</pre><h3>3. <strong>key</strong> Ability: Storing Objects On-Chain</h3><p>The key ability is essential for storing objects on the Sui blockchain. It signifies that the struct has a unique ID, which is crucial for on-chain identification and management. In Sui, almost everything is an NFT, meaning it&#39;s unique and has a unique ID.</p><pre>public struct Player has key {<br>    id: UID, // UID is the unique identifier<br>    // ... other fields<br>}</pre><p>To create an instance of a struct with key ability, you write:</p><pre>let player = Player {<br>    id: object::new(ctx)<br>    // ...other fields<br>}</pre><p>The ctx is a transaction context, we will talk about it next.</p><h3>4. init Function: Initializing Your Module</h3><p>The init function is special: it&#39;s automatically called <em>once</em> when your module is published on the blockchain. It&#39;s the ideal place to set up the initial state of your module. It <em>must</em> take a TxContext argument.</p><pre>public struct Game has key {<br>    id: UID,<br>    max_players: u64,<br>    current_players: u64,<br>}<br><br>fun init(ctx: &amp;mut TxContext) {<br>    let game = Game {<br>        id: object::new(ctx),<br>        max_players: 10,<br>        current_players: 0,<br>    };<br>    transfer::share_object(game); // Make the game accessible to everyone.<br>}</pre><p>This example creates a Game object with some initial configuration (max_players, current_players) and then makes it shared using transfer::share_object. This means anyone can interact with the game, following the rules you define in your module.</p><p>The TxContext is provided by the Sui network when the module is published. It contains information about the transaction that&#39;s publishing the module, including the sender&#39;s address (ctx.sender()), which is crucial for setting up ownership and permissions. Think of it as the environment your module is running in when it&#39;s first deployed. The &amp;mut means the init function can modify the context if needed (though it&#39;s not usually usually required). object::new(ctx) generates a unique ID for the new Game object.</p><h3>5. Owned vs. Shared Objects</h3><p>Sui distinguishes between owned and shared objects, which determines how they can be accessed and modified. Think of it like owning a car: if it’s <em>owned</em>, only you have the keys. If it’s <em>shared</em>, like a taxi, multiple people can use it. A <em>frozen</em> object is like a car in a museum — everyone can look, but no one can touch.</p><ul><li><strong>Owned:</strong> Only the owner can modify an owned object.</li><li><strong>Shared:</strong> Anyone can modify a shared object, following the module’s rules.</li><li><strong>Frozen:</strong> Immutable. Everyone can view, but no one can modify.</li></ul><pre>public struct Car has key {<br>    id: UID,<br>    mileage: u64,<br>}<br><br>fun init(ctx: &amp;mut TxContext) {<br>    let owned_car = Car { id: object::new(ctx), mileage: 0 };<br>    let shared_car = Car { id: object::new(ctx), mileage: 0 };<br><br>    transfer::transfer(owned_car, ctx.sender()); // Transfer ownership<br>    transfer::share_object(shared_car);          // Make it shared<br>}</pre><ul><li>transfer::transfer(owned_car, ctx.sender()); transfers ownership of the owned_car to the transaction sender (the one who initiated the transaction). After this line executes, the sender is the <em>sole owner</em> of owned_car.</li><li>transfer::share_object(shared_car); makes the shared_car a <em>shared object</em>. This means that <em>anyone</em> can interact with shared_car according to the rules defined in your smart contract. It&#39;s no longer owned by a single entity.</li></ul><h3>6. Object Handling: Managing Object Lifecycles</h3><p>Move has strict rules about object management. To simulate “real-world” objects and ensure security, every object must be explicitly handled (consumed, transferred, or destroyed) before a function finishes. You can’t just create an object and let it disappear. This prevents resource leaks and ensures predictable behavior.</p><p>Let’s illustrate with an example. Imagine you want to create a Car object:</p><pre>public struct Car has key {<br>    id: UID,<br>    mileage: u64,<br>}<br><br>fun create_car(ctx: &amp;mut TxContext) {<br>    let car = Car { id: object::new(ctx), mileage: 0 };<br>    // This code would cause a compilation error!<br>    // The car object is created but not handled.<br>}</pre><p>The previous code will not compile. Let’s fix it:</p><pre>fun create_car(ctx: &amp;mut TxContext) {<br>    let car = Car { id: object::new(ctx), mileage: 0 };<br>    transfer::transfer(car, ctx.sender()); // Transfer ownership to the sender. This fixes the error.<br>}</pre><p>The original (incorrect) create_car function created a Car object but didn&#39;t do anything with it. Move&#39;s ownership rules require that every object be either transferred, shared, or destroyed.</p><p>The corrected create_car function uses transfer::transfer(car, ctx.sender()). ctx.sender() retrieves the address of the transaction sender (the one calling the function). transfer::transfer(car, ctx.sender()) then transfers ownership of the newly created car to that sender. This satisfies Move&#39;s ownership rules, and the code will now compile. The key is that the car object is now <em>handled</em>—it has an owner.</p><h3>7. Capability Pattern: Secure Access Control</h3><p>The capability pattern is a powerful way to manage permissions in Move. You create a special &quot;capability&quot; object and grant it to specific addresses. Only those holding the capability can perform certain actions.</p><pre>public struct AdminCap has key {<br>    id: UID,<br>}<br><br>fun init(ctx: &amp;mut TxContext) {<br>    let admin_cap = AdminCap { id: object::new(ctx) };<br>    transfer::transfer(admin_cap, ctx.sender()); // Give admin capability to the deployer<br>}<br><br>// Example usage (only the owner of AdminCap can call this)<br>fun sell_car(car: &amp;mut Car, _admin_cap: &amp;AdminCap) {<br>    // ... selling logic ...<br>}</pre><p>In this example, AdminCap is a capability. The init function creates an AdminCap and gives it to the transaction sender (likely the one deploying the module). Now, only the owner of that AdminCap can successfully call the sell_car function.</p><p>Here’s why: When someone tries to call sell_car, Move&#39;s runtime automatically checks if the caller <em>owns</em> an AdminCap object. If the caller <em>does </em><strong><em>NOT</em></strong> own the AdminCap, the transaction will fail <em>before</em> the sell_car function even begins to execute. No explicit checks within sell_car are required. Move&#39;s type system and ownership rules enforce this automatically. This is what makes the capability pattern so clean and secure. It shifts access control to the Move runtime, making your smart contracts more concise and less prone to errors. It&#39;s a very elegant solution for access control.</p><h3>8. Dropping: Explicitly Discarding Values</h3><p>Move requires you to handle all values. If you create a value, you must do something with it. Let’s see what happens if you don’t:</p><pre>public struct Book {} // No &#39;drop&#39; ability<br><br>fun create_book(ctx: &amp;mut TxContext) {<br>    let book = Book {}; // Creates a Book object<br>    // This will cause a compilation error! Book must be handled.<br>}</pre><p>This code will <em>not</em> compile. Because Book does <em>not</em> have the drop ability, Move requires you to explicitly handle the book value. You can&#39;t just create it and let it go out of scope. The compiler will complain about an unused value.</p><p>To fix this, you have two main options. If you intend to discard the value, you can give the struct the drop ability:</p><pre>public struct Book has drop {} // Now has the &#39;drop&#39; ability<br><br>fun create_book(ctx: &amp;mut TxContext) {<br>    let book = Book {}; // Creates a Book object<br>    // Because Book has &#39;drop&#39;, it&#39;s automatically discarded <br>    // at the end of the function.<br>}</pre><p>Now the code compiles. Because Book has the drop ability, Move knows it&#39;s okay to discard it. The book value is implicitly dropped at the end of the moving function.</p><p>The other option, if you don’t want to give the struct the drop ability for some reason, is to &quot;unpack&quot; it:</p><pre>public struct Book {} // No &#39;drop&#39; ability<br><br>fun create_book(ctx: &amp;mut TxContext) {<br>    let book = Book {};<br>    let Book {} = book; // &quot;Unpack&quot; the book.  This tells Move you&#39;ve handled it.<br>}</pre><p>This also compiles. The let Book {} = book; line &quot;unpacks&quot; the book value. Even though we&#39;re not using any of the fields within the Book struct, this line tells Move that we&#39;ve acknowledged the book&#39;s existence and handled it (by effectively discarding it). This is necessary for structs without drop to avoid compiler errors.</p><h3>9. Moving vs. Copying: Ownership Semantics</h3><p>Move has strict ownership rules that dictate how values are handled. This is crucial for security and preventing double spending. Let’s explore the difference between copying and moving.</p><p><strong>Copying (Primitive Types):</strong></p><p>Primitive types like integers are <strong><em>copied</em></strong>. This means when you assign one primitive variable to another, a completely new, independent copy is created. Changes to one copy don’t affect the other.</p><pre>let a = 10;<br>let b = a; // &#39;a&#39; is copied to &#39;b&#39;. &#39;a&#39; and &#39;b&#39; are independent.<br>let b = b + 2; // Modifying &#39;b&#39; does not affect &#39;a&#39;. &#39;a&#39; is 10, &#39;b&#39; is 12.</pre><p>In this example, b is a <em>copy</em> of a. They are completely separate values in memory.</p><p><strong>Moving (Structs — Default Behavior):</strong></p><p>Structs, by default, are <strong><em>moved</em></strong>. When you assign one struct variable to another, the original variable becomes unusable. The value is <em>transferred</em>, not duplicated.</p><pre>public struct Book has drop {}<br>let book1 = Book {};<br>let book2 = book1; // &#39;book1&#39; is moved to &#39;book2&#39;. &#39;book1&#39; is no longer valid!<br><br>// Trying to use a moved value (will cause a compile error)<br>debug::print(&amp;book1); // This will NOT compile! &#39;book1&#39; has been moved.</pre><p>Here, book1 is <em>moved</em> to book2. book1 is no longer a valid variable. Trying to use it will result in a compile-time error. You should write:</p><pre>debug::print(&amp;book2);</pre><p><strong>Moving and Function Arguments:</strong></p><p>Moving also applies to function arguments. When you pass a struct to a function, it’s moved into the function’s scope.</p><pre>public struct Book has key { id: UID }<br><br>fun pay(book: Book, ctx: &amp;TxContext) {<br>    //... pay functionality...<br>    transfer::transfer(book, ctx.sender()); // Transfer book to payer<br>}<br>fun buy(ctx: &amp;mut TxContext) {<br>    let book = Book { id: object::new(ctx) };<br>    pay(book, ctx); // &#39;book&#39; is moved into the &#39;pay&#39; function.<br><br>    debug::print(&amp;book); // This will NOT compile! &#39;book&#39; has been moved.<br>}</pre><p>In this case, the book object is moved into the pay function. After the pay function is called, you can no longer use the original book variable in the buy function.</p><p><strong>Copying Structs (Using the </strong><strong>copy Ability):</strong></p><p>You can enable copying for structs by giving them the copy ability. This allows you to create independent copies of structs, just like with primitive types.</p><pre>public struct Book has drop, copy { <br>    pages: u64 <br>}<br><br>let book3 = Book { pages: 100 };<br>let book4 = book3; // &#39;book3&#39; is copied to &#39;book4&#39;. Both are valid.<br><br>book4.pages = 200; // Modifying book4 does not modify book3.<br><br>debug::print(&amp;book3.pages); // Prints 100.<br>debug::print(&amp;book4.pages); // Prints 200.</pre><p>Now, book4 is a <em>copy</em> of book3. They are independent, and changes to one don&#39;t affect the other. The copy ability is essential when you want multiple independent instances of a struct.</p><h3>10. store Ability: Nesting Structs</h3><p>Structs with the key ability cannot directly contain other structs. The store ability solves this.</p><pre>public struct Book has key {  // Book has the &#39;key&#39; ability<br>    id: UID,<br>}<br><br>public struct Shelf has key {  // Shelf also has the &#39;key&#39; ability<br>    id: UID,<br>    book: Book, // Trying to store a Book in a Shelf<br>}</pre><p>This code will <em>not</em> compile. Move will throw an error because Shelf (which has the key ability) is trying to contain Book (which also has the key ability, but <em>not</em> the store ability).</p><p>A struct with store can be contained within another struct.</p><pre>public struct Book has key, store {<br>    id: UID,<br>}<br><br>public struct Shelf has key {<br>    id: UID,<br>    book: Book, // Now allowed because Book has the &#39;store&#39; ability<br>}</pre><h3>11. References: Borrowing Data</h3><p>References allow you to access data without taking ownership. They “borrow” the data. This is useful when you want to use a value without preventing other parts of your code from using it as well.</p><p><strong>Basic Reference:</strong></p><pre>public struct Book has drop {}<br><br>public fun borrowing() {<br>    let book = Book {};<br>    let book_ref = &amp;book; // &#39;book_ref&#39; is a reference to &#39;book&#39;<br>    <br>    // Prints the Book value.<br>    debug::print(book_ref); <br><br>    // Prints the Book value (because &#39;book_ref&#39; and &#39;&amp;book&#39; both refer to the same data).<br>    debug::print(&amp;book);    <br>}</pre><p>Here, book_ref is a reference to book. It points to the same data in memory. No new Book object is created. Both book_ref and book can be used.</p><p><strong>Mutable References:</strong></p><p>You can also create mutable references, which allow you to modify the original data:</p><pre>public struct Book has drop {<br>    pages: u64,<br>}<br><br>public fun borrowing_mut() {<br>    let mut book = Book { pages: 100 }; // &#39;book&#39; is mutable<br>    let book_ref = &amp;mut book; // &#39;book_ref&#39; is a mutable reference to &#39;book&#39;<br><br>    book_ref.pages = 1000; // Modifying through the reference<br><br>    debug::print(&amp;book_ref.pages); // Prints 1000<br>    debug::print(&amp;book.pages);     // Prints 1000 (because it&#39;s the same book)<br>}</pre><p>Because book_ref is a <em>mutable</em> reference (&amp;mut), we can change the pages field, and this change is reflected when we access book directly because they both point to the same data.</p><h3><strong>Learn More:</strong></h3><p>To deepen your Move knowledge, explore the official documentation: <a href="https://move-language.github.io/move/">https://move-language.github.io/move/</a> or enroll in my Sui Move development course: <a href="https://academy.eincode.com/courses/sui-dapps-with-move-react-build-real-projects">https://academy.eincode.com/courses/sui-dapps-with-move-react-build-real-projects</a></p><h3><strong>Conclusion:</strong></h3><p>Congratulations! You’ve now covered 11 essential concepts for working with Move on Sui. Understanding these fundamentals is a significant step towards becoming a proficient Sui developer. Remember that practice is key. The more you code in Move, the more comfortable you’ll become with its unique features and powerful capabilities.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=39299763959c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/eincode/learn-move-for-sui-11-key-concepts-explained-simply-39299763959c">Learn Move for Sui: 11 Key Concepts Explained Simply</a> was originally published in <a href="https://medium.com/eincode">Eincode</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Mastering the Multi-Layer Perceptron (MLP) for Image Classification]]></title>
            <link>https://medium.com/eincode/mastering-the-multi-layer-perceptron-mlp-for-image-classification-a0272baf1e29?source=rss----96930c935cba---4</link>
            <guid isPermaLink="false">https://medium.com/p/a0272baf1e29</guid>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[neural-networks]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <dc:creator><![CDATA[Filip Jerga]]></dc:creator>
            <pubDate>Thu, 12 Sep 2024 18:42:29 GMT</pubDate>
            <atom:updated>2024-09-12T18:42:29.626Z</atom:updated>
            <content:encoded><![CDATA[<h4>A Step-by-Step Guide to Building and Training Neural Networks Using the MNIST Dataset</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZHWEh1Cm7ULVIHMnLyouIA.png" /></figure><p>In machine learning, one of the most fundamental tasks is image classification. <strong>Multi-Layer Perceptrons (MLPs)</strong> provide an excellent foundation to understand how neural networks work. MLPs are a type of neural network composed of multiple layers of neurons, making them capable of learning complex relationships in data. In this blog post, we’ll explore how MLPs function and how to use them to classify images from the famous MNIST dataset, which contains handwritten digits.</p><h3>First, Resources!</h3><p><strong>This blog article is based on this course:</strong> <a href="https://eincode.com/courses/master-neural-networks-build-with-javascript-and-react">https://eincode.com/courses/master-neural-networks-build-with-javascript-and-react</a></p><p><strong>Github Repo (Full Code):</strong> <a href="https://github.com/Jerga99/neural-network-course">https://github.com/Jerga99/neural-network-course</a></p><h3>What is a Multi-Layer Perceptron (MLP)?</h3><p>A <strong>Multi-Layer Perceptron (MLP)</strong> is a type of artificial neural network consisting of multiple layers of neurons. It’s called “multi-layer” because it includes an <strong>input layer</strong>, one or more <strong>hidden layers</strong>, and an <strong>output layer</strong>.</p><ul><li><strong>Input Layer</strong>: This layer receives the raw data. In the case of image classification, each neuron in the input layer represents one pixel. For a 28x28 image, the input layer would have 784 neurons. This layer simply passes the data to the next layer without modification.</li><li><strong>Hidden Layers</strong>: These layers perform the heavy lifting of the model. Each neuron in a hidden layer receives input from the previous layer, computes a weighted sum of these inputs, adds a bias, and passes the result through an <strong>activation function</strong> like <strong>ReLU</strong>. ReLU introduces non-linearity, allowing the network to capture complex patterns.</li><li><strong>Output Layer</strong>: The output layer generates the final prediction. For classification tasks, the output layer has one neuron per class (e.g., 10 neurons for digits 0–9 in MNIST). The <strong>softmax</strong> function converts the raw scores into probabilities, and the class with the highest probability is chosen as the prediction.</li></ul><p>MLPs are <strong>fully connected</strong>, meaning each neuron in one layer is connected to every neuron in the next. The goal of training an MLP is to adjust the weights and biases to minimize the prediction error.</p><h3>Practical Example: Classifying MNIST Digits</h3><p>To demonstrate how MLPs work in practice, we’ll walk through a simple application: classifying handwritten digits from the MNIST dataset. MNIST consists of 28x28 grayscale images of digits (0–9), and the goal is to build a model that correctly identifies these digits.</p><h3>Step 1: Preparing the Data</h3><p>Data preparation is crucial before feeding the data into the MLP. Let’s look at how this works with the MNIST dataset:</p><ol><li><strong>Flatten the Images</strong>: MNIST images are 28x28 pixels. Since MLPs expect a vector as input, each image is “flattened” into a 1D array of 784 pixels.</li><li><strong>Normalize Pixel Values</strong>: Pixel values in images range from 0 to 255. To make training more efficient, we normalize them to values between 0 and 1 by dividing by 255. This keeps the weights from getting too large and improves the learning process.</li><li><strong>One-hot Encode the Labels</strong>: MNIST labels are digits from 0 to 9. We need to convert them into a format the network can understand for classification. One-hot encoding is a method where each label is transformed into a binary vector. For example, the digit “3” becomes [0, 0, 0, 1, 0, 0, 0, 0, 0, 0]. The network outputs probabilities for each class, and the position with the highest value corresponds to the predicted digit.</li></ol><p><strong>Pseudo code for normalization and one-hot encoding (Full Code in “Resources”)</strong></p><pre>Normalize data:<br>  for each image in dataset:<br>    for each pixel in image:<br>      pixel_value = pixel_value / 255  # Normalize pixel values to range [0, 1]<br><br>One-hot encode labels:<br>  for each label in dataset:<br>    create a vector of length 10 filled with zeros<br>    set the position of the correct label to 1</pre><h3>Step 2: Building the MLP Model</h3><p>An MLP typically has multiple layers of neurons. For this task, we’ll build a model with:</p><ol><li><strong>Input Layer</strong>: 784 neurons (one for each pixel in the flattened image).</li><li><strong>Hidden Layer</strong>: 64 neurons. This layer uses an activation function called <strong>ReLU (Rectified Linear Unit)</strong>. ReLU introduces non-linearity to the model, which is important for learning complex patterns in the data.</li><li><strong>Output Layer</strong>: 10 neurons, one for each possible digit (0–9). This layer uses the <strong>softmax</strong> activation function, which converts the raw output into probabilities that sum to 1. The class with the highest probability is chosen as the predicted label.</li></ol><p><strong>Pseudo code for model structure (Full Code in “Resources”):</strong></p><pre>MLP structure:<br>  Input Layer: 784 neurons<br>  Hidden Layer: 64 neurons, activation = ReLU<br>  Output Layer: 10 neurons, activation = Softmax</pre><h3>What is ReLU?</h3><p>The <strong>ReLU</strong> activation function is defined as f(x) = max(0, x). It helps introduce non-linearity into the network because without it, the MLP would just be a linear model, which wouldn’t be able to solve complex problems. ReLU keeps all negative values at 0 and passes through positive values, which helps the network focus on important features.</p><p><strong>Softmax</strong> ensures that the output values represent probabilities, i.e., values between 0 and 1 that sum to 1.</p><h3>Step 3: Forward Propagation (Making Predictions)</h3><p>Forward propagation is the process by which the network makes a prediction. During this step, the input data is passed through the network, and the model computes the output probabilities.</p><ol><li><strong>Input to Hidden Layer</strong>: The input data (a flattened image) is multiplied by the weights and biases of the hidden layer, and the result is passed through the ReLU activation function. This creates the hidden layer’s activation values.</li><li><strong>Hidden Layer to Output Layer</strong>: The output of the hidden layer is passed to the output layer, where a similar process occurs. The final output is passed through the softmax activation function, which produces a probability distribution across the 10 possible classes (0–9).</li></ol><p><strong>Pseudo code for forward propagation</strong>:</p><pre>Forward pass:<br>  for each neuron in hidden layer:<br>    hidden_sum = sum(input[i] * weight[i]) + bias<br>    hidden_activation = ReLU(hidden_sum)<br><br>  for each neuron in output layer:<br>    output_sum = sum(hidden_activation[j] * weight[j]) + bias<br>    output_probabilities = Softmax(output_sum)</pre><p>The result of forward propagation is the network’s prediction, which is a probability distribution across the 10 possible digits.</p><h3>Step 4: Backpropagation (Learning from Errors)</h3><p>Backpropagation is the learning phase of the network. After making a prediction in the forward pass, the network calculates the error by comparing the prediction to the actual label. It then “propagates” this error backward through the network to update the weights and biases, minimizing future errors.</p><ol><li><strong>Calculate the Error</strong>: The error (or loss) is calculated by comparing the predicted output with the actual label. One commonly used loss function for classification is <strong>Mean Squared Error (MSE)</strong>, which measures how far the predictions are from the correct values.</li><li><strong>Compute Gradients</strong>: Backpropagation uses a method called <strong>gradient descent</strong> to adjust the weights and biases. The gradient tells us how much to change each weight to reduce the error. The network computes these gradients by calculating the partial derivatives of the loss function with respect to each weight and bias.</li><li><strong>Update Weights and Biases</strong>: Once the gradients are computed, the network updates the weights and biases to reduce the error. The learning rate controls how large these updates are. A smaller learning rate results in slower but more precise adjustments, while a larger learning rate speeds up learning but can overshoot the optimal weights.</li></ol><p><strong>Pseudo code for backpropagation</strong>:</p><pre>Backward pass:<br>  for each output neuron:<br>    calculate output error = predicted - target<br>    compute gradient for output weights and biases using the error<br><br>  for each hidden neuron:<br>    calculate hidden error = sum(output errors * weights)<br>    compute gradient for hidden weights and biases using hidden error<br><br>Update weights:<br>  for each weight:<br>    weight = weight - learning_rate * gradient</pre><p>This process is repeated for each training sample. Over time, as the network adjusts its weights and biases, it learns to make better predictions.</p><h3>Step 5: Training the MLP</h3><p>The training process involves running forward propagation and backpropagation for multiple epochs (iterations over the entire dataset). With each epoch, the network becomes better at making accurate predictions.</p><ol><li><strong>Epochs</strong>: An epoch refers to one complete pass through the entire training dataset. Typically, training is done for several epochs (e.g., 30–50).</li><li><strong>Mini-batches</strong>: Instead of updating the weights after every single training example (which can be slow), the dataset is divided into smaller mini-batches. The weights are updated after each mini-batch, speeding up training while still making accurate adjustments.</li></ol><p><strong>Pseudo code</strong>:</p><pre>Train the model:<br>  for each epoch:<br>    shuffle training data<br>    for each mini-batch:<br>      perform forward propagation<br>      compute the loss<br>      perform backpropagation<br>      update the weights and biases</pre><h3>Step 6: Testing the Model</h3><p>Once the model is trained, it’s important to evaluate its performance on unseen data (the test set). This allows us to measure how well the model generalizes to new data.</p><p>Testing the model involves running forward propagation on the test set and calculating the accuracy. The model’s accuracy is the percentage of test samples it correctly classifies.</p><p><strong>Pseudo code for testing</strong>:</p><pre>Test the model:<br>  correct_predictions = 0<br>  for each test input:<br>    perform forward propagation<br>    if predicted class == actual class:<br>      correct_predictions++<br><br>  accuracy = correct_predictions / total_test_samples</pre><h3>Why Use MLPs for Image Classification?</h3><p>MLPs are an excellent starting point for building neural networks, especially for beginners. While they are powerful enough to handle various tasks, including image classification, they are not as efficient for image data as Convolutional Neural Networks (CNNs). Still, mastering MLPs is crucial because they lay the groundwork for understanding more advanced architectures. Some key benefits include:</p><ul><li><strong>Simplicity</strong>: MLPs are relatively straightforward to implement, making them a great choice for learning about neural networks.</li><li><strong>Versatility</strong>: They can be used for a wide range of tasks beyond image classification, such as regression and natural language processing.</li><li><strong>Foundation for Deep Learning</strong>: Understanding how MLPs work prepares you to tackle more advanced models like CNNs, RNNs, and deep learning frameworks.</li></ul><h3>Stepping Beyond MLPs</h3><p>Although MLPs are powerful for learning basic neural network concepts, they are less efficient for image data, where spatial relationships between pixels are important. This is where <strong>Convolutional Neural Networks (CNNs)</strong> come in. CNNs are designed to take advantage of the 2D structure of images and are much better suited for large-scale image classification tasks.</p><h3>Learn More in My Course</h3><p>In this blog, we’ve covered the basics of building a Multi-Layer Perceptron for image classification.</p><p>To dive deeper , check out my complete course on neural networks.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a0272baf1e29" width="1" height="1" alt=""><hr><p><a href="https://medium.com/eincode/mastering-the-multi-layer-perceptron-mlp-for-image-classification-a0272baf1e29">Mastering the Multi-Layer Perceptron (MLP) for Image Classification</a> was originally published in <a href="https://medium.com/eincode">Eincode</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Master Neural Networks: The Perceptron]]></title>
            <link>https://medium.com/eincode/master-neural-networks-the-perceptron-65414ba6ba89?source=rss----96930c935cba---4</link>
            <guid isPermaLink="false">https://medium.com/p/65414ba6ba89</guid>
            <category><![CDATA[neural-networks]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Filip Jerga]]></dc:creator>
            <pubDate>Mon, 02 Sep 2024 15:05:25 GMT</pubDate>
            <atom:updated>2024-09-02T15:05:25.605Z</atom:updated>
            <content:encoded><![CDATA[<h4>Learning Perceptrons: A Beginner’s Guide to Neural Networks with JavaScript</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*57QwQNrckjviKo9vRvKUZA.jpeg" /></figure><p>The Perceptron is one of the simplest types of artificial neural networks, and it’s the foundation upon which more complex neural networks are built. In this article, we’ll walk through a basic implementation of a Perceptron in JavaScript, explaining each step in plain language to help you grasp the fundamental concepts. By the end of this post, you’ll have a solid understanding of how a Perceptron works and how it can be used to classify data.</p><h3>Resources First!</h3><p><strong>Complete Perceptron Code</strong>: <a href="https://github.com/Jerga99/neural-network-course/blob/main/perceptron.js">https://github.com/Jerga99/neural-network-course/blob/main/perceptron.js</a></p><p><strong>Full Neural Networks Course:</strong> <a href="https://academy.eincode.com/courses/master-neural-networks-build-with-javascript-and-react">https://academy.eincode.com/courses/master-neural-networks-build-with-javascript-and-react</a></p><h3>What is a Perceptron?</h3><p>At its core, a Perceptron is a simple algorithm that can make predictions based on input data. It’s used for binary classification, meaning it can decide between two classes, like yes/no, true/false, or in our case, whether an object is more like a pencil or an eraser.</p><h3>The Dataset</h3><p>Let’s start with the data. We have two sets of data:</p><ul><li><strong>Training Data</strong>: This is the data we use to train our Perceptron. It consists of inputs (features) and labels (the correct answer for each input).</li><li><strong>Test Data</strong>: After training, we use this data to see how well our Perceptron can predict new, unseen inputs.</li></ul><p>Here’s the data we’re using:</p><pre>// Train Inputs [weight(g), scale size (1–10)]<br>const trainInputs = [<br> [2, 7],<br> [3, 6],<br> [1, 1],<br> [1, 2],<br> [2, 1]<br>];<br><br>// Train Labels<br>const trainLabels = [1,1,0,0,0];<br>const testInputs = [<br> [2, 6], // pencil-like<br> [3, 7], // pencil-like<br> [1, 3], // eraser-like<br> [2, 2], // eraser-like<br> [2, 5] // pencil-like<br>];<br>// Test Labels<br>const testLabels = [1, 1, 0, 0, 1];</pre><ul><li><strong>Inputs</strong>: Each input is a pair of numbers representing an object’s weight (in grams) and its size on a scale from 1 to 10.</li><li><strong>Labels</strong>: Each label is either 1 (pencil-like) or 0 (eraser-like).</li></ul><h3>The Perceptron Model</h3><p>The Perceptron algorithm works by calculating a weighted sum of the input features and then applying an activation function to decide the output. Here’s the basic structure of our Perceptron class:</p><pre>class Perceptron {<br> constructor(learningRate = 0.01) {<br> this.weights = Array(2).fill(0).map(() =&gt; Math.random() * 0.3–0.1);<br> this.bias = 0;<br> this.learningRate = learningRate;<br> }<br><br>activationFunction(sum) {<br> return sum &gt; 0 ? 1 : 0;<br> }<br>}</pre><ul><li><strong>Weights</strong>: These are numbers that determine how important each input feature is.</li><li><strong>Bias</strong>: This is an extra parameter that helps the Perceptron model data that isn’t perfectly centered around the origin.</li><li><strong>Learning Rate</strong>: This controls how much we adjust the weights in each training step.</li></ul><h3>The Training Process</h3><p>Training the Perceptron involves the following steps:</p><ol><li><strong>Calculate the Weighted Sum</strong>: For each input, we multiply each feature by its corresponding weight and add them up. Then, we add the bias to this sum.</li></ol><pre>let sum = this.bias;<br>for (let i = 0; i &lt; inputs.length; i++) {<br>  sum += inputs[i] * this.weights[i];<br>}</pre><p>2. <strong>Apply the Activation Function</strong>: The activation function checks if the weighted sum is greater than 0. If it is, the Perceptron predicts 1, otherwise it predicts 0.</p><pre>const prediction = this.activationFunction(sum);</pre><p>3. <strong>Update Weights and Bias</strong>: If the prediction doesn’t match the actual label, we update the weights and bias to make the Perceptron better at predicting next time.</p><pre>if (label != prediction) {<br>  for (let i = 0; i &lt; this.weights.length; i++) {<br>    this.weights[i] += this.learningRate * (label - prediction) * inputs[i];<br>  }<br>  this.bias += this.learningRate * (label - prediction);<br>}</pre><h3>Training the Perceptron</h3><p>We train the Perceptron over several <strong>epochs</strong>. An epoch means going through the entire training dataset once. Here’s the training loop:</p><pre>const EPOCHS = 3;<br>const perceptron = new Perceptron(0.01);<br><br>for (let epoch = 0; epoch &lt; EPOCHS; epoch++) {<br>  perceptron.train(trainInputs, trainLabels);<br><br>  // Calculate accuracies<br>  const trainingAccuracy = calculateAccuracy(trainInputs, trainLabels);<br>  const testingAccuracy = calculateAccuracy(testInputs, testLabels);<br><br>  console.log(`Epoch ${epoch + 1}`);<br>  console.log(`Training Accuracy: ${trainingAccuracy}%`);<br>  console.log(`Testing Accuracy: ${testingAccuracy}%`);<br>  console.log(&quot;-------------------------------------&quot;)<br>}</pre><ul><li>After each epoch, we calculate the accuracy on both the training data and the test data. This helps us understand how well the Perceptron is learning.</li></ul><h3>Results</h3><p>Finally, we print out the weights and bias after training. These values show how the Perceptron is set up to make predictions:</p><pre>console.log(&quot;weights: &quot; + perceptron.weights);<br>console.log(&quot;bias: &quot; + perceptron.bias);</pre><h3>Training and Testing Accuracy: What Do They Mean?</h3><p>After training your Perceptron, you’ll calculate the accuracy on both the training and test datasets. Here’s what these metrics tell you:</p><ul><li><strong>Training Accuracy</strong>: This measures how well your Perceptron performs on the training data it has seen before. High training accuracy indicates that your model has learned the patterns in the training data effectively.</li><li><strong>Testing Accuracy</strong>: This measures how well your Perceptron performs on new, unseen data (the test set). High testing accuracy suggests that your model can generalize well to new data, which is crucial for any machine learning model.</li></ul><h4><strong>Overfitting vs. Underfitting</strong>:</h4><ul><li><strong>Overfitting</strong>: If your training accuracy is very high but your testing accuracy is low, your model may be overfitting. This means it has learned the training data too well, including noise or irrelevant patterns, and doesn’t perform well on new data.</li><li><strong>Underfitting</strong>: If both training and testing accuracy are low, your model might be underfitting, meaning it hasn’t learned the data well enough. This could be due to insufficient training or a model that’s too simple.</li></ul><h3>Conclusion</h3><p>In this article, we walked through a simple implementation of a Perceptron in JavaScript. We started with a basic understanding of the Perceptron, explored the training process, and then examined the results. The Perceptron is a powerful yet simple tool for binary classification tasks, and understanding it lays the groundwork for more advanced machine learning models.</p><p>Feel free to experiment with the code, tweak the learning rate, or try different datasets. Understanding the basics is key to mastering more complex concepts in machine learning!</p><p><strong>To learn more, check the ‘Resources’ section at the beginning of this article.</strong></p><p>Cheers,</p><p>Filip</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=65414ba6ba89" width="1" height="1" alt=""><hr><p><a href="https://medium.com/eincode/master-neural-networks-the-perceptron-65414ba6ba89">Master Neural Networks: The Perceptron</a> was originally published in <a href="https://medium.com/eincode">Eincode</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Machine Learning: Simple Linear Regression with React JS and Plotly]]></title>
            <link>https://medium.com/eincode/machine-learning-simple-linear-regression-with-react-js-and-plotly-be1e15406181?source=rss----96930c935cba---4</link>
            <guid isPermaLink="false">https://medium.com/p/be1e15406181</guid>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[reactjs]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Filip Jerga]]></dc:creator>
            <pubDate>Wed, 22 May 2024 15:13:03 GMT</pubDate>
            <atom:updated>2024-05-22T15:13:03.222Z</atom:updated>
            <content:encoded><![CDATA[<h4>As developers, integrating data analysis and prediction models is crucial. Learn Simple Linear Regression, a fundamental machine learning technique.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*32oSMGIXTggjaaSN4glb_Q.jpeg" /></figure><h3>Introduction</h3><p>As developers, integrating data analysis and prediction models is crucial. Simple Linear Regression, a fundamental machine learning technique, helps us understand relationships between variables and make predictions. In this post, we’ll implement simple linear regression using React and Plotly, covering the mathematical background and providing step-by-step coding instructions.</p><h3>Resources</h3><p>Full Course: <a href="https://academy.eincode.com/courses/machine-learning-primer-with-js-regression">https://academy.eincode.com/courses/machine-learning-primer-with-js-regression</a></p><p>Full Code: <a href="https://github.com/Jerga99/ML-Regression-vol1">https://github.com/Jerga99/ML-Regression-vol1</a></p><h3>Mathematical Background of Simple Linear Regression</h3><p>Simple Linear Regression is used to predict the value of a dependent variable (<strong>Y</strong>) based on the value of an independent variable (<strong>X</strong>). The relationship between <strong>X</strong> and <strong>Y</strong> is modeled by fitting a linear equation to observed data.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FH-Vuz50HQwGDUlufdeQeg.png" /></figure><p>The linear equation can be represented as:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/382/1*NsKMNhEBoxMAb0gXUItRBw.png" /></figure><p>Where:</p><ul><li><strong>Y</strong> is the dependent variable (exam scores).</li><li><strong>X</strong> is the independent variable (study hours).</li><li><strong>b0</strong>​ is the intercept of the regression line (the value of Y when X is 0).</li><li><strong>b1</strong> is the slope of the regression line (the change in Y for a one-unit change in X).</li></ul><h4>Calculating the Parameters</h4><p>To find the best-fitting line, we need to calculate <strong>b0</strong>​ and <strong>b1</strong>​ using the following formulas:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/416/1*cxE_Op-BCBkHo1-CzLvenw.png" /></figure><p>Where:</p><ul><li><strong>Xi</strong>​ and <strong>Yi​</strong> are the individual sample points.</li><li><strong>x̄ </strong>and <strong>ȳ</strong> are the means of <strong>X</strong> and <strong>Y</strong>, respectively.</li></ul><h3>Setting Up the Data</h3><p>Let’s start by setting up our data in a React component. We’ll use two arrays to represent our study hours and corresponding exam scores.</p><pre>const studyHoursData = [1, 2, 3, 4, 5];<br>const examScoresData = [55, 70, 80, 85, 90];</pre><h3>Calculating the Means</h3><p>The next step is to calculate the means of our data sets.</p><pre>const meanStudyHours = studyHoursData.reduce((sum, val) =&gt; sum + val, 0) / studyHoursData.length;<br>const meanExamScores = examScoresData.reduce((sum, val) =&gt; sum + val, 0) / examScoresData.length;</pre><h3>Building the React Component</h3><p>Now, we’ll build a React component that will perform the regression calculations and display the results using Plotly for visualization.</p><pre>import { useEffect, useState } from &#39;react&#39;;<br>import Plot from &quot;react-plotly.js&quot;;</pre><pre>function ExamScorePrediction() {<br>  const [regressionLine, setRegressionLine] = useState([]);<br>  const [regressionParams, setRegressionParams] = useState({b0: 0, b1: 0});<br>  const [inputHours, setInputHours] = useState(&quot;&quot;);<br>  const [predictedScore, setPredictedScore] = useState(null);<br><br>  const data = [{<br>    x: studyHoursData,<br>    y: examScoresData,<br>    mode: &quot;markers&quot;,<br>    type: &quot;scatter&quot;,<br>    marker: { color: &quot;blue&quot; }<br>  }, {<br>    x: studyHoursData,<br>    y: regressionLine,<br>    mode: &quot;lines&quot;,<br>    type: &quot;scatter&quot;,<br>    name: &quot;Regression Line&quot;,<br>    line: {color: &quot;red&quot;}<br>  }];<br><br>  const layout = {<br>    title: &quot;Study hours vs Exam Scores&quot;,<br>    xaxis: {<br>      title: &quot;Study hours&quot;,<br>      autorange: true,<br>    },<br>    yaxis: {<br>      title: &quot;Exam scores&quot;,<br>      autorange: true,<br>    },<br>  }<br><br>  useEffect(() =&gt; {<br>    if (inputHours === &quot;&quot;) {<br>      setPredictedScore(null);<br>    } else if (parseFloat(inputHours) &gt;= 0) {<br>      const score = regressionParams.b0 + regressionParams.b1 * parseFloat(inputHours);<br>      setPredictedScore(score &lt;= 100 ? score.toFixed(2) : 100);<br>    }<br>  }, [inputHours, regressionParams]);<br><br>  useEffect(() =&gt; {<br>    trainModel();<br>  }, []);<br><br>  useEffect(() =&gt; {<br>    if (regressionParams.b0 &gt; 0 &amp;&amp; regressionParams.b1 &gt; 0) {<br>      // Model Testing<br>      const predictionsFromInputs = studyHoursData.map((x) =&gt; regressionParams.b0 + regressionParams.b1 * x);<br>      const residuals = predictionsFromInputs.map((y, i) =&gt; examScoresData[i] - y);<br><br>      const ssResiduals = residuals.reduce((sum, residual) =&gt; sum + Math.pow(residual, 2), 0);<br>      const ssTotal = examScoresData.reduce((sum, score) =&gt; sum + Math.pow(score - meanExamScores, 2), 0);<br><br>      const r2 = 1 - (ssResiduals / ssTotal);<br>      const mae = residuals.reduce((sum, residual) =&gt; sum + Math.abs(residual), 0) / residuals.length;<br>      const mse = residuals.reduce((sum, residual) =&gt; sum + Math.pow(residual, 2), 0) / residuals.length;<br><br>      console.log(mse);<br>      console.log(mae)<br>      console.log(r2);<br>    }<br>  }, [regressionParams]);<br><br>  const trainModel = () =&gt; {<br>    // Step 1 - Compute means<br>    // Step 2 - Compute Slope (B1, m)<br>    const numerator = studyHoursData.reduce((sum, hour, i) =&gt; sum + (hour - meanStudyHours) * (examScoresData[i] - meanExamScores), 0);<br>    const denominator = studyHoursData.reduce((sum, hour) =&gt; sum + Math.pow(hour - meanStudyHours, 2) ,0);<br>    const b1 = numerator / denominator;<br>    const b0 = meanExamScores - b1 * meanStudyHours;<br><br>    const regressionYs = studyHoursData.map(x =&gt; b0 + b1 * x);<br>    setRegressionLine(regressionYs);<br>    setRegressionParams({b0, b1});<br>  }<br><br><br>  return (<br>    &lt;div&gt;<br>      &lt;div style={{textAlign: &quot;center&quot;}}&gt;<br>        &lt;input<br>          type=&quot;number&quot;<br>          value={inputHours}<br>          onChange={(e) =&gt; {<br>            setInputHours(e.target.value);<br>          }}<br>          placeholder=&quot;Enter study hours&quot;<br>          style={{marginBottom: 10}}<br>        /&gt;<br>        { predictedScore &amp;&amp;<br>          &lt;div&gt;<br>            Predicted exam score: {predictedScore}<br>          &lt;/div&gt;<br>        }<br>        &lt;div&gt;b0: {regressionParams.b0}&lt;/div&gt;<br>        &lt;div&gt;b1: {regressionParams.b1}&lt;/div&gt;<br>      &lt;/div&gt;<br>      &lt;Plot<br>        style={{width: &quot;100%&quot;, height: 500}}<br>        data={data}<br>        layout={layout}<br>      /&gt;<br>    &lt;/div&gt;<br>  );<br>}<br><br>export default ExamScorePrediction;<br><br></pre><h3>Code Explanation</h3><h4>Component State and Data</h4><ul><li><strong>State Variables:</strong></li><li>regressionLine: Stores the y-values of the regression line.</li><li>regressionParams: Holds the slope (<strong>b1</strong>) and intercept (<strong>b0</strong>) of the regression line.</li><li>inputHours: Keeps track of the user&#39;s input for study hours.</li><li>predictedScore: Stores the predicted exam score based on the input hours.</li><li><strong>Data for Plotly:</strong></li><li>We create two objects in the data array: one for the scatter plot of the original data points and one for the regression line.</li></ul><h4>Layout for Plotly</h4><ul><li><strong>Layout Object:</strong></li><li>Defines the title and axis labels for the plot to provide a clear and informative visualization.</li></ul><h4>useEffect Hooks</h4><ul><li><strong>Predicted Score Calculation:</strong></li><li>This hook updates the predicted score whenever inputHours or regressionParams changes. If the input is valid, it calculates the predicted score using the regression equation and updates the state.</li><li><strong>Model Training:</strong></li><li>This hook calls the trainModel function to calculate the regression parameters when the component mounts.</li><li><strong>Logging Metrics:</strong></li><li>This hook calculates and logs regression metrics (<strong>MSE</strong>, <strong>MAE</strong>, <strong>R2</strong>) whenever the regression parameters are updated, helping us evaluate the model’s performance.</li></ul><h4>Train Model Function</h4><ul><li><strong>Training the Model:</strong></li><li>Calculates the slope (<strong>b1</strong>) and intercept (<strong>b0</strong>) using the formulas for simple linear regression.</li><li>Computes the y-values for the regression line and updates the state with these values and the regression parameters.</li></ul><h3>Explaining the trainModel Function</h3><p>The trainModel function is the core part of the code where the simple linear regression model is trained. This involves calculating the slope (<strong>b1</strong>) and intercept (<strong>b0</strong>) of the regression line, which are then used to predict the dependent variable based on the independent variable. Let&#39;s break down each step of the function:</p><h3>1. Compute Means</h3><p>Before calculating the slope and intercept, we need the means of the independent (study hours) and dependent (exam scores) variables, which are precomputed as meanStudyHours and meanExamScores.</p><h3>2. Compute the Slope (b1)</h3><p>The slope (<strong>b1</strong>) indicates the change in the dependent variable for a one-unit change in the independent variable. It is calculated using the formula:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/390/1*GouOr9wKYhX1cMYZ7OtyfA.png" /></figure><p>In the code:</p><pre>const numerator = studyHoursData.reduce((sum, hour, i) =&gt; sum + (hour - meanStudyHours) * (examScoresData[i] - meanExamScores), 0);</pre><ul><li><strong>Numerator Calculation:</strong></li><li>This line calculates the sum of the product of the deviations of each data point from their respective means.</li><li>hour - meanStudyHours: The deviation of each study hour from the mean study hours.</li><li>examScoresData[i] - meanExamScores: The deviation of each exam score from the mean exam scores.</li><li>The product of these deviations is summed up for all data points.</li></ul><pre>const denominator = studyHoursData.reduce((sum, hour) =&gt; sum + Math.pow(hour - meanStudyHours, 2), 0);</pre><ul><li><strong>Denominator Calculation:</strong></li><li>This line calculates the sum of the squared deviations of each study hour from the mean study hours.</li><li>Math.pow(hour - meanStudyHours, 2): The square of the deviation of each study hour from the mean.</li><li>These squared deviations are summed up for all data points.</li></ul><pre>const b1 = numerator / denominator;</pre><ul><li>The slope <strong>b1</strong> is then calculated as the ratio of the numerator to the denominator.</li></ul><h3>3. Compute the Intercept (b0)</h3><p>The intercept (b0) is the value of the dependent variable when the independent variable is zero. It is calculated using the formula:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/356/1*UFw5xRCs_igghEuJTHOFyg.png" /></figure><p>In the code:</p><pre>const b0 = meanExamScores - b1 * meanStudyHours;</pre><ul><li>The intercept <strong>b0</strong> is computed by subtracting the product of the slope (<strong>b1</strong>) and the mean of the independent variable (<strong>meanStudyHours</strong>) from the mean of the dependent variable (<strong>meanExamScores</strong>).</li></ul><h3>4. Compute the Regression Line Values</h3><p>Using the slope (<strong>b1</strong>) and intercept (<strong>b0</strong>), we can now calculate the predicted values (<strong>y-values</strong>) for the regression line.</p><pre>const regressionYs = studyHoursData.map(x =&gt; b0 + b1 * x);</pre><ul><li><strong>Predicted Values:</strong></li><li>This line computes the predicted exam scores (regressionYs) for each study hour in the dataset.</li><li>For each study hour <strong>x</strong>, the predicted value is calculated as <strong>b0+b1⋅x</strong>.</li></ul><h3>5. Update State</h3><p>Finally, we update the state with the calculated regression line values and parameters.</p><pre>setRegressionLine(regressionYs);<br>setRegressionParams({b0, b1});</pre><ul><li><strong>setRegressionLine:</strong> Updates the state with the array of predicted values (regressionYs), which will be used to plot the regression line.</li><li><strong>setRegressionParams:</strong> Updates the state with the calculated slope (<strong>b1</strong>) and intercept (<strong>b0</strong>).</li></ul><h3>Understanding R², MAE, and MSE in Simple Linear Regression</h3><p>When evaluating the performance of a regression model, it’s crucial to understand how well the model’s predictions align with the actual data. Three common metrics used for this purpose are the <strong>R² (R-squared) value</strong>, the <strong>Mean Absolute Error (MAE)</strong>, and the <strong>Mean Squared Error (MSE)</strong>. Let’s break down these metrics and see how they are calculated and interpreted.</p><h3>1. R-squared (R²)</h3><p>R², also known as the coefficient of determination, measures the proportion of the variance in the dependent variable that is predictable from the independent variable. It ranges from 0 to 1, where:</p><ul><li><strong>0</strong> means that the model does not explain any of the variance in the dependent variable.</li><li><strong>1</strong> means that the model explains all the variance in the dependent variable.</li></ul><h4>Calculation of R²</h4><p>The formula for R² is:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/382/1*JrRUT6Oa-y1nkuHPMDMM8g.png" /></figure><p>Where:</p><ul><li><strong>SSresidual</strong>​ is the sum of squares of residuals, which measures the variance of the residuals (the difference between observed and predicted values).</li><li><strong>SStotal</strong>​ is the total sum of squares, which measures the total variance in the observed data.</li></ul><p>In the code:</p><pre>const ssResiduals = residuals.reduce((sum, residual) =&gt; sum + Math.pow(residual, 2), 0);<br>const ssTotal = examScoresData.reduce((sum, score) =&gt; sum + Math.pow(score - meanExamScores, 2), 0);<br>const r2 = 1 - (ssResiduals / ssTotal);</pre><ul><li>ssResiduals is calculated by summing the squared residuals.</li><li>ssTotal is calculated by summing the squared differences between each observed value and the mean of the observed values.</li><li>r2 is then computed as 1 − (ssResiduals / ssTotal​).</li></ul><h3>2. Mean Absolute Error (MAE)</h3><p>MAE measures the average magnitude of the errors in a set of predictions, without considering their direction. It is the average over the absolute differences between the predicted and actual values. MAE gives an idea of how wrong the predictions were on average.</p><h4>Calculation of MAE</h4><p>The formula for MAE is:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/514/1*K-vvNrgxV_0o3dvJgMjf5w.png" /></figure><p>Where:</p><ul><li><strong>n</strong> is the number of observations.</li><li><strong>yi</strong> is the actual value.</li><li><strong>ŷi</strong>​ is the predicted value.</li></ul><p>In the code:</p><pre>const mae = residuals.reduce((sum, residual) =&gt; sum + Math.abs(residual), 0) / residuals.length;</pre><ul><li>mae is calculated by summing the absolute values of the residuals and then dividing by the number of observations.</li></ul><h3>3. Mean Squared Error (MSE)</h3><p>MSE measures the average of the squares of the errors — that is, the average squared difference between the estimated values and the actual value. It gives a sense of the variance of the prediction errors.</p><h4>Calculation of MSE</h4><p>The formula for MSE is:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/510/1*Kf-YFT4XbjiAl5j036OhiQ.png" /></figure><p>In the code:</p><pre>const mse = residuals.reduce((sum, residual) =&gt; sum + Math.pow(residual, 2), 0) / residuals.length;</pre><ul><li>mse is calculated by summing the squared residuals and then dividing by the number of observations.</li></ul><h3>Conclusion</h3><p>By following this detailed guide, you now have a comprehensive understanding of how to implement simple linear regression in a React application using Plotly for visualization. We’ve covered the mathematical background, data setup, and step-by-step code explanation to ensure you grasp the core concepts and practical implementation.</p><p>Feel free to experiment with the code and dataset to gain a deeper understanding of how linear regression works and how it can be applied in different scenarios. As developers, integrating such statistical methods into our applications can significantly enhance data analysis and predictive capabilities. Happy coding!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=be1e15406181" width="1" height="1" alt=""><hr><p><a href="https://medium.com/eincode/machine-learning-simple-linear-regression-with-react-js-and-plotly-be1e15406181">Machine Learning: Simple Linear Regression with React JS and Plotly</a> was originally published in <a href="https://medium.com/eincode">Eincode</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Simple Image Upload with Firebase in Next.js]]></title>
            <link>https://medium.com/eincode/simple-image-upload-with-firebase-in-next-js-0a9163dbf126?source=rss----96930c935cba---4</link>
            <guid isPermaLink="false">https://medium.com/p/0a9163dbf126</guid>
            <category><![CDATA[firebase]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[nextjs]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Filip Jerga]]></dc:creator>
            <pubDate>Fri, 17 May 2024 06:38:18 GMT</pubDate>
            <atom:updated>2024-05-17T06:40:00.425Z</atom:updated>
            <content:encoded><![CDATA[<h4>In this tutorial, we’ll walk through the steps to create a simple image upload feature using Firebase and Next.js. This guide is perfect for beginners who want to enhance their web development skills by integrating Firebase into a Next.js project.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Lx9HeNJjMaD1vxjcB7u52Q.png" /></figure><h3>Introduction</h3><p>Uploading images is a common feature in many web applications. By using Firebase and Next.js, we can create a robust and efficient image upload system. Firebase provides a scalable backend solution, while Next.js offers a powerful framework for building React applications.</p><p>In this post, we’ll cover:</p><ul><li>Setting up a Firebase project</li><li>Integrating Firebase with Next.js</li><li>Implementing the image upload functionality</li><li>Viewing uploaded images in a gallery</li></ul><h3>Resources</h3><p>Video Tutorial:<a href="https://youtu.be/Y-kwlvhR7Z0">https://youtu.be/Y-kwlvhR7Z0</a></p><p>Full Courses: <a href="https://academy.eincode.com/">https://academy.eincode.com/</a></p><h3>Prerequisites</h3><p>Before we begin, make sure you have the following:</p><ul><li>Basic knowledge of React and Next.js</li><li>A Firebase account</li><li>Node.js and npm installed on your machine</li></ul><h3>Step 1: Setting Up Firebase</h3><p>First, you need to create a Firebase project. Follow these steps:</p><ol><li>Go to the Firebase Console.</li><li>Click on “Add project” and follow the prompts to create a new project.</li><li>Once your project is created, navigate to the “Storage” section and click on “Get started” to enable Firebase Storage.</li></ol><p>Next, you’ll need to add a Firebase configuration file to your Next.js project:</p><ol><li>Click on the “Settings” icon in the Firebase Console and select “Project settings”.</li><li>Under “Your apps”, click on the web icon to create a new web app.</li><li>Copy the Firebase configuration object.</li></ol><h3>Step 2: Integrating Firebase with Next.js</h3><p>Create a new Next.js project if you don’t already have one:</p><pre>npx create-next-app next-firebase-image-upload<br>cd next-firebase-image-upload</pre><p>Install Firebase:</p><pre>npm install firebase</pre><p>Create a firebaseConfig.js file in the src/app directory and add the Firebase configuration:</p><pre>// src/app/firebaseConfig.js<br><br>import { initializeApp } from &quot;firebase/app&quot;;<br>import { getStorage } from &quot;firebase/storage&quot;;<br><br>// Your Firebase configuration object<br>const firebaseConfig = {<br>  apiKey: &quot;your_api_key&quot;,<br>  authDomain: &quot;your_auth_domain&quot;,<br>  projectId: &quot;your_project_id&quot;,<br>  storageBucket: &quot;your_storage_bucket&quot;,<br>  messagingSenderId: &quot;your_messaging_sender_id&quot;,<br>  appId: &quot;your_app_id&quot;<br>};<br><br>// Initialize Firebase app<br>const app = initializeApp(firebaseConfig);<br><br>// Get a reference to the storage service<br>const storage = getStorage(app);<br><br>export { storage };</pre><h3>Step 3: Creating the Home Page</h3><p>Create a page.js file in the src/app directory to serve as the home page:</p><pre>import Link from &quot;next/link&quot;;</pre><pre>export default function Home() {<br>  return (<br>    &lt;main&gt;<br>      &lt;h1&gt;Welcome to Image Upload App!&lt;/h1&gt;<br>      &lt;nav&gt;<br>        &lt;ul&gt;<br>          {/* Link to the Upload Image page */}<br>          &lt;li&gt;&lt;Link href=&quot;/upload&quot;&gt;Upload Image&lt;/Link&gt;&lt;/li&gt;<br>          {/* Link to the Gallery page */}<br>          &lt;li&gt;&lt;Link href=&quot;/gallery&quot;&gt;View Gallery&lt;/Link&gt;&lt;/li&gt;<br>        &lt;/ul&gt;<br>      &lt;/nav&gt;<br>    &lt;/main&gt;<br>  );<br>}</pre><h3>Step 4: Implementing the Image Upload Page</h3><p>Create an upload/page.js file in the src/app directory to handle image uploads:</p><pre>&quot;use client&quot;<br><br>import Image from &quot;next/image&quot;;<br>import { useState } from &quot;react&quot;;<br>import { ref, uploadBytes, getDownloadURL } from &quot;firebase/storage&quot;;<br>import { storage } from &quot;../firebaseConfig&quot;;<br><br>export default function Upload() {<br>  const [file, setFile] = useState(null); // State to store the selected file<br>  const [uploading, setUploading] = useState(false); // State to indicate the upload status<br>  const [uploadedUrl, setUploadedUrl] = useState(null); // State to store the uploaded image URL<br><br>  const handleFileChange = (event) =&gt; {<br>    setFile(event.target.files[0]); // Set the selected file<br>  };<br><br>  const handleUpload = async () =&gt; {<br>    if (!file) return; // Return if no file is selected<br><br>    setUploading(true); // Set uploading state to true<br>    const storageRef = ref(storage, `images/${file.name}`); // Create a reference to the file in Firebase Storage<br><br>    try {<br>      await uploadBytes(storageRef, file); // Upload the file to Firebase Storage<br>      const url = await getDownloadURL(storageRef); // Get the download URL of the uploaded file<br>      setUploadedUrl(url); // Set the uploaded image URL<br>      console.log(&quot;File Uploaded Successfully&quot;);<br>    } catch (error) {<br>      console.error(&#39;Error uploading the file&#39;, error);<br>    } finally {<br>      setUploading(false); // Set uploading state to false<br>    }<br>  };<br><br>  return (<br>    &lt;div&gt;<br>      &lt;input type=&quot;file&quot; onChange={handleFileChange} /&gt; {/* File input to select the image */}<br>      &lt;button onClick={handleUpload} disabled={uploading}&gt;<br>        {uploading ? &quot;Uploading...&quot; : &quot;Upload Image&quot;} {/* Button to upload the image */}<br>      &lt;/button&gt;<br>      {uploadedUrl &amp;&amp; (<br>        &lt;div&gt;<br>          &lt;p&gt;Uploaded image:&lt;/p&gt;<br>          &lt;Image<br>            src={uploadedUrl}<br>            alt=&quot;Uploaded image&quot;<br>            width={300}<br>            height={300}<br>            layout=&quot;responsive&quot;<br>          /&gt;<br>        &lt;/div&gt;<br>      )}<br>    &lt;/div&gt;<br>  );<br>}</pre><h3>Step 5: Creating the Gallery Page</h3><p>Create a gallery/page.js file in the src/app directory to display uploaded images:</p><pre>&quot;use client&quot;<br><br>import { listAll, ref, getDownloadURL } from &quot;firebase/storage&quot;;<br>import { useEffect, useState } from &quot;react&quot;;<br>import { storage } from &quot;../firebaseConfig&quot;;<br>import Image from &quot;next/image&quot;;<br><br>export default function Gallery() {<br>  const [images, setImages] = useState([]); // State to store the list of image URLs<br><br>  useEffect(() =&gt; {<br>    const fetchImages = async () =&gt; {<br>      const imagesRef = ref(storage, &quot;images/&quot;); // Reference to the images directory in Firebase Storage<br><br>      try {<br>        const result = await listAll(imagesRef); // List all items in the images directory<br>        const urls = await Promise.all(result.items.map(item =&gt; getDownloadURL(item))); // Get the download URLs for all images<br>        setImages(urls); // Set the list of image URLs<br>      } catch (error) {<br>        console.error(&quot;Error fetching images&quot;, error);<br>      }<br>    };<br><br>    fetchImages(); // Fetch images when the component mounts<br>  }, []);<br><br>  return (<br>    &lt;div&gt;<br>      &lt;h1&gt;Gallery&lt;/h1&gt;<br>      &lt;div style={{ display: &quot;flex&quot;, flexDirection: &quot;row&quot; }}&gt;<br>        {images.map((url, index) =&gt; (<br>          &lt;div key={url} style={{ margin: 10, position: &#39;relative&#39;, width: &#39;300px&#39;, height: &#39;500px&#39; }}&gt;<br>            &lt;Image<br>              src={url}<br>              alt={`Image ${index}`}<br>              sizes=&quot;300px&quot;<br>              fill<br>              style={{<br>                objectFit: &#39;contain&#39;,<br>              }}<br>            /&gt;<br>          &lt;/div&gt;<br>        ))}<br>      &lt;/div&gt;<br>    &lt;/div&gt;<br>  );<br>}</pre><h3>Conclusion</h3><p>You now have a simple image upload feature integrated into your Next.js application using Firebase. This setup includes the ability to upload images and view them in a gallery. You can expand this with additional functionality like user authentication, file metadata, and more advanced error handling.</p><p>Feel free to check out the <a href="https://github.com/Jerga99/next-firebase-image-upload">GitHub repository</a> for the complete code.</p><p>If you found this tutorial helpful, please give it a clap and share it with others. Stay tuned for more tutorials and tips on web development!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=0a9163dbf126" width="1" height="1" alt=""><hr><p><a href="https://medium.com/eincode/simple-image-upload-with-firebase-in-next-js-0a9163dbf126">Simple Image Upload with Firebase in Next.js</a> was originally published in <a href="https://medium.com/eincode">Eincode</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Python & Turtle: A Practical Guide for Beginners and Beyond]]></title>
            <link>https://medium.com/eincode/python-turtle-a-practical-guide-for-beginners-and-beyond-3154ba19c2b7?source=rss----96930c935cba---4</link>
            <guid isPermaLink="false">https://medium.com/p/3154ba19c2b7</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[python-programming]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[algorithms]]></category>
            <dc:creator><![CDATA[Filip Jerga]]></dc:creator>
            <pubDate>Tue, 21 Nov 2023 15:34:02 GMT</pubDate>
            <atom:updated>2023-11-21T15:34:02.421Z</atom:updated>
            <content:encoded><![CDATA[<h4>Learn Python language practically and build a game with the Turtle module—a blog post about Eincode’s new course.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Os0WN_lgYDaF1sPoFlXeyQ.jpeg" /></figure><p>Greetings, aspiring developers and coding enthusiasts! If you’ve ever been curious about the world of programming, I’ve got the perfect adventure lined up for you. Introducing our Python &amp; Turtle: A Practical Guide for Beginners and Beyond— a dynamic journey designed for beginners and early-stage developers looking for a hands-on, practical introduction to Python.</p><h3>Course</h3><p><a href="https://bit.ly/3R9unow">https://bit.ly/3R9unow</a></p><p>Let me start with why you should consider learning Python.</p><h3>1. Python’s Readability: The Language of Clarity</h3><p>One of Python’s standout features is its readability. Code is often described as “executable pseudocode,” making it clear and concise. This readability not only makes Python an excellent language for beginners but also enhances collaboration among developers. Dive into Python, and you’ll find yourself in a coding environment that feels almost like reading plain English.</p><h3>2. Versatility: A Language for Every Realm</h3><p>Python isn’t confined to a single domain; it’s a versatile language that transcends boundaries. Whether you’re delving into web development, data analysis, machine learning, artificial intelligence, games or automation, Python is your trusty companion. Explore how Python seamlessly adapts to various applications, opening up a world of possibilities for developers.</p><h3>3. Pythonic Zen: Embracing Elegance and Simplicity</h3><p>The Python community has a set of guiding principles known as the Zen of Python. These principles emphasize the beauty of simplicity, readability, and elegance in code. Discover how embracing the Pythonic way can elevate your coding experience, emphasizing the importance of clarity and straightforward solutions.</p><h3>4. The Power of Libraries: A Developer’s Arsenal</h3><p>Python boasts an extensive library ecosystem that empowers developers to achieve more with less effort. From Django for web development to TensorFlow for machine learning, Python libraries are a treasure trove of tools. Uncover how tapping into this rich library ecosystem can supercharge your projects and streamline your development journey.</p><h3>5. Python’s Role in Cutting-Edge Technologies</h3><p>Python isn’t just a language; it’s at the forefront of cutting-edge technologies. Explore its pivotal role in machine learning and artificial intelligence. Delve into how Python is driving innovation in fields like data science, where it has become the go-to language for analysis and visualization.</p><h3>6. Community and Collaboration: Pythonic Bonds</h3><p>Joining the Python community means stepping into a world of collaboration and support. Discover how the community’s inclusive nature fosters learning and growth. From local meetups to global conferences, Python enthusiasts come together to share knowledge, solve problems, and celebrate the beauty of coding in Python.</p><h3>What’s in Store for You?</h3><p>In the first leg of our journey, we’ll explore the core concepts of Python programming. We won’t bore you with mundane lectures; instead, expect engaging sessions that lay a strong foundation for your Python journey. From variables and simple data types to hands-on assignments in string manipulation and conditional statements, I am here to sharpen your coding skills.</p><p>As we progress, we’ll delve into crucial topics such as loops, iterations, functions, and debugging techniques. This isn’t just about learning the syntax; it’s about developing problem-solving skills that are crucial for becoming a proficient Python developer. Real-world Code Interview assignments, including Fibonacci sequences and sorting algorithms, will be your playground.</p><p>Next up, get ready for a deep dive into object-oriented programming. We’re dedicating a substantial part of the course to classes, methods, and inheritance — consider this your passport to the more exciting and advanced topics waiting for you later on.</p><p>Now, let’s make it visual! Explore the Turtle module for captivating visuals, graphics, and visualization. Ever dreamt of creating your own game? We’re introducing advanced concepts like update loops, delta times, and movement, all using pure Python code. It’s not just about coding; it’s about creating and bringing your ideas to life.</p><p>In the final sections of the course, user interfaces take center stage. Learn to create a simple interface, complete with text display, buttons, and event handling. Unleash the power of lambda functions in Python, adding a valuable tool to your coding toolkit. Cap it off with a hands-on final project — your chance to showcase what you’ve learned in the world of game development.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3154ba19c2b7" width="1" height="1" alt=""><hr><p><a href="https://medium.com/eincode/python-turtle-a-practical-guide-for-beginners-and-beyond-3154ba19c2b7">Python &amp; Turtle: A Practical Guide for Beginners and Beyond</a> was originally published in <a href="https://medium.com/eincode">Eincode</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Next.js / React with ChatGPT]]></title>
            <link>https://medium.com/eincode/next-js-react-with-chatgpt-5a5450bcf1ef?source=rss----96930c935cba---4</link>
            <guid isPermaLink="false">https://medium.com/p/5a5450bcf1ef</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[chatgpt]]></category>
            <category><![CDATA[ai]]></category>
            <dc:creator><![CDATA[Filip Jerga]]></dc:creator>
            <pubDate>Fri, 05 May 2023 17:10:47 GMT</pubDate>
            <atom:updated>2023-05-05T17:10:47.301Z</atom:updated>
            <content:encoded><![CDATA[<p>Learn how to integrate the ChatGPT model into your javascript application.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9RUrfC7Av1uUujMf9a96RA.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/@ilgmyzin?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">ilgmyzin</a> on <a href="https://unsplash.com/photos/agFmImWyPso?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><h3>1. Setup</h3><p>Clone or download the initial project</p><p><a href="https://github.com/Jerga99/nextjs-chatgpt-integration">https://github.com/Jerga99/nextjs-chatgpt-integration</a></p><p>The whole setup is explained in the <strong>readme</strong> file</p><p>If you are more interested in a video tutorial, watch my youtube video explaining the same stuff.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FdmM83DhzE98%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DdmM83DhzE98&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FdmM83DhzE98%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/7afabfcf8b72487c7b488877ed04e91b/href">https://medium.com/media/7afabfcf8b72487c7b488877ed04e91b/href</a></iframe><p>Ok, let’s get to work! After you initialize the project, you should have this basic layout.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1Po0VI00BMZa8tVKGO0MLQ.png" /><figcaption>The base layout of the application</figcaption></figure><h3>2. Get prompt data</h3><p>All changes will be performed in <strong>src/pages/index.js</strong></p><pre>export default function Home() {<br>  const [prompt, setPrompt] = useState(&quot;&quot;);<br><br>  return (<br>    &lt;div className=&quot;container&quot;&gt;<br>      &lt;div className=&quot;inputContainer&quot;&gt;<br>        &lt;textarea<br>          onChange={(e) =&gt; {<br>            setPrompt(e.target.value);<br>          }} <br>          value={prompt}<br>          placeholder=&quot;Ask a question&quot; <br>          rows={3} <br>        /&gt;<br>      &lt;/div&gt;<br>      ... rest of the template<br>    &lt;/div&gt;<br>  )<br>}</pre><p>The critical part is providing <strong>onChange</strong> to textarea to store values in the prompt state. Now when a user writes to textarea, values get stored.</p><h3><strong>3. Simulate messaging</strong></h3><p>As we submit the prompt, we want to display the message in the UI. Also, we want to simulate the response from ChatGPT. For now, the response will be just some hardcoded string.</p><pre>export default function Home() {<br>  const [prompt, setPrompt] = useState(&quot;&quot;);<br>  const [messages, setMessages] = useState([]);<br><br>  const handleSubmit = async () =&gt; {<br>    if (prompt.trim().length === 0) {<br>      return;<br>    }<br><br>    setMessages((messages) =&gt; [...messages, {<br>      text: prompt.trim(),<br>      id: new Date().toISOString(),<br>      author: &quot;human&quot;<br>    }]);<br><br>    setPrompt(&quot;&quot;);<br><br>    await new Promise((res) =&gt; setTimeout(res, 1000));<br><br>    setMessages((messages) =&gt; [...messages, {<br>      text: &quot;Just some hardcoded response bla bla bla...&quot;,<br>      id: new Date().toISOString(),<br>      author: &quot;ai&quot;<br>    }]);<br>  }<br><br>  return (<br>    &lt;div className=&quot;container&quot;&gt;<br>      &lt;div className=&quot;inputContainer&quot;&gt;<br>        &lt;textarea<br>          onChange={(e) =&gt; {<br>            setPrompt(e.target.value);<br>          }} <br>          value={prompt}<br>          placeholder=&quot;Ask a question&quot; <br>          rows={3} <br>        /&gt;<br>        &lt;button <br>          onClick={handleSubmit}<br>          className=&quot;submit&quot;&gt;Submit<br>        &lt;/button&gt;<br>      &lt;/div&gt;<br>      ... rest of the template<br>    &lt;/div&gt;<br>  )<br>}</pre><p>Let’s add the state to store the messages first.</p><pre>const [messages, setMessages] = useState([]);</pre><p>Next, we add the function <strong>handleSubmit</strong>, which gets called when a user clicks the submit button.</p><p>Let’s talk about this function. First, we ensure that we provide the data in the prompt. If the prompt is empty, we return early from the function.</p><p>Next, we set a new message to the state of messages. The first message stored is a user prompt.</p><p>The message has this format:</p><pre>{<br>  text: string; // message value<br>  id: string; // Identifier, for example new date<br>  author: &quot;human&quot; | &quot;ai&quot;; // author can be human or ai<br>}</pre><p>After the first message is added, we will wait for 1000ms (1 sec) to simulate the delay of getting a response from a server.</p><p>After that, we store the AI hardcoded message. We are done in this section.</p><h3>4. Display messages</h3><p>We stored the messages in the state but didn’t display them.</p><p>Create a new component to display a message.</p><pre>function MessageItem({message}) {<br>  const [text, setText] = useState(message.author === &quot;human&quot; ? message.text : &quot;&quot;);<br><br>  useEffect(() =&gt; {<br>    setTimeout(() =&gt; {<br>      setText(message.text.slice(0, text.length + 1));<br>    }, 10);<br>  }, [text, message.text]);<br><br>  return (<br>    &lt;div className=&quot;answer&quot;&gt;<br>      &lt;div className={`author author-${message.author}`}&gt;<br>        {message.author}:<br>      &lt;/div&gt;<br>      &lt;div className=&quot;message&quot;&gt;<br>        {text}<br>      &lt;/div&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><p>Now map the <strong>messages</strong> and display them in the return of the <strong>Home</strong> function.</p><pre>&lt;div className=&quot;container&quot;&gt;<br>  &lt;div className=&quot;inputContainer&quot;&gt;<br>    &lt;textarea<br>      onChange={(e) =&gt; {<br>        setPrompt(e.target.value);<br>      }} <br>      value={prompt}<br>      placeholder=&quot;Ask a question&quot; <br>      rows={3} <br>    /&gt;<br>    &lt;button <br>      onClick={handleSubmit}<br>      className=&quot;submit&quot;&gt;Submit<br>    &lt;/button&gt;<br>  &lt;/div&gt;<br>  &lt;div className=&quot;answers&quot;&gt;<br>    {messages.map(message =&gt; <br>      &lt;MessageItem <br>        key={message.id} <br>        message={message} <br>      /&gt;<br>    )}<br>  &lt;/div&gt;<br>&lt;/div&gt;</pre><h3>5. API Endpoint</h3><p>We need to create an API endpoint to send the prompt to and get a response from ChatGPT.</p><p>In <strong>pages/api/ </strong>folder<strong> </strong>add a new file called <strong>completion.js</strong></p><pre><br>export default async function handler(req, res) {<br>  if (req.method === &quot;POST&quot;) {<br>    const prompt = req.body.prompt || &quot;&quot;;<br><br>    if (!process.env.OPENAI_SECRET_KEY) {<br>      return res.status(500).json({error: {message: &quot;Api key is not provided!&quot;}});<br>    }<br><br>    if (prompt.trim().length === 0) {<br>      return res.status(400).json({error: {message: &quot;Provide prompt value!&quot;}});<br>    }<br><br>    try {<br>      const RESULT = &quot;Just some hardcoded response bla bla bla...&quot;;<br><br>      return res.status(200).json({result: completion.data.choices[0].text});<br>    } catch (e) {<br>      return res.status(400).json({error: {message: e.message}});<br>    }<br><br>  } else {<br>    return res.status(500).json({error: {message: &quot;Invalid Api Route!&quot;}});<br>  }<br>}</pre><p>A straightforward code. We first get the prompt data from the request body.</p><p>If there are non, we return the error.</p><p>Similarly, we returned the error if we didn’t set up <strong>OPENAI_SECRET_KEY</strong> (which we didn’t yet).</p><p>Finally, if all went well, we sent back a hardcoded response.</p><p>We are not calling this endpoint yet, so let’s fix it!</p><h3>6. Call the endpoint</h3><p>Back in <strong>pages/index.js</strong></p><p>Call the endpoint in <strong>handleSubmit</strong></p><pre>const handleSubmit = async () =&gt; {<br>  if (prompt.trim().length === 0) {<br>    return;<br>  }<br><br>  setMessages((messages) =&gt; [...messages, {<br>    text: prompt.trim(),<br>    id: new Date().toISOString(),<br>    author: &quot;human&quot;<br>  }]);<br><br>  setPrompt(&quot;&quot;);<br>  const response =  await fetch(&quot;/api/completion&quot;, {<br>    method: &quot;POST&quot;,<br>    headers: {<br>      &quot;Content-type&quot;: &quot;application/json&quot;<br>    },<br>    body: JSON.stringify({prompt: prompt.trim()})<br>  });<br><br>  const json = await response.json();<br><br>  if (response.ok) {<br>    console.log(json.result);<br><br>    setMessages((messages) =&gt; [...messages, {<br>      text: json.result,<br>      id: new Date().toISOString(),<br>      author: &quot;ai&quot;<br>    }]);<br>  } else {<br>    console.warn(json?.error?.message);<br>  }<br>}</pre><p>In the fetch function, we specify the URL of the endpoint and provide the prompt data.</p><p>Not let’s pass this data to the ChatGPT model.</p><h3>7. Setup OpenAI API</h3><p>To communicate with ChatGPT, we first need to get an API key.</p><p>Get this key on the following link: <a href="https://platform.openai.com/account/api-keys">https://platform.openai.com/account/api-keys</a></p><p>In the project’s root folder, create a <strong>.env</strong> file and provide the API key you got from OpenAI.</p><pre>OPENAI_SECRET_KEY=your_key</pre><p>Then in <strong>completion.js</strong>, on top of the file, prepare the configuration.</p><pre>const configuration = new Configuration({<br>  apiKey: process.env.OPENAI_SECRET_KEY<br>});<br><br>const openAi = new OpenAIApi(configuration);</pre><h3>8. Call the model</h3><p>Here is the final part</p><pre>import { Configuration, OpenAIApi } from &quot;openai&quot;;<br><br>const configuration = new Configuration({<br>  apiKey: process.env.OPENAI_SECRET_KEY<br>});<br><br>const openAi = new OpenAIApi(configuration);<br><br>export default async function handler(req, res) {<br>  if (req.method === &quot;POST&quot;) {<br>    const prompt = req.body.prompt || &quot;&quot;;<br><br>    if (!process.env.OPENAI_SECRET_KEY) {<br>      return res.status(500).json({error: {message: &quot;Api key is not provided!&quot;}});<br>    }<br><br>    if (prompt.trim().length === 0) {<br>      return res.status(400).json({error: {message: &quot;Provide prompt value!&quot;}});<br>    }<br><br>    try {<br>      const completion = await openAi.createCompletion({<br>        model: &quot;text-davinci-003&quot;,<br>        prompt: prompt,<br>        temperature: 0.7,<br>        max_tokens: 1024<br>      });<br><br>      return res.status(200).json({result: completion.data.choices[0].text});<br>    } catch (e) {<br>      return res.status(400).json({error: {message: e.message}});<br>    }<br><br>  } else {<br>    return res.status(500).json({error: {message: &quot;Invalid Api Route!&quot;}});<br>  }<br>}</pre><p>In the <strong>try </strong>block, we call <strong>createCompletion,</strong> providing the prompt data and some other parameters (learn more about <a href="https://platform.openai.com/playground">parameters</a>).</p><p>The model will respond with an answer which we provide back in the server response; this way, we get the response back to the client application where we display it.</p><p>Now you should be able to get the actual answer:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*oIlinZ-ExtAencMXz7ysIQ.gif" /></figure><p>And that’s it! To learn more, you can watch the complete course:</p><p><a href="https://academy.eincode.com/courses/next-js-with-chatgpt-development-guide">Next.js with ChatGPT - Development Guide</a></p><p>Thank you.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5a5450bcf1ef" width="1" height="1" alt=""><hr><p><a href="https://medium.com/eincode/next-js-react-with-chatgpt-5a5450bcf1ef">Next.js / React with ChatGPT</a> was originally published in <a href="https://medium.com/eincode">Eincode</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>