<?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[Stories by noryx on Medium]]></title>
        <description><![CDATA[Stories by noryx on Medium]]></description>
        <link>https://medium.com/@noryx?source=rss-9fa87ef1654c------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*aVDnGc7V-Gy2ksrK8qCO_w.jpeg</url>
            <title>Stories by noryx on Medium</title>
            <link>https://medium.com/@noryx?source=rss-9fa87ef1654c------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 02:20:07 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@noryx/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Defining a Novel and Authorship in the Time of AI]]></title>
            <link>https://medium.com/philosophytoday/defining-a-novel-and-authorship-in-the-time-of-ai-6c080f8074ae?source=rss-9fa87ef1654c------2</link>
            <guid isPermaLink="false">https://medium.com/p/6c080f8074ae</guid>
            <category><![CDATA[literature]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[writing]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[philosophy]]></category>
            <dc:creator><![CDATA[noryx]]></dc:creator>
            <pubDate>Fri, 24 Apr 2026 10:41:01 GMT</pubDate>
            <atom:updated>2026-04-24T10:41:01.620Z</atom:updated>
            <content:encoded><![CDATA[<h4>We don’t just read stories, we look for the human behind them.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*EHlBsPrVOQLU8dDu" /><figcaption>Photo by <a href="https://unsplash.com/@gulfergin_01?utm_source=medium&amp;utm_medium=referral">Gülfer ERGİN</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>More than half of UK novelists believe artificial intelligence will eventually replace their work entirely, according to a recent University of Cambridge study reported in <a href="https://www.theguardian.com/books/2025/nov/20/more-than-half-of-uk-novelists-believe-ai-will-replace-their-work"><em>The Guardian</em></a>. The research suggests not only anxiety about technological change, but a deeper concern: that AI systems trained on vast amounts of fiction may fundamentally reshape the literary economy, devalue human writing, and flood the market with machine-generated books.</p><p>For many writers, this is no longer a distant speculation. It is already reflected in falling incomes, disputes over copyright, and fears that creative labor is being absorbed into systems trained on unlicensed texts. The question, then, is not simply whether AI can write novels — but what becomes of the novel when it no longer requires a novelist.</p><h4>Beyond Economics: The Question of Authorship</h4><p>Novels are not merely written words. They are forms of lived experience structured through language — attempts to translate feeling, memory, imagination, and perception into narrative form.</p><p>Most novels emerge from lived experience, or from the imaginative reconstruction of experience: relationships, personal contradictions, social observation, and emotional memory, rather than purely engineered plots or optimized storytelling structures.</p><p>This anxiety about authorship is not entirely new. Literary theory has long questioned the idea of the author as the sole origin of meaning. Thinkers such as Roland Barthes and Michel Foucault argued that texts are shaped less by individual intention and more by language, culture, and interpretation. The novel itself has also continually changed across history — from linear realist narratives to modernist stream-of-consciousness and postmodern fragmentation — suggesting that instability, rather than fixed identity, has always been part of the genre.</p><p>For example, when readers engage with authors like Haruki Murakami or Virginia Woolf, they are not only following plots. They are engaging with a particular way of seeing the world, a personal rhythm of thought and language, and an implicit human experience behind the text.</p><p>In this sense, literature is not just content. It is a form of structured subjectivity — a mind expressed through language. This is why authorship matters in novels in a way it often does not in other media. Readers do not simply want a story; they want a voice that carries meaning.</p><h4>AI as a Creative Tool</h4><p>AI is already on the path toward transforming novel writing, but it is unlikely to replace human novelists entirely. Instead, it is more plausible that AI will function as a tool within the creative process — reshaping how stories are drafted, structured, and refined, rather than eliminating the need for human authorship.</p><p>AI can already imitate narrative voice convincingly. It can generate emotional dialogue, symbolic plots, and even philosophical themes. For many readers, especially in popular or genre fiction, this may already be “good enough.”</p><p>From a market perspective, this creates a realistic scenario: AI produces large volumes of fiction quickly, readers consume stories without concern for authorship, and publishing becomes partially automated.</p><h4>Evidence of Literary Anxiety</h4><p><a href="https://www.mctd.ac.uk/wp-content/uploads/2025/11/MCTD-AIAndTheNovel-PolicyBrief-Accessible.html">A study</a> conducted for the Minderoo Centre for Technology and Democracy at the University of Cambridge suggests widespread unease about the speed and scale of AI’s advance into the literary world. Surveying 258 published novelists and 74 industry figures, the research found that just over half (51%) of novelists believe AI could eventually replace their work.</p><p>Many participants also reported concerns that their writing may already have been used — without permission — to train large language models. Beyond financial anxiety, there is a deeper worry: that the meaning of authorship itself is being quietly eroded.</p><p>In this sense, AI may indeed “replace” novelists as producers of content. But replacement in production is not the same as replacement in meaning.</p><h4>Reading as Relationship</h4><p>Reading a novel is often misunderstood as passive consumption. In reality, it is closer to a relationship between reader and author.</p><p>Readers follow authors over time, interpret recurring themes, and connect works to a perceived personality or life experience. The act of reading becomes a way of engaging with another consciousness.</p><p>This is where AI introduces a complication. If there is no lived experience behind the text, what exactly is the reader relating to?</p><p>Even if the story is identical, many readers may still distinguish between a human who meant the story and a system that generated it. That difference may not always affect entertainment value, but it affects perceived depth and authenticity.</p><h4>Personalized Fiction and the End of Shared Texts</h4><p>The most radical possibility is not AI-written books, but personalized novels. In this model, each reader receives a different version of a story tailored to their preferences, emotions, or even life history.</p><p>If this becomes common, literature may lose one of its defining features: the shared text. Two people reading the “same novel” would no longer be reading the same words. At that point, the novel becomes less like a cultural artifact and more like a dynamic simulation of storytelling.</p><h4>Conclusion: What AI Really Challenges</h4><p>The question “Can AI replace novelists?” assumes that novels are stable objects and novelists are replaceable producers of those objects. But AI forces us to reconsider both assumptions.</p><p>It is likely that AI will replace some forms of commercial storytelling, transform how stories are produced and consumed, and blur the boundary between author and reader. However, it is less clear that it will replace the deeper function of novelists as creators of human perspective.</p><p>Ultimately, the issue may not be whether AI can write novels, but whether literature without human intention is still literature in the same sense. In this way, AI does not only challenge novelists — it challenges the idea of authorship itself.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6c080f8074ae" width="1" height="1" alt=""><hr><p><a href="https://medium.com/philosophytoday/defining-a-novel-and-authorship-in-the-time-of-ai-6c080f8074ae">Defining a Novel and Authorship in the Time of AI</a> was originally published in <a href="https://medium.com/philosophytoday">Philosophy Today</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Human–Machine Friendships in the Modern Age]]></title>
            <link>https://medium.com/@noryx/human-machine-friendships-in-the-modern-age-e10afda50f40?source=rss-9fa87ef1654c------2</link>
            <guid isPermaLink="false">https://medium.com/p/e10afda50f40</guid>
            <category><![CDATA[physics]]></category>
            <category><![CDATA[python-programming]]></category>
            <category><![CDATA[bots]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[python]]></category>
            <dc:creator><![CDATA[noryx]]></dc:creator>
            <pubDate>Mon, 06 Apr 2026 11:37:30 GMT</pubDate>
            <atom:updated>2026-04-06T11:58:50.122Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*cR0ySXu9JZiUiOgU" /><figcaption>Photo by <a href="https://unsplash.com/@magnusengo?utm_source=medium&amp;utm_medium=referral">Magnus Engø</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>I got a lot of claps on my early articles. I was happy to see that people had clapped for my articles on medium. But something didn’t feel right.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/913/1*zfc_hdQiqr4u_xdGo--e9A.png" /></figure><p>Even if they understood my article on basic physics programming, thinking that many beautiful women clapped was probably a bit overconfident.</p><p>I don’t know why my first four articles received claps from those accounts. But in my later posts, the number started to decrease. In my most recent article, I got only one from a similar account.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XSvqRHOdpatXLFgqnewDSA.png" /></figure><p>Yes, they are all just bots, as explained in the article <em>‘Are Some “Followers” Bots’</em>. Now the question is, how can we trigger them to clap for our articles?</p><p><a href="https://medium.com/@kevin.mcnam/are-some-followers-bots-d12e636ba950">Are Some “Followers” Bots</a></p><p>It’s fascinating to observe the behavior of these automated accounts. They mimic engagement like real readers but without genuine understanding or intent. Some of them may be semi-automated accounts that seem to ‘train’ on your articles manually, producing outrageously long, AI-style comments that try to sound thoughtful and meaningful.</p><p>For me, as someone who loves talking with chatbots, I was excited to see even a bot clap for my post or leave an AI-generated comment. But if you’re a real human reading this, feel free to leave a comment, and I’ll follow you if you’re already following me.</p><p>Will those bots clap for this post? In my early posts, those bots started giving claps within 2–3 days.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e10afda50f40" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Trouble With Jonah]]></title>
            <link>https://medium.com/write-your-world/the-trouble-with-jonah-1c0f6e829dcd?source=rss-9fa87ef1654c------2</link>
            <guid isPermaLink="false">https://medium.com/p/1c0f6e829dcd</guid>
            <category><![CDATA[philosophy]]></category>
            <category><![CDATA[self-love]]></category>
            <category><![CDATA[self-improvement]]></category>
            <category><![CDATA[mental-health-awareness]]></category>
            <category><![CDATA[write-your-world]]></category>
            <dc:creator><![CDATA[noryx]]></dc:creator>
            <pubDate>Wed, 18 Feb 2026 08:53:57 GMT</pubDate>
            <atom:updated>2026-02-18T08:53:57.346Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/630/1*fLrkQByFIql1L7r1vIORCw.jpeg" /><figcaption>The Author and the Sea.</figcaption></figure><p>I drank the holy water.</p><p>At least, that’s what they told me it was.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/430/1*zbRu5aUHPuEm6x1yQjXcjw.jpeg" /><figcaption>Holy Water.</figcaption></figure><p>They said it came from a sacred place, carried across continents in plastic bottles that felt heavier than they should. Not because of the minerals — but because of expectation. One sip, and maybe the soul reboots. One gulp, and maybe the bugs disappear.</p><p>Spoiler: I was still running sinner.exe.</p><p>It made me think about Jonah.</p><p>People love the whale part. The drama. The storm. The lottery on the ship. The cinematic moment when he gets thrown into the sea like unwanted cargo.</p><p>But the real trouble with Jonah wasn’t the ocean.</p><p>It was orbit.</p><p>He was assigned to a people who wouldn’t listen. Imagine speaking truth into a wall of polite indifference. Imagine warning about consequences while everyone scrolls past you. At some point, he left. Not because he stopped believing — but because he was tired of being a satellite.</p><p>You know how it feels to orbit something that doesn’t see you?</p><p>In astronomy, a star shines by itself. A satellite doesn’t. It circles, reflects, depends. It lives in gravitational obedience. If the star collapses, the satellite drifts into cold silence.</p><p>Maybe Jonah was tired of orbiting a mission that felt like it had no light.</p><p>So he boarded a ship.</p><p>And the sea — that ancient debugger — responded.</p><p>The storm wasn’t random. It was interruption. A cosmic pop-up window:</p><p>“Are you sure you want to quit?”</p><p>They cast lots. His name surfaced. Into the water he went.</p><p>We always imagine punishment. But what if it was containment?</p><p>Inside the belly of the great creature, in darkness so complete it erased ego, Jonah finally stopped orbiting his frustration. There was no audience. No crowd. No metrics. No applause. No rejection.</p><p>Just him.</p><p>And God.</p><p>No star. No satellite. Just gravity.</p><p>He didn’t negotiate. He didn’t justify. He didn’t blame the people.</p><p>He said:</p><p>“I was wrong.”</p><p>That was the update.</p><p>Not the water.<br>Not the storm.<br>Not the fish.</p><p>The update was surrender.</p><p>When he was returned to land, it wasn’t random geography. It was the same mission. The same people. The same city.</p><p>But a different orbit.</p><p>And this time, something changed.</p><p>The people listened.</p><p>Maybe the real miracle wasn’t survival inside a fish. Maybe it was this: the star and the satellite finally aligned.</p><p>We spend our lives confused about what we are.</p><p>We want to be stars — self-burning, self-sufficient, undeniable.<br>But most of the time, we are satellites — reflecting borrowed light, circling meaning, hoping not to drift.</p><p>And sometimes we run.</p><p>We swap routines for distractions.<br>We ignore obligations.<br>We call it “self-care.”<br>We rename avoidance as wisdom.</p><p>Trouble with Jonah isn’t about a prophet and a fish.</p><p>It’s about us.</p><p>It’s about the moment we mistake exhaustion for permission.<br>It’s about thinking distance will fix disobedience.<br>It’s about believing holy water will cleanse what only surrender can transform.</p><p>I drank the holy water.</p><p>It didn’t rewrite my destiny.<br>It didn’t delete my flaws.<br>It didn’t silence the storm.</p><p>But it reminded me of something:</p><p>You can’t hydrate your way out of responsibility.</p><p>Sometimes the sea is mercy.<br>Sometimes the belly is protection.<br>Sometimes being thrown overboard is how you’re thrown back into purpose.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*0etuwzTnJ76orYPIFZuiyQ.jpeg" /><figcaption>“Even the Stars Are a Mess” — album by Whitley</figcaption></figure><p>Maybe you’re not a failed star.</p><p>Maybe you’re just a satellite that forgot what it’s orbiting.</p><p>And maybe — just maybe — <br>the trouble with Jonah<br>is the trouble with all of us.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1c0f6e829dcd" width="1" height="1" alt=""><hr><p><a href="https://medium.com/write-your-world/the-trouble-with-jonah-1c0f6e829dcd">The Trouble With Jonah</a> was originally published in <a href="https://medium.com/write-your-world">Write Your World</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Eigenvectors Explained: The Hidden Skeleton of AI and Machine Learning]]></title>
            <link>https://ai.plainenglish.io/eigenvectors-explained-the-hidden-skeleton-of-ai-and-machine-learning-008ae2e9909b?source=rss-9fa87ef1654c------2</link>
            <guid isPermaLink="false">https://medium.com/p/008ae2e9909b</guid>
            <category><![CDATA[artifical-intellegence]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[eigenvectors]]></category>
            <category><![CDATA[python-programming]]></category>
            <dc:creator><![CDATA[noryx]]></dc:creator>
            <pubDate>Mon, 09 Feb 2026 06:34:56 GMT</pubDate>
            <atom:updated>2026-02-23T11:38:50.924Z</atom:updated>
            <content:encoded><![CDATA[<p>If you’re diving into AI or machine learning, you’ll eventually hit a wall called <strong>eigenvectors</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vvB6vYrBAzNswEzr26hGBQ.png" /></figure><p>Eigenvectors show up everywhere: Principal Component Analysis (PCA), dimensionality reduction, spectral methods, and even the internal stability analysis of neural networks.</p><p><strong>Eigenfaces (PCA-based) method is mostly no longer used in modern production face-recognition systems, but it is still very important educationally and sometimes used in lightweight or research scenarios.</strong></p><p>Most explanations lean heavily on dense linear algebra. This one focuses on <strong>intuition first.</strong></p><h3>The Core Idea: Stability in Motion</h3><p>An <strong>eigenvector</strong> is a direction that stays the same when data is transformed. While the data around it might stretch or shrink, that specific direction remains fixed.</p><h3>What “Transformation” Means in AI</h3><p>In machine learning, data is constantly being manipulated through matrix operations:</p><ul><li><strong>Feature Scaling:</strong> Stretching or squishing data ranges</li><li><strong>Rotation/Projection:</strong> Shifting how we look at data points to find patterns</li><li><strong>Compression:</strong> Squashing high-dimensional data into fewer dimensions</li></ul><p>When a matrix transforms your data, most directions shift and tilt. However, a few specific directions remain perfectly aligned with their original path. Those stable directions are your <strong>eigenvectors</strong>.</p><h3>Eigenvalues: The “Volume” Knob</h3><p>If the eigenvector is the <strong>direction</strong>, the <strong>eigenvalue</strong> is the magnitude. It tells you how much the data is being stretched or squished along that specific eigenvector.</p><ul><li><strong>Large Eigenvalue:</strong> This direction captures a lot of information (variance). It’s a “loud” signal</li><li><strong>Small Eigenvalue:</strong> This direction captures very little and might just be “noise.”</li></ul><h3>Real-World Use Cases in Machine Learning</h3><h4>Principal Component Analysis (PCA)</h4><p>PCA is the most famous application of eigenvectors. It uses them to:</p><ul><li>Identify the most informative “paths” through a cloud of data</li><li>Reduce the number of features without losing the “soul” of the dataset</li><li><strong>Pro Tip:</strong> In PCA, the “Principal Components” are simply the eigenvectors of the data’s covariance matrix</li></ul><h4>Data Compression</h4><p>Images and audio contain massive amounts of redundant info. Eigenvectors help systems:</p><ul><li>Preserve the underlying structure (the “edges” of an image)</li><li>Discard the unnecessary fluff, allowing for efficient storage without destroying meaning</li></ul><h4>Neural Network Stability</h4><p>Behind the scenes, neural networks are massive stacks of matrix multiplications. Researchers use eigenvectors to:</p><ul><li>Analyze <strong>training stability</strong> (preventing gradients from exploding or vanishing)</li><li>Understand how information moves through layers</li><li><strong>SVD (Singular Value Decomposition):</strong> A cousin of eigen-decomposition used in recommendation systems (like Netflix) to find hidden patterns in user behavior</li></ul><h4>Example: Seeing the Math in Action</h4><p>The best way to understand this is to see it. Using Python’s NumPy library, we can visualize how an eigenvector refuses to &quot;tilt&quot; even when the space around it is warped.</p><p>Python Code:</p><pre>import numpy as np<br>import matplotlib.pyplot as plt<br><br># 1. Define a transformation matrix (Shear and Stretch)<br>A = np.array([[2, 1], <br>              [1, 2]])<br># 2. Calculate Eigenvalues and Eigenvectors<br>eigenvalues, eigenvectors = np.linalg.eig(A)<br><br># 3. Setup the visualization<br>origin = [0], [0]<br>fig, ax = plt.subplots(figsize=(6, 6))<br><br># Define a &quot;random&quot; vector (this will change direction)<br>v_random = np.array([1, 0])<br>v_random_transformed = A @ v_random<br><br># Define an eigenvector (this should stay on its path)<br>v_eig = eigenvectors[:, 0]<br>v_eig_transformed = A @ v_eig<br><br># 4. Plotting<br>ax.quiver(*origin, v_random[0], v_random[1], color=&#39;r&#39;, angles=&#39;xy&#39;, scale_units=&#39;xy&#39;, scale=1, label=&#39;Random Vector&#39;)<br>ax.quiver(*origin, v_random_transformed[0], v_random_transformed[1], color=&#39;salmon&#39;, angles=&#39;xy&#39;, scale_units=&#39;xy&#39;, scale=1, label=&#39;Transformed Random&#39;)<br>ax.quiver(*origin, v_eig[0], v_eig[1], color=&#39;b&#39;, angles=&#39;xy&#39;, scale_units=&#39;xy&#39;, scale=1, label=&#39;Eigenvector&#39;)<br>ax.quiver(*origin, v_eig_transformed[0], v_eig_transformed[1], color=&#39;skyblue&#39;, angles=&#39;xy&#39;, scale_units=&#39;xy&#39;, scale=1, label=&#39;Transformed Eigenvector&#39;)<br>plt.xlim(-1, 5); plt.ylim(-1, 5); plt.grid(True, linestyle=&#39;--&#39;)<br>plt.legend(); plt.title(&quot;Visualizing Eigenvectors: Directional Stability&quot;)<br>plt.show()</pre><h4>How to Read This Result</h4><p>In the code above, we solve the fundamental equation:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/593/1*_7vMFGhJIisVytrVJERgCQ.png" /></figure><ul><li><strong>The Red Vector:</strong> It was pointing straight right, but after the transformation, it tilted upward. It “lost” its original direction</li><li><strong>The Blue Vector (Eigenvector):</strong> It stays on its original diagonal path. It only grew longer (scaled by its eigenvalue)</li></ul><h3>Mental Models for Mastery</h3><h4>The Spinning Globe</h4><p>Picture a spinning globe.</p><ul><li><strong>The Movement:</strong> Almost every point on the surface is moving in a circle</li><li><strong>The Eigenvector:</strong> The axis running from the North Pole to the South Pole. Despite the rotation, the axis itself stays fixed</li><li><strong>The Eigenvalue:</strong> The speed of the spin. A faster spin means a larger eigenvalue for that transformation</li></ul><h4>The “Skeleton” of Data</h4><p>Imagine a cloud of points representing the height and weight of 1,000 people. The points will form an elongated oval shape.</p><ul><li>The <strong>long axis</strong> of that oval is an eigenvector. It shows the direction of the most variation</li><li>The <strong>short axis</strong> is another eigenvector</li><li>In AI, we often “throw away” the short axis to simplify our model, keeping only the “main” eigenvectors that hold the most information</li></ul><h3>Eigenvectors in Modern AI Systems</h3><p>Even though modern deep learning systems are extremely advanced, <strong>eigenvector-based ideas still play essential roles</strong> across many areas of AI.</p><p><strong>Dimensionality Reduction</strong><br>PCA uses eigenvectors of covariance matrices to compress datasets while preserving the most important information. This remains a standard preprocessing and analysis tool.</p><p><strong>Computer Vision</strong><br>While classical methods like <strong>Eigenfaces</strong> are mostly no longer used in production face-recognition systems, eigenvector analysis is still fundamental to feature extraction, representation learning, and understanding visual variation in data.</p><p><strong>Graph Learning</strong><br>Spectral clustering and graph neural networks rely on eigenvectors of graph Laplacians to reveal structure, connectivity, and communities within graphs.</p><p><strong>Optimization and Training Stability</strong><br>Eigenvalues of Hessian and Jacobian matrices are used to analyze curvature, convergence behavior, and training stability in deep neural networks.</p><p>Eigenvectors quietly guide how machine learning models represent structure, stability, and meaningful variation in complex data , even when they are no longer explicitly visible in the final algorithms.</p><h3>A Real-World Example: Face Recognition (Eigenfaces)</h3><p>One of the most famous applications of eigenvectors is face recognition, often called the <strong>Eigenfaces</strong> method.</p><p>Suppose we collect thousands of face images. Each image may contain <strong>hundreds of thousands of pixel values</strong>, meaning that directly comparing two faces requires processing extremely large vectors. When a system must compare a new face against thousands or millions of stored images, raw-pixel comparison becomes computationally expensive and highly sensitive to noise such as lighting changes, facial expressions, or small pose differences.</p><p>Instead of working directly with raw pixels, we compute <strong>eigenvectors from the entire face dataset</strong>. These eigenvectors capture the main facial variation patterns across all faces, such as:</p><ul><li>Eye regions</li><li>Nose structure</li><li>Face outlines</li><li>Lighting and shadow patterns</li></ul><p>Each face can then be represented not by hundreds of thousands of pixel values, but by a <strong>small set of coefficients</strong> describing how strongly the face aligns with each eigenvector pattern. Recognition systems compare these compact representations rather than full images, making face matching <strong>much faster, more memory-efficient, and more robust</strong>.</p><h3>Simple Example Code (Eigenfaces Concept)</h3><p>Below is a simplified conceptual Python example showing how eigenvectors are used for face recognition using PCA:</p><pre>import numpy as np<br>from sklearn.decomposition import PCA<br>from sklearn.datasets import fetch_olivetti_faces<br><br># 1. Load dataset<br>faces = fetch_olivetti_faces()<br>X = faces.data   # each row = flattened face image<br><br># 2. Reduce dimensionality using eigenvectors (PCA)<br>pca = PCA(n_components=100, whiten=True)<br>X_reduced = pca.fit_transform(X)<br><br># 3. Reconstruct a face using eigenvectors<br>reconstructed = pca.inverse_transform(X_reduced)<br><br>print(&quot;Original shape:&quot;, X.shape)<br>print(&quot;Reduced representation:&quot;, X_reduced.shape)</pre><p>In this example:</p><ul><li>PCA computes the <strong>eigenvectors</strong> of the face dataset</li><li>Each face is converted into a <strong>much smaller vector representation</strong></li><li>Recognition systems compare these compact representations instead of full images</li></ul><p>This dramatically improves speed while preserving important facial information.</p><h3>A Real Eigenfaces Example Using Actual Photos</h3><p>Below is a minimal but real example showing how Eigenfaces-style recognition works with <strong>real face images</strong> using OpenCV and PCA.</p><p>Assume your dataset is organized like this:</p><pre>import cv2<br>import numpy as np<br>import matplotlib.pyplot as plt<br>from sklearn.datasets import fetch_lfw_people<br>from sklearn.decomposition import PCA<br>from sklearn.preprocessing import StandardScaler<br><br># 1. Load dataset from internet<br>lfw = fetch_lfw_people(min_faces_per_person=20, resize=0.4)<br><br>X = lfw.data                # flattened images<br>y = lfw.target              # labels<br>label_map = lfw.target_names<br><br>print(&quot;Dataset shape:&quot;, X.shape)<br><br># 2. Normalize pixel values<br>scaler = StandardScaler()<br>X_scaled = scaler.fit_transform(X)<br><br># 3. PCA (Eigenfaces)<br>n_components = 100<br>pca = PCA(n_components=n_components, whiten=True, random_state=42)<br>X_pca = pca.fit_transform(X_scaled)<br><br>print(&quot;PCA shape:&quot;, X_pca.shape)<br><br># 4. Select a test image<br>test_index = 0<br>test_img = X[test_index]<br>true_label = y[test_index]<br><br>test_scaled = scaler.transform([test_img])<br>test_pca = pca.transform(test_scaled)<br><br># 5. Find closest match<br>distances = np.linalg.norm(X_pca - test_pca, axis=1)<br>match_index = np.argmin(distances)<br><br>print(&quot;True person   :&quot;, label_map[true_label])<br>print(&quot;Matched person:&quot;, label_map[y[match_index]])<br><br># 6. Show the test image<br>plt.imshow(test_img.reshape(lfw.images[0].shape), cmap=&#39;gray&#39;)<br>plt.title(&quot;Test Image&quot;)<br>plt.axis(&#39;off&#39;)<br>plt.show()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/391/1*fJPHgiaF4I3fM37nmTpCXg.png" /></figure><p>In this real-world pipeline:</p><ul><li>Eigenvectors (Eigenfaces) form a <strong>compact facial basis</strong></li><li>Each face becomes a <strong>short numerical signature</strong></li><li>Recognition compares faces in eigenvector space, not pixel space</li></ul><p>This is why eigenvectors were powerful enough to enable <strong>early, practical face recognition systems</strong>, long before modern deep learning models existed.</p><h3>The Hidden Skeleton Analogy</h3><p>Think of machine learning models as living organisms. Data is the flesh, algorithms are the muscles, and <strong>eigenvectors are the skeleton</strong> , the hidden structure that determines shape, stability, and movement.</p><p>You rarely see the skeleton directly, but without it, nothing functions properly.</p><h3>Final Thought</h3><p>Eigenvectors help machine learning models understand what really matters in complex data. They don’t just describe numbers , they reveal the <strong>structure</strong>. Once you see them as the “skeleton” of your data, the confusion fades and their importance in AI becomes clear.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=008ae2e9909b" width="1" height="1" alt=""><hr><p><a href="https://ai.plainenglish.io/eigenvectors-explained-the-hidden-skeleton-of-ai-and-machine-learning-008ae2e9909b">Eigenvectors Explained: The Hidden Skeleton of AI and Machine Learning</a> was originally published in <a href="https://ai.plainenglish.io/">Artificial Intelligence in Plain English</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Build Your Own glTF Viewer with Three.js]]></title>
            <link>https://javascript.plainenglish.io/build-your-own-gltf-viewer-with-three-js-c7bf4bbdce0a?source=rss-9fa87ef1654c------2</link>
            <guid isPermaLink="false">https://medium.com/p/c7bf4bbdce0a</guid>
            <category><![CDATA[threejs]]></category>
            <category><![CDATA[gltf]]></category>
            <category><![CDATA[webgl]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[3d-rendering]]></category>
            <dc:creator><![CDATA[noryx]]></dc:creator>
            <pubDate>Wed, 21 Jan 2026 07:35:48 GMT</pubDate>
            <atom:updated>2026-01-28T17:24:17.340Z</atom:updated>
            <content:encoded><![CDATA[<p>For those new to <strong>glTF</strong>, it’s basically the <strong>JPEG of 3D models</strong> — a compact, standardized format that makes 3D assets fast to load and easy to display on the web. It supports textures, animations, and modern materials, so your 3D models look great without weighing down your site.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gK9rDug43N4J6rnce0qkJg.jpeg" /><figcaption>Avowed Xaurip Spear (<a href="https://avowed.obsidian.net/#media">https://avowed.obsidian.net/#media</a>)</figcaption></figure><p>We’re going to take some glTF models and build our own interactive viewer with Three.js — so you can show 3D content on a website just as easily as you’d drop in an image.</p><p>Before we start <strong>experimenting with glTF viewers in Three.js</strong>, you might want to check out my previous posts: <strong>“</strong><a href="https://medium.com/@noryx/which-is-easier-for-rendering-glb-models-three-js-or-babylon-js-bafdb46c9549"><strong>Which Is Easier for Rendering GLB Models: Three.js or Babylon.js?</strong></a><strong>”</strong> and <strong>“</strong><a href="https://medium.com/@noryx/loading-a-3d-model-in-the-browser-using-javascript-filereader-e97c5ffaf5e1"><strong>Loading a 3D Model in the Browser Using JavaScript FileReader</strong></a><strong>”</strong>. Those articles cover the basics of loading 3D files and comparing rendering engines, which will give you some helpful background as we dive into building our own <strong>glTF</strong> viewer.</p><p><strong>After comparing</strong>, I found that <strong>Babylon.js is actually easier to use and requires less code</strong>, but <strong>Three.js gives me more control</strong>, which lets me build a glTF viewer that’s more user-friendly. That’s why I decided to use <strong>Three.js</strong> to create this web-based glTF viewer.</p><p>The first thing I had to figure out was <strong>how to get a .gltf or .glb file into the browser</strong> so I could render it. As I explained in my previous post, <strong>“</strong><a href="https://medium.com/@noryx/loading-a-3d-model-in-the-browser-using-javascript-filereader-e97c5ffaf5e1"><strong>Loading a 3D Model in the Browser Using JavaScript FileReader</strong></a><strong>”</strong>, I can use <strong>JavaScript’s FileReader</strong> for this.</p><h3>Building the Viewer Core</h3><p>With the <strong>FileReader</strong> handling the file upload, the next step is bringing that data into a 3D environment. To do this, I used <strong>Three.js</strong> to build a scene that acts like a virtual stage, a camera to act as our eyes, and a renderer to draw everything onto the screen.</p><h3>Setting the Scene</h3><p>This block creates the “world” where your 3D models live.</p><pre>const scene = new THREE.Scene();<br>scene.background = new THREE.Color(0x121212);<br><br>const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);<br>camera.position.set(0, 1.5, 12);<br><br>const renderer = new THREE.WebGLRenderer({ antialias: true });<br>renderer.setSize(window.innerWidth, window.innerHeight);<br>document.body.appendChild(renderer.domElement);<br><br>controls = new OrbitControls(camera, renderer.domElement);<br>controls.enableDamping = true;<br><br>// Ensure the camera is looking at the center of the scene (or slightly below)<br>controls.target.set(0, 1.5, 0); <br>controls.update(); // Required after manually changing camera/target</pre><h4><strong>The Scene</strong></h4><p>The Scene is your virtual stage. We set the background to a dark color to make the models pop.</p><h4><strong>The Camera</strong></h4><p>The PerspectiveCamera mimics the human eye—objects get smaller as they move further away, which makes the 3D space feel real.</p><h4><strong>The Renderer</strong></h4><p>This is the engine that draws the pixels. Enabling antialias ensures that the edges of your models are smooth and crisp, rather than &quot;jaggy.&quot;</p><h3>Lighting and Interaction</h3><p>Without light, 3D objects are just black silhouettes. Without controls, you can’t explore the model.</p><pre>scene.add(new THREE.AmbientLight(0xffffff, 1.5));<br><br>const light = new THREE.DirectionalLight(0xffffff, 2);<br>light.position.set(5, 10, 7.5);<br>scene.add(light);<br>const controls = new OrbitControls(camera, renderer.domElement);<br>controls.enableDamping = true;</pre><h4><strong>The Lights</strong></h4><p>I used two types: AmbientLight provides a soft glow so no part of the model is pitch black, and DirectionalLight acts like the sun to create depth, shadows, and highlights.</p><h4><strong>The Controls</strong></h4><p>OrbitControls allows the user to rotate the model by dragging and zoom in with the scroll wheel. enableDamping adds a bit of &quot;inertia,&quot; making the movement feel smooth and professional.</p><h3>The GLTFLoader and Auto-Centering</h3><p>This part takes the raw file data and turns it into a visible object, ensuring it’s positioned correctly.</p><pre>const loader = new GLTFLoader();<br><br>loader.parse(result, &#39;&#39;, (gltf) =&gt; {<br>    currentModel = gltf.scene;<br>    scene.add(currentModel);<br>    // Center and scale model automatically<br>    const box = new THREE.Box3().setFromObject(currentModel);<br>    const center = box.getCenter(new THREE.Vector3());<br>    currentModel.position.sub(center);<br>});</pre><h4>The Loader</h4><p>The GLTFLoader is the translator. It takes the binary data from the FileReader and builds a Three.js group of meshes.</p><h4><strong>The Bounding Box logic</strong></h4><p>Because every 3D model is built at a different scale or offset, I used Box3 to measure the model&#39;s physical dimensions. By calculating the center and subtracting it from the model&#39;s position, the code ensures the object always appears in the middle of the screen.</p><h3>Bringing it to Life with Animations</h3><p>glTF models often come with built-in movements. This logic detects them and lets the user play them.</p><pre>if (animations.length &gt; 0) {<br>    mixer = new THREE.AnimationMixer(currentModel);<br>    const action = mixer.clipAction(animations[0]);<br>    action.play();<br>}</pre><h4><strong>The Animation Mixer</strong></h4><p>Think of the AnimationMixer as a digital DJ. It coordinates all the moving parts (the &quot;bones&quot;) of the model according to the clock.</p><h4><strong>ClipAction</strong></h4><p>This represents a specific movement. If the loader finds animations, it creates a “player” for them and starts the first one automatically.</p><h3>The Render Loop</h3><p>3D isn’t a static image; it’s a series of frames updated so fast it looks like video.</p><pre>const clock = new THREE.Clock();<br><br>function animate() {<br>    requestAnimationFrame(animate);<br>    <br>    if (mixer) mixer.update(clock.getDelta());<br>    controls.update();<br>    renderer.render(scene, camera);<br>}</pre><h4><strong>The Loop</strong></h4><p>requestAnimationFrame tells the browser to run this function roughly 60 times every second. When we talk about “60 times every second,” we are describing the <strong>FPS (Frames Per Second)</strong>.</p><h4><strong>Updating State</strong></h4><p>In every single frame, we tell the mixer (for movement) and controls (for mouse dragging) how much time has passed using the clock. Finally, renderer.render draws the updated view of the stage through the camera lens.</p><h3>The UI Development Part</h3><p>After dealing with JavaScript, let’s move on to the CSS and HTML sections. We made the UI simple, where the user is given the option to drag a glTF file or open a folder here.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZKgkE1xrwkPEmCrj3mdSLA.png" /></figure><p>The CSS code:</p><pre>&lt;style&gt;<br>    html, body { width: 100%; height: 100%; margin: 0; overflow: hidden; font-family: &#39;Segoe UI&#39;, Tahoma, Geneva, Verdana, sans-serif; background-color: #121212; }<br>    canvas { width: 100%; height: 100%; display: block; }<br>    <br>    /* Landing Overlay (Matches your image) */<br>    #landing-overlay {<br>        position: fixed;<br>        top: 0; left: 0;<br>        width: 100%; height: 100%;<br>        background-color: #121212;<br>        display: flex;<br>        flex-direction: column;<br>        align-items: center;<br>        justify-content: center;<br>        z-index: 100;<br>        color: #888;<br>    }<br><br>    .drop-box {<br>        width: 400px;<br>        height: 150px;<br>        background: #1e1e1e;<br>        border-radius: 8px;<br>        display: flex;<br>        align-items: center;<br>        justify-content: center;<br>        font-size: 1.2rem;<br>        margin-bottom: 20px;<br>        border: 2px dashed transparent;<br>        transition: border 0.3s ease;<br>    }<br><br>    /* Visual feedback when dragging over the window */<br>    body.drag-active .drop-box {<br>        border-color: #1a73e8;<br>        color: #1a73e8;<br>    }<br><br>    .choose-file-btn {<br>        background: transparent;<br>        color: #888;<br>        border: none;<br>        cursor: pointer;<br>        display: flex;<br>        align-items: center;<br>        gap: 8px;<br>        font-size: 1rem;<br>    }<br>    .choose-file-btn:hover { color: #fff; }<br><br>    /* Controls Panel (Hidden until model loads) */<br>    .controls-panel {<br>        position: absolute; <br>        top: 15px; right: 15px;<br>        z-index: 10;<br>        display: none; /* Hidden initially */<br>        flex-direction: column; <br>        gap: 10px;<br>        align-items: flex-end;<br>        background: rgba(255, 255, 255, 0.9); <br>        padding: 15px;<br>        border-radius: 8px; <br>    }<br><br>    .anim-section { display: none; flex-direction: column; gap: 5px; border-top: 1px solid #ccc; padding-top: 10px; text-align: right; }<br>    select { padding: 8px; border-radius: 4px; border: 1px solid #ccc; }<br>    label { font-size: 11px; color: #555; font-weight: bold; }<br>  &lt;/style&gt;</pre><p>The HTML code:</p><pre>&lt;div id=&quot;landing-overlay&quot;&gt;<br>    &lt;div class=&quot;drop-box&quot;&gt;<br>        Drag glTF 2.0 file here<br>    &lt;/div&gt;<br>    &lt;button class=&quot;choose-file-btn&quot; onclick=&quot;document.getElementById(&#39;fileInput&#39;).click()&quot;&gt;<br>        &lt;span&gt;⬆&lt;/span&gt; Choose file<br>    &lt;/button&gt;<br>&lt;/div&gt;<br><br>&lt;div class=&quot;controls-panel&quot; id=&quot;uiPanel&quot;&gt;<br>  &lt;button style=&quot;padding: 8px 12px; background: #1a73e8; color: white; border: none; border-radius: 4px; cursor: pointer;&quot; onclick=&quot;document.getElementById(&#39;fileInput&#39;).click()&quot;&gt;Upload New&lt;/button&gt;<br>  <br>  &lt;div id=&quot;animContainer&quot; class=&quot;anim-section&quot;&gt;<br>    &lt;label for=&quot;animSelect&quot;&gt;ANIMATIONS&lt;/label&gt;<br>    &lt;select id=&quot;animSelect&quot;&gt;<br>      &lt;option value=&quot;-1&quot;&gt;Static Pose&lt;/option&gt;<br>    &lt;/select&gt;<br>  &lt;/div&gt;<br>&lt;/div&gt;</pre><p>When the user uploads a model with animation data, a dropdown is also shown to select the animation to play or to display the model in a static pose.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fkB5EGWnopL5GylId3uRrA.gif" /></figure><p>That’s it for now. Maybe you can improve the UI or fix the bug that happens when uploading a model that’s too big or something. Let’s start experimenting and make it better!</p><p>Live preview:</p><p><a href="https://noryx-studio.github.io/gltf-viewer/">Three.js GLB Viewer</a></p><p>The full source code is available on my <a href="https://github.com/noryx-studio/gltf-viewer"><strong>GitHub account</strong></a>, where you can explore, modify, and experiment.</p><p><a href="https://github.com/noryx-studio/gltf-viewer">GitHub - noryx-studio/gltf-viewer</a></p><p>For more tutorials and code examples, you can follow my GitHub account to keep learning, building your own projects, and supporting me!</p><p><strong>Thank you for reading!</strong></p><p>If you have any questions, feel free to ask — I’d be happy to explain more.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c7bf4bbdce0a" width="1" height="1" alt=""><hr><p><a href="https://javascript.plainenglish.io/build-your-own-gltf-viewer-with-three-js-c7bf4bbdce0a">Build Your Own glTF Viewer with Three.js</a> was originally published in <a href="https://javascript.plainenglish.io/">JavaScript in Plain English</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How Python Solves const Without a const Keyword]]></title>
            <link>https://python.plainenglish.io/how-python-solves-const-without-a-const-keyword-f89fcfd0b027?source=rss-9fa87ef1654c------2</link>
            <guid isPermaLink="false">https://medium.com/p/f89fcfd0b027</guid>
            <category><![CDATA[programming-tips]]></category>
            <category><![CDATA[python-programming]]></category>
            <category><![CDATA[python-beginner]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[noryx]]></dc:creator>
            <pubDate>Thu, 15 Jan 2026 18:49:57 GMT</pubDate>
            <atom:updated>2026-01-16T20:34:32.387Z</atom:updated>
            <content:encoded><![CDATA[<p>If you come to Python from JavaScript, Java, C#, C++, or another language, one thing stands out right away: Python has no const keyword. There’s no special syntax for defining constants.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ImELnltt57v4MAoV8wYctw.png" /></figure><p>At first, this can feel like a missing feature—but it’s actually a deliberate design choice. Python handles constants differently.</p><p>Python doesn’t have a const keyword by design, not because it’s missing a feature. It takes a different approach from languages that include const. Python’s philosophy is to be a simple, expressive tool for solving problems, rather than a language that exposes every possible control mechanism, as seen in more complex languages like C++.</p><h3>The Confusion Around const</h3><p>In JavaScript, const is often used to protect a variable from reassignment.</p><pre>const x = 10<br>x = 20 // Error: Assignment to constant variable</pre><p>At first glance, it looks like const makes values completely unchangeable.</p><p>However, objects behave differently.</p><pre>const numbers = [1, 2, 3]<br>numbers.push(4)   // Allowed, array is mutable<br>numbers = [5, 6]  // Error: cannot reassign</pre><p>This shows an important distinction.</p><p>const protects the variable binding, not the object it refers to.</p><p>Python makes this distinction explicit and builds its model around it.</p><h3>Python’s Core Idea: Names and Objects</h3><p>Python does not think in terms of variables holding values. Instead, it works with names and objects.</p><ul><li>Names point to objects</li><li>Objects define whether their contents can change</li></ul><pre>x = 10</pre><p>In this example:</p><ul><li>x is a name</li><li>10 is an object</li></ul><p>Rebinding a name is always allowed.</p><pre>x = 20</pre><p>This behavior is intentional. Reassignment is explicit and easy to reason about.</p><h3>Mutable vs Immutable — The Key Concept</h3><p>Understanding mutability is <strong>essential</strong> to understanding why Python does not need const. For a more complete example, you can see it <a href="https://www.geeksforgeeks.org/python/mutable-vs-immutable-objects-in-python/">here</a>.</p><ul><li>Immutable objects cannot be changed after creation. Any operation that appears to modify them actually creates a new object</li><li>Mutable objects can be changed in place. Modifying them affects the original object</li></ul><p>For example, if we use JavaScript:</p><pre>// Immutable example: strings<br>let text = &quot;hello&quot;<br>text[0] = &quot;H&quot;<br>console.log(text) // &quot;hello&quot;<br><br>// Mutable example: arrays<br>const numbers = [1, 2, 3]<br>numbers.push(4)<br>console.log(numbers) // [1, 2, 3, 4]</pre><p>In Python, the behavior is similar.</p><pre># Immutable: strings<br>s = &quot;hello&quot;<br># s[0] = &quot;H&quot;  # Error: strings are immutable<br><br># Mutable: lists<br>numbers = [1, 2, 3]<br>numbers.append(4)</pre><p>Most bugs that const is meant to prevent come from mutable objects, not from reassignment itself.</p><h3>How Constants Work in Python</h3><p>Python uses naming conventions instead of enforced constants.</p><pre>PI = 3.14159<br>MAX_RETRIES = 5</pre><p>Uppercase names communicate intent. They tell other developers that these values should not be reassigned.</p><p>Python relies on discipline and readability rather than strict enforcement. In practice, this works well.</p><h3>Protecting Mutable Data</h3><p>Problems usually appear when a value is intended to be constant but refers to a mutable object.</p><pre>CONFIG = {&quot;debug&quot;: True}<br>CONFIG[&quot;debug&quot;] = False</pre><p>This is allowed because:</p><ul><li>CONFIG is only a name</li><li>The dictionary is mutable</li></ul><p>Ways to reduce accidental changes:</p><ul><li>Pass copies of objects to functions</li><li>Use immutable types such as tuples or frozensets</li><li>Use MappingProxyType to create read-only dictionary views</li></ul><h3>Passing Values to Functions Safely</h3><p>Immutable values are safe by default.</p><pre>def add_one(x):<br>    x += 1<br><br>n = 10<br>add_one(n)<br>print(n)  # 10</pre><p>Mutable values can be modified unintentionally.</p><pre>def add_item(items):<br>    items.append(4)<br><br>numbers = [1, 2, 3]<br>add_item(numbers)<br>print(numbers)  # [1, 2, 3, 4]</pre><h3>Protecting Data</h3><p>Copy the object before modifying it.</p><pre>def add_item(items):<br>    items = items.copy()<br>    items.append(4)<br>    return items</pre><p>Or use immutable data structures.</p><pre>def add_item(items):<br>    return items + (4,)<br><br>numbers = (1, 2, 3)</pre><h3>Optional: Static Warnings With Final</h3><p>Python provides optional static hints using Final.</p><pre>from typing import Final<br><br>PI: Final = 3.14159</pre><p>This does not prevent runtime changes. It only helps tools like linters and editors warn about unintended reassignment.</p><h3>Why Python’s Approach Works</h3><p>Python is built on a few simple assumptions:</p><ul><li>Reassigning names is usually harmless</li><li>Mutating objects is where most bugs appear</li><li>Clear and explicit code is better than hidden restrictions</li></ul><p>Immutable types, naming conventions, and straightforward patterns remove most of the need for a const keyword.</p><h3>Controlling Shared State with deepcopy</h3><p>Most of the confusion around const actually comes from <strong>mutable objects</strong>, not from reassignment. The real problem is shared state. When two names refer to the same mutable object, changing it through one name affects the other unexpectedly.</p><pre>a = [1, 2, 3]<br>b = a<br><br>b.append(4)<br>print(a)  # [1, 2, 3, 4]</pre><p>Even if the name a is intended to stay constant, the object it points to can still be changed. This is why Python does not rely on const. A keyword that prevents rebinding would not stop this kind of bug.</p><p>Python gives you <strong>explicit tools</strong> to control this behavior. The copy module lets you make a new, independent object. A shallow copy duplicates the outer container but keeps references to the inner objects. A deep copy duplicates everything recursively, breaking all shared references.</p><pre>import copy<br><br>a = [[1, 2], [3, 4]]<br>b = copy.deepcopy(a)<br>b[0].append(99)<br><br>print(a)  # [[1, 2], [3, 4]]<br>print(b)  # [[1, 2, 99], [3, 4]]</pre><p>This makes the behavior obvious: mutation only affects the objects you explicitly choose to change. Nothing happens behind the scenes. Python prefers this <strong>explicit approach</strong> over hidden rules or language-enforced constants.</p><h3>Takeaways</h3><p>This design makes Python a simple and expressive tool for most problems. At the same time, it can feel limiting in situations that require very fine-grained control over objects and memory — the kind of control exposed by more complex languages like C++. In Python, understanding the difference between mutable and immutable objects is essential.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f89fcfd0b027" width="1" height="1" alt=""><hr><p><a href="https://python.plainenglish.io/how-python-solves-const-without-a-const-keyword-f89fcfd0b027">How Python Solves const Without a const Keyword</a> was originally published in <a href="https://python.plainenglish.io/">Python in Plain English</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Ceheng Waterfall Felt Like an Empty Game Map]]></title>
            <link>https://medium.com/no-time/ceheng-waterfall-felt-like-an-empty-game-map-4aaf93d953b7?source=rss-9fa87ef1654c------2</link>
            <guid isPermaLink="false">https://medium.com/p/4aaf93d953b7</guid>
            <category><![CDATA[life]]></category>
            <category><![CDATA[no-time]]></category>
            <category><![CDATA[backyard]]></category>
            <category><![CDATA[forest]]></category>
            <dc:creator><![CDATA[noryx]]></dc:creator>
            <pubDate>Sun, 11 Jan 2026 02:07:07 GMT</pubDate>
            <atom:updated>2026-01-13T08:48:49.661Z</atom:updated>
            <content:encoded><![CDATA[<p>The first thing I noticed wasn’t the view — it was the silence.</p><p>I was alone.</p><p>The forest stretched in every direction, layered with palms and dense vegetation, like a massive open-world map rendered in high detail. Trees stood still, the sky washed in pale light.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Qm13nsuF_fWNQAj8HnBPew.jpeg" /><figcaption>(All images by author).</figcaption></figure><p>The path to Ceheng Waterfall was quiet in a way that didn’t ask for attention. It just existed. Trees lined the hills, layered in different shades of green, stretching farther than the eye could follow. Everything looked alive, yet strangely still.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*z8Nn84Hu5XPyi1BiHkTKZw.jpeg" /></figure><p>The forest felt like a world that had already loaded.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eQL_CnSSxvqBgrAHA0u_ag.jpeg" /></figure><p>There were signs that people had been here before — a narrow trail, a small concrete structure near the path — but nothing moved now. No voices carried through the air. No footsteps followed behind.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WbCuz-aJzwUoJ2o_t0QVJg.jpeg" /></figure><p>Walking through it felt familiar, like exploring an open-world game before the story begins.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EV56mF-90_z2sqOxF9m34g.jpeg" /></figure><p>The environment is detailed, complete, and waiting — but nothing happens unless you move. Every sound suddenly feels louder when there’s nothing else competing with it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZpHnZbDUBqonHKRtPzoodA.jpeg" /></figure><p>Leaves shifted slightly in the breeze, as if it would continue the same way whether anyone was there or not.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Zl6V9TVhkbJiS5TUuOpw7Q.jpeg" /></figure><p>That was the strange comfort of it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LVCMaz8kH468pLfWcpaNYA.jpeg" /></figure><p>For a brief moment, the world felt simple: just a path, a landscape, and the act of being present inside it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9UkfWGHJEToE-grlQs4ahQ.jpeg" /></figure><p>Some places feel most real when they’re quiet.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Uq2LMHjaP8xMaKntAjyevg.jpeg" /></figure><p>And for a moment, this one felt like an empty map — complete, silent, and enough.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*caKTsOIy-dqIqcpw-uDPqQ.jpeg" /></figure><p>The sound of water gradually grew clearer.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-bMg-ukROh8lWtPkxgHZHw.jpeg" /></figure><p>Somewhere along the path, the search stopped mattering. I kept moving without checking anything, letting instinct lead instead of signs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8TCQRJkll_BsFUlhczhWLg.jpeg" /></figure><p>Dirt on my shoes, sweat on my skin, no rush to arrive. If the waterfall wanted to show itself, it would. And if it didn’t, that was fine too.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FPAJWq-CdZ9ztI1Akc6hdQ.jpeg" /></figure><p>Ceheng Waterfall didn’t feel abandoned. It felt untouched — like a place that didn’t need an audience to exist.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*seh3qFGJeLNb6KYHPKu5tQ.jpeg" /></figure><p>The absence of movement didn’t create tension; it created space. Space to notice small details. Space to slow down. Space to breathe without being pulled in any direction.</p><p>Writers, We’d love to have you!!! Join us and share your stories. Let’s Publish it.</p><p><a href="https://medium.com/no-time/no-time-publication-0b759cdf7126">No Time — Publication</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4aaf93d953b7" width="1" height="1" alt=""><hr><p><a href="https://medium.com/no-time/ceheng-waterfall-felt-like-an-empty-game-map-4aaf93d953b7">Ceheng Waterfall Felt Like an Empty Game Map</a> was originally published in <a href="https://medium.com/no-time">No Time</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Understanding Linked Lists as Custom Data Structures in C++]]></title>
            <link>https://medium.com/@noryx/understanding-linked-lists-as-custom-data-structures-in-c-1ea472bedb4f?source=rss-9fa87ef1654c------2</link>
            <guid isPermaLink="false">https://medium.com/p/1ea472bedb4f</guid>
            <category><![CDATA[cpp-programming]]></category>
            <category><![CDATA[data-structure-algorithm]]></category>
            <category><![CDATA[linked-lists]]></category>
            <category><![CDATA[data-structures]]></category>
            <category><![CDATA[algorithms]]></category>
            <dc:creator><![CDATA[noryx]]></dc:creator>
            <pubDate>Wed, 07 Jan 2026 16:29:44 GMT</pubDate>
            <atom:updated>2026-01-11T04:35:54.460Z</atom:updated>
            <content:encoded><![CDATA[<p>Before we start learning about linked lists in C++, you may want to read my <a href="https://medium.com/@noryx/understanding-custom-and-built-in-data-structures-in-c-aafddf822fe7">previous post</a> explaining custom and built-in data structures in C++. That will help you understand what data structures are, especially in C++.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BnYcx16LRlod1xT5jgstmA.jpeg" /><figcaption>The Hydra Canyon (Hercules Action Game PS1 )</figcaption></figure><p>In the previous article, we discussed how <strong>using a </strong><strong>struct in C++ can make code simpler</strong> because members are public by default. This is especially convenient for simple data containers like a Point or a Node in a linked list.</p><p>For example, a basic linked list node using a struct can look like this:</p><pre>struct Node {<br>    int data;<br>    Node* next;<br>};</pre><p>Creating and linking nodes is straightforward:</p><pre>Node* head = new Node{10, nullptr};<br>Node* second = new Node{20, nullptr};<br>head-&gt;next = second;</pre><p>Everything is simple, readable, and easy to follow.</p><h3>So Why Does Hackerrank Use Classes and Look More Complex?</h3><p>Hackerrank’s linked list template can look complicated at first, especially compared to a simple struct-based linked list:</p><pre>class SinglyLinkedListNode {<br>public:<br>    int data;<br>    SinglyLinkedListNode* next;<br>    SinglyLinkedListNode(int node_data) {<br>        this-&gt;data = node_data;<br>        this-&gt;next = nullptr;<br>    }<br>};<br><br>class SinglyLinkedList {<br>public:<br>    SinglyLinkedListNode* head;<br>    SinglyLinkedListNode* tail;<br><br>    SinglyLinkedList() {<br>        this-&gt;head = nullptr;<br>        this-&gt;tail = nullptr;<br>    }<br><br>    void insert_node(int node_data) {<br>        SinglyLinkedListNode* node = new SinglyLinkedListNode(node_data);<br>        if (!this-&gt;head) this-&gt;head = node;<br>        else this-&gt;tail-&gt;next = node;<br>        this-&gt;tail = node;<br>    }<br>};</pre><p>At first glance, it seems more complex than necessary. The design, however, has specific purposes.</p><h3>Object-Oriented Style</h3><p>Hackerrank uses classes to follow object-oriented programming principles. The SinglyLinkedList class encapsulates the logic of the list by automatically tracking the head and tail pointers. The insert_node method ensures nodes are inserted correctly without manually adjusting pointers. Even though the node’s data and next pointer are public, the class separates list operations from individual nodes. This approach makes the code more consistent and professional, especially for teaching and automated testing.</p><h3>Constructors for Safe Node Initialization</h3><p>The constructor in SinglyLinkedListNode guarantees that every node starts with its next pointer set to null:</p><pre>SinglyLinkedListNode(int node_data) {<br>    this-&gt;data = node_data;<br>    this-&gt;next = nullptr;<br>}</pre><p>Without a constructor, you would need to manually initialize the next pointer each time. Constructors reduce repetitive code and make node creation safer.</p><h3>Automatic Tail Management</h3><p>Storing a tail pointer in the SinglyLinkedList class allows insertion at the end of the list in constant time. Without the tail pointer, adding a node would require traversing the entire list, which is less efficient and more error-prone.</p><h3>Using Structs Instead of Classes</h3><p>Structs in C++ can have constructors, methods, and member functions just like classes. The main difference is that struct members are public by default. The same linked list can be implemented with structs:</p><pre>#include &lt;iostream&gt;<br>using namespace std;<br><br>struct SinglyLinkedListNode {<br>    int data;<br>    SinglyLinkedListNode* next;<br><br>    // Constructor<br>    SinglyLinkedListNode(int node_data) {<br>        data = node_data;<br>        next = nullptr;<br>    }<br>};<br><br>struct SinglyLinkedList {<br>    SinglyLinkedListNode* head;<br>    SinglyLinkedListNode* tail;<br><br>    // Constructor<br>    SinglyLinkedList() {<br>        head = nullptr;<br>        tail = nullptr;<br>    }<br><br>    // Insert node at the end<br>    void insert_node(int node_data) {<br>        SinglyLinkedListNode* node = new SinglyLinkedListNode(node_data);<br>        if (!head) head = node;<br>        else tail-&gt;next = node;<br>        tail = node;<br>    }<br>}; <br><br>int main() {<br>    SinglyLinkedList list;<br>    list.insert_node(10);<br>    list.insert_node(20);<br>    list.insert_node(30);<br><br>    SinglyLinkedListNode* current = list.head;<br>    while (current) {<br>        cout &lt;&lt; current-&gt;data &lt;&lt; endl;<br>        current = current-&gt;next;<br>    }<br><br>    // Free memory<br>    current = list.head;<br>    while (current) {<br>        SinglyLinkedListNode* temp = current;<br>        current = current-&gt;next;<br>        delete temp;<br>    }<br><br>    return 0;<br>}</pre><p>This struct-based version behaves exactly the same as the class version, but it is simpler and easier to read.</p><h3>Can We Print Data from the Simplest Linked List Version Like in HackerRank?</h3><p>A question that comes to mind is: can we add data and print it using the simplest version of a linked list, like this?</p><pre>struct Node {<br>    int data;<br>    Node* next;<br>};</pre><p>Yes, we can, simply by using a function like this to add the data:</p><pre>void insertNode(Node*&amp; head, int data) {<br>    Node* newNode = new Node();<br>    newNode-&gt;data = data;<br>    newNode-&gt;next = nullptr;<br><br>    // If the list is empty<br>    if (head == nullptr) {<br>        head = newNode;<br>        return;<br>    }<br><br>    // Traverse to the end<br>    Node* temp = head;<br>    while (temp-&gt;next != nullptr) {<br>        temp = temp-&gt;next;<br>    }<br><br>    temp-&gt;next = newNode;<br>}</pre><p>The *&amp; combination is actually two things:</p><ol><li><strong>*</strong> → This is part of Node*, meaning “pointer to Node.” So Node* head is a pointer to a node.</li><li><strong>&amp;</strong> → This means we are <strong>passing the pointer by reference</strong>.</li></ol><h4>Why do we need &amp; here?</h4><p>If we wrote it like this:</p><pre>void insertNode(Node* head, int data)</pre><ul><li>head is <strong>passed by value</strong>, which means a <strong>copy of the pointer</strong> is made.</li><li>If the list is empty (head == nullptr) and we try to assign head = newNode;, it would only change the <strong>copy</strong> inside the function.</li><li>The original head in main() would <strong>remain nullptr</strong>.</li></ul><p>Example:</p><pre>Node* head = nullptr;<br>insertNode(head, 10); // head stays nullptr if we don&#39;t use &amp;!</pre><p>By using Node*&amp; head, we are <strong>passing the pointer itself by reference</strong>, so any changes to head inside the function <strong>affect the original pointer</strong> in main().</p><h4>Quick analogy</h4><ul><li>Node* head → You have a <strong>copy of the address</strong> of the first node.</li><li>Node*&amp; head → You have a <strong>reference to the original address variable</strong>, so you can change where it points.</li></ul><h4>Without &amp;, you’d have to return the new head:</h4><pre>Node* insertNode(Node* head, int data) {<br>    Node* newNode = new Node();<br>    newNode-&gt;data = data;<br>    newNode-&gt;next = nullptr;<br><br>    if (!head) return newNode; // return new head<br>    <br>    Node* temp = head;    <br>    while (temp-&gt;next != nullptr) temp = temp-&gt;next;<br>    temp-&gt;next = newNode;<br>    <br>    return head;<br>}<br><br>// usage<br>head = insertNode(head, 10);</pre><p>Using *&amp; just <strong>avoids returning</strong> and lets you modify head directly.</p><h4>What if we want to print the data?</h4><p>We can use the same approach we used to solve the <strong>“Print the Elements of a Linked List”</strong> problem on HackerRank.</p><pre>// Function to print the linked list<br>void printLinkedList(Node* head) {<br>    Node* temp = head;<br>    while (temp != nullptr) {<br>        cout &lt;&lt; temp-&gt;data &lt;&lt; endl;<br>        temp = temp-&gt;next;<br>    }<br>}</pre><h3><strong>Okay, Now What Is a Linked List and What Is It Used For?</strong></h3><p>A <strong>linked list</strong> is a way to store a group of data items in order. Instead of keeping everything next to each other in memory (like an array), each item in a linked list is stored in a separate piece called a <strong>node</strong>.</p><p>Each node contains two things:</p><ol><li>The <strong>data</strong> (the value you want to store)</li><li>A <strong>reference (or link)</strong> to the next node in the list</li></ol><p>Because of this, the nodes are connected like a chain.</p><h3>How a Linked List Works</h3><p>A linked list starts with a special node called the <strong>head</strong>. The head points to the first node in the list. Each node then points to the next one, and the last node points to null, which means the list ends there.</p><p>You move through a linked list by following these links, one node at a time.</p><h3>Why Use a Linked List?</h3><p>Linked lists are useful when:</p><ul><li>You need to <strong>add or remove data easily</strong></li><li>You don’t know the size of the data in advance</li><li>You want to avoid shifting elements like you would in an array</li></ul><p>For example, inserting a new element in the middle of an array can be slow because everything after it must move. In a linked list, you only change a few links.</p><h3>Common Uses of Linked Lists</h3><p>Linked lists are often used for:</p><ul><li>Implementing <strong>stacks and queues</strong></li><li>Managing <strong>dynamic memory</strong></li><li>Navigating items (like undo/redo actions)</li><li>Handling large amounts of data where frequent changes are needed</li></ul><h3>Linked Lists vs Arrays (Simple View)</h3><ul><li><strong>Arrays</strong> are fast to access but hard to resize</li><li><strong>Linked lists</strong> are easy to resize but slower to access</li></ul><h3>Final Thoughts</h3><p>A linked list is a simple but powerful data structure. It may not always be the fastest option, but it’s very flexible and great for situations where data changes often.</p><p>Once you understand linked lists, many other data structures become easier to learn.</p><p><strong>Thank you for reading!</strong></p><p>If you have any questions, feel free to ask — I’d be happy to explain more.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1ea472bedb4f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Understanding Custom and Built-in Data Structures in C++]]></title>
            <link>https://medium.com/@noryx/understanding-custom-and-built-in-data-structures-in-c-aafddf822fe7?source=rss-9fa87ef1654c------2</link>
            <guid isPermaLink="false">https://medium.com/p/aafddf822fe7</guid>
            <category><![CDATA[data-structure-algorithm]]></category>
            <category><![CDATA[algorithms]]></category>
            <category><![CDATA[cpp-programming]]></category>
            <category><![CDATA[data-structures]]></category>
            <dc:creator><![CDATA[noryx]]></dc:creator>
            <pubDate>Mon, 05 Jan 2026 14:52:40 GMT</pubDate>
            <atom:updated>2026-01-21T17:08:41.249Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*VeNp9BwmHjXRkF-7pO0uzA.jpeg" /><figcaption><a href="https://open.spotify.com/track/0x7zahScwdhZzt84MGVlUn">River by Nantua</a></figcaption></figure><p>If you have experience with C++, you are already familiar with struct and class. In C++, the main difference between them is the <strong>default access specifier</strong>:</p><ul><li>struct members are <strong>public by default</strong></li><li>class members are <strong>private by default</strong></li></ul><p>This distinction is very helpful when designing data structures. For <strong>simple data structures</strong>, using a struct can be more convenient.</p><p>Example:</p><pre>struct Point {<br>    float x;<br>    float y;<br>};</pre><p>Using a struct, the code is simpler because we can access the member variables directly. This is possible because the default access specifier is public.</p><p>If we use a class, it looks like this:</p><pre>class Point {<br>public:<br>    float x;<br>    float y;<br>};</pre><p>When using a class, we must explicitly write the public keyword to make the member variables accessible.</p><p>For example:</p><pre>Point position;<br><br>position.x = 20.0f;<br>position.y = 20.0f;</pre><p>Why is struct simpler? Because we don’t need to write the public keyword to access member variables or data inside the Point data structure.</p><p>Another scenario where this is useful is when updating the position of an object using a function:</p><pre>void UpdateObjectPos(Point&amp; objectPos, const Point&amp; updatePos) {<br>    objectPos.x = updatePos.x;<br>    objectPos.y = updatePos.y;<br>}</pre><p>If we used a class for the Point data structure, we would still need to declare the members as public to perform this operation. For simple data containers like this, using a struct keeps the code cleaner and easier to read.</p><h3>Built-in Data Structures in C++</h3><p>In addition to custom data structures created with struct or class, C++ provides many <strong>built-in data structures</strong> through the <strong>Standard Template Library (STL)</strong>. These data structures are designed to store and manage <strong>collections of data efficiently</strong>.</p><h3>Sequence Containers</h3><p>Sequence containers store elements in a specific order.</p><ul><li>std::array – fixed-size array</li><li>std::vector – dynamic array (most commonly used)</li><li>std::list – doubly linked list</li><li>std::deque – double-ended queue</li></ul><p>Example:</p><pre>std::vector&lt;Point&gt; points;</pre><p>This stores multiple Point objects in a dynamic array that can grow or shrink as needed.</p><p>Another example:</p><p>If the data in the vector is a set of numbers, we can sort it using the C++ standard library like this:</p><pre>// A vector of integers that will be sorted in ascending order<br>std::vector&lt;int&gt; vec = {2, 3, 4, 5, 6, 9, 3, 2, 1, 1, 3, 8, 5};<br><br>// Sort the vector in ascending order<br>std::sort(vec.begin(), vec.end());</pre><h3>Associative Containers</h3><p>Associative containers store data in a structured way for fast searching.</p><ul><li>std::map – key–value pairs, sorted by key</li><li>std::set – unique sorted values</li><li>std::multimap, std::multiset – allow duplicate keys or values</li></ul><p>Example:</p><pre>std::map&lt;int, Point&gt; pointMap;</pre><p>This allows fast lookup of a Point using an integer key.</p><h3>Unordered Containers</h3><p>Unordered containers use hashing for faster average lookup time.</p><ul><li>std::unordered_map</li><li>std::unordered_set</li></ul><p>Example:</p><pre>std::unordered_map&lt;int, Point&gt; pointTable;</pre><p>Another example:</p><p>One useful thing we can do using an unordered_map is find the <strong>mode</strong> of a set of numbers, which is the value that appears most frequently. For example, consider the following data set: {1, 2, 3, 4, 4, 5, 2, 3, 4, 3, 4}. If the data is small, we can count the occurrences manually, but this becomes impractical when dealing with millions of values. Using an unordered_map, we can store each number as a key and its frequency as the value, then determine which number appears most often:</p><pre>#include &lt;unordered_map&gt;<br>#include &lt;vector&gt;<br><br>// A vector of integers where we want to find the mode (most frequent value)<br>std::vector&lt;int&gt; numbers = {1, 2, 3, 4, 4, 5, 2, 3, 4, 3, 4};<br><br>// An unordered_map where:<br>// - key   = the number from the vector<br>// - value = how many times that number appears<br>std::unordered_map&lt;int, int&gt; frequency;<br><br>// Count how many times each number appears in the vector<br>for (int n : numbers) {<br>    // If the key does not exist, it is created with value 0, then incremented<br>    frequency[n]++;<br>}<br><br>// Initialize the mode with the first element in the vector<br>int mode = numbers[0];<br><br>// Keeps track of the highest frequency found so far<br>int maxCount = 0;<br><br>// Iterate through the frequency map to find the number with the highest count<br>for (const auto&amp; pair : frequency) {<br>    // pair.first  -&gt; the number<br>    // pair.second -&gt; how many times it appears<br><br>    if (pair.second &gt; maxCount) {<br>        maxCount = pair.second;   // Update highest frequency<br>        mode = pair.first;        // Update mode to the most frequent number<br>    }<br>}</pre><p>This approach is efficient because unordered_map provides fast average-time insertion and lookup, making it ideal for large data sets.</p><h3>Custom vs Built-in Data Structures</h3><ul><li><strong>Custom data structures (</strong><strong>struct, </strong><strong>class)</strong> define the <strong>shape and meaning of a single object</strong>.</li><li><strong>Built-in data structures (STL containers)</strong> manage <strong>collections of objects efficiently</strong>.</li></ul><p>In practice, these are often used together:</p><pre>struct Point {<br>    float x;<br>    float y;<br>};<br><br>std::vector&lt;Point&gt; points;</pre><p>Here, Point defines <em>what</em> the data is, while std::vector defines <em>how many</em> and <em>how</em> the data is stored.</p><h3>Summary</h3><ul><li>Use <strong>struct</strong> for simple data containers</li><li>Use <strong>class</strong> when encapsulation and behavior are important</li><li>Use <strong>STL containers</strong> (vector, map, etc.) to store and manage collections of data</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=aafddf822fe7" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Coming Back to React.js After a Few Years: A React.js Technical Interview]]></title>
            <link>https://medium.com/@noryx/coming-back-to-react-js-after-a-few-years-a-react-js-technical-interview-6400e39e0f8a?source=rss-9fa87ef1654c------2</link>
            <guid isPermaLink="false">https://medium.com/p/6400e39e0f8a</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[reactjs]]></category>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[front-end-development]]></category>
            <dc:creator><![CDATA[noryx]]></dc:creator>
            <pubDate>Mon, 22 Dec 2025 16:46:21 GMT</pubDate>
            <atom:updated>2025-12-22T17:13:13.916Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vSpP8G5YyxwIiTKtSnzVGQ.png" /></figure><p>If you are coming back to React.js after a few years, things might look a bit <em>busier</em> than before. Like, what is Vite? I didn’t see it a few years ago. That’s what I feel right now. It seems more complicated than React.js a few years ago.</p><p>Rather than installing Node.js on my machine, for this article I’m simply using StackBlitz (<a href="https://stackblitz.com/">https://stackblitz.com/</a>) as the development environment, so everything runs directly in the browser without any local setup.</p><p>New tools, new names, new versions. Don’t worry — the core ideas are still the same. We still use commands like npm install or npm run dev, just like before, only with different tools.</p><p>In this article, we’ll build the simplest possible counter using Redux Toolkit, along with a todo list that used for my technical interview a few years ago.</p><h3>What are we building first?</h3><p>A counter with two buttons:</p><ul><li><strong>+</strong> to increase the number</li><li><strong>-</strong> to decrease the number</li></ul><p>The state will be stored in <strong>Redux</strong>, even though this example could easily be done with useState. We use Redux here only to understand how it works today.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e4sV-O8A-LKJgqGxqPdylQ.png" /></figure><p>The full source code is available on <strong>StackBlitz</strong> for you to try out:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fstackblitz.com%2Fedit%2Fvitejs-vite-go9we4qb%3Fembed%3D1%26file%3Dsrc%252FApp.tsx&amp;display_name=StackBlitz&amp;url=https%3A%2F%2Fstackblitz.com%2Fedit%2Fvitejs-vite-go9we4qb%3Ffile%3Dsrc%252FApp.tsx&amp;image=https%3A%2F%2Fsocial-img.staticblitz.com%2Fprojects%2Fvitejs-vite-go9we4qb%2F2c7b9582ef2d02276f841c4ba3c72ed8&amp;type=text%2Fhtml&amp;schema=stackblitz" width="745" height="400" frameborder="0" scrolling="no"><a href="https://medium.com/media/b0a17bf7d4ef6a7c9a85d32aa64a28b5/href">https://medium.com/media/b0a17bf7d4ef6a7c9a85d32aa64a28b5/href</a></iframe><h3>The idea (before the code)</h3><p>Think of Redux like this:</p><ul><li>There is <strong>one global store</strong></li><li>The store holds some state (count)</li><li>We change the state by <strong>dispatching actions</strong></li></ul><p>Redux Toolkit just makes this process <strong>shorter and less painful</strong> than old Redux.</p><h3>The store</h3><p>This file contains everything related to our counter state.</p><pre>// src/store.ts<br>import { configureStore, createSlice } from &quot;@reduxjs/toolkit&quot;;<br><br>const counterSlice = createSlice({<br>  name: &quot;counter&quot;,<br>  initialState: { value: 0 },<br>  reducers: {<br>    increment: (state) =&gt; {<br>      state.value += 1;<br>    },<br>    decrement: (state) =&gt; {<br>      state.value -= 1;<br>    },<br>  },<br>});<br>export const { increment, decrement } = counterSlice.actions;<br>export const store = configureStore({<br>  reducer: {<br>    counter: counterSlice.reducer,<br>  },<br>});<br>export type RootState = ReturnType&lt;typeof store.getState&gt;;</pre><p>What’s happening here?</p><ul><li>createSlice replaces <strong>actions + reducers + constants</strong> from old Redux</li><li>We are allowed to “mutate” the state because Redux Toolkit uses <strong>Immer</strong> under the hood</li></ul><h3>Connecting Redux to React</h3><p>Now we provide the store to our app.</p><pre>// src/main.tsx<br>import React from &quot;react&quot;;<br>import ReactDOM from &quot;react-dom&quot;;<br>import { Provider } from &quot;react-redux&quot;;<br>import { store } from &quot;./store&quot;;<br>import App from &quot;./App&quot;;<br><br>ReactDOM.render(<br>  &lt;Provider store={store}&gt;<br>    &lt;App /&gt;<br>  &lt;/Provider&gt;,<br>  document.getElementById(&quot;root&quot;)<br>);</pre><p>This step is important, but simple:</p><blockquote><em>The </em><em>&lt;Provider&gt; makes the Redux store available to all components.</em></blockquote><h3>The App component</h3><p>This is where we read and update the state.</p><pre>// src/App.tsx<br>import React from &quot;react&quot;;<br>import { useDispatch, useSelector } from &quot;react-redux&quot;;<br>import { increment, decrement } from &quot;./store&quot;;<br>import type { RootState } from &quot;./store&quot;;<br><br>const App = () =&gt; {<br>  const count = useSelector((state: RootState) =&gt; state.counter.value);<br>  const dispatch = useDispatch();<br>  return (<br>    &lt;div style={{ padding: 20 }}&gt;<br>      &lt;h1&gt;Redux Counter&lt;/h1&gt;<br>      &lt;p&gt;Count: {count}&lt;/p&gt;<br>      &lt;button onClick={() =&gt; dispatch(increment())}&gt;+&lt;/button&gt;<br>      &lt;button onClick={() =&gt; dispatch(decrement())} style={{ marginLeft: 10 }}&gt;<br>        -<br>      &lt;/button&gt;<br>    &lt;/div&gt;<br>  );<br>};<br>export default App;</pre><p>What to notice here:</p><ul><li>useSelector reads data from the store</li><li>useDispatch sends actions to the store</li><li>No boilerplate, no extra files</li></ul><h3>What are we building next?</h3><p>A few years ago (in 2019 — yes, before I graduated from university), I had a technical interview for a Software Engineer position at a startup. I already had experience developing a fully functional web application using Laravel. However, my experience with React.js was limited to building a simple CRUD application and a page that displayed a list of tourist attractions.</p><p>The main <strong>challenge</strong> of this technical test wasn’t the code itself, but explaining how Redux works and why we should use it. This project was a small-scale example of how Redux can solve problems in larger applications. If we can explain it using a good analogy, the chances of getting the job become much higher.</p><p>Back to the memory when I was 21 years old, seeing it now makes me a little bit scared. I remember thinking about how I had worked with many packages and folders, and that even though it was just a simple to-do list. How much more complicated must a real project be? The startup was a video streaming platform.</p><p>I wasn’t mentally prepared for that job at the time, but as a 21-year-old, I really wanted to get it, even though it looked very complicated and Redux felt like it could kill me. Still, I kept thinking that if I got the job — even if I only survived for a few months — I would still be a 22-year-old young man.</p><p>Now, at 27, looking back at it feels a little more scary.</p><p>I’m trying to <strong>challenge</strong> myself by recreating the technical test. Before I started all of these experiments, I believe React.js has become more complicated than it was before. Is that true? Let’s find out.</p><h3><strong>JavaScript Package Managers</strong></h3><p>Before we start doing anything with React, we need a package manager to install dependencies, and that’s also why I’m using <strong>StackBlitz</strong>. Today, we have several JavaScript package managers — npm, Yarn, pnpm, and even newer tools like Bun. For this project, using <strong>StackBlitz</strong> with npm feels like the simplest choice.</p><p>Now that all the development tools are ready, where should we start? I have the old project that I submitted a few years ago, and this is what it looks like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yOlVY4WyeRaGMX9IN1KYzw.png" /></figure><p>After seeing that, I had a few questions:</p><ul><li>Why am I seeing React.js today not using class components?</li><li>Why does the project at that time is use redux-storage-engine-localstorage and redux-storage, and now is not?</li></ul><p>I can’t open the old technical test that was provided on Google Drive. But I remember that the old test focused on implementing the logic, while the UI was already provided. The UI was built using the todomvc-app-css package. So, if we write LESS code like this, the UI is already done:</p><pre>export default function App() {<br>  return (<br>    &lt;div className=&quot;todoapp&quot;&gt;<br>      &lt;header className=&quot;header&quot;&gt;<br>        &lt;h1&gt;todos&lt;/h1&gt;<br>        &lt;input<br>          className=&quot;new-todo&quot;<br>          placeholder=&quot;What needs to be done?&quot;<br>        /&gt;<br>      &lt;/header&gt;<br><br>      &lt;ul className=&quot;todo-list&quot;&gt;<br>        &lt;li className=&quot;completed&quot;&gt;<br>          &lt;div className=&quot;view&quot;&gt;<br>            &lt;input className=&quot;toggle&quot; type=&quot;checkbox&quot; checked /&gt;<br>            &lt;label&gt;Learn React&lt;/label&gt;<br>            &lt;button className=&quot;destroy&quot; /&gt;<br>          &lt;/div&gt;<br>        &lt;/li&gt;<br><br>        &lt;li&gt;<br>          &lt;div className=&quot;view&quot;&gt;<br>            &lt;input className=&quot;toggle&quot; type=&quot;checkbox&quot; /&gt;<br>            &lt;label&gt;Use TodoMVC CSS&lt;/label&gt;<br>            &lt;button className=&quot;destroy&quot; /&gt;<br>          &lt;/div&gt;<br>        &lt;/li&gt;<br>      &lt;/ul&gt;<br>    &lt;/div&gt;<br>  )<br>}</pre><p>And this is what it looks like when rendered:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/449/1*d7HZy2jNNH8Wwh56mblwfA.png" /></figure><p>We only needed to implement the logic for the technical test, and because the interviewer said I was an honest person, he gave me good feedback so I knew what I should improve.</p><p>And redux-storage-engine-localstorage was mostly relevant around 2015–2017. By 2018 it was already fading, and after Redux Toolkit (2019), it no longer made sense for new projects.</p><p>Even though Redux Toolkit existed in 2019, Redux usage today is actually simpler than in 2019–2022, because best practices have matured and Redux is used more selectively.</p><h4>Why am I seeing React.js today not using class components?</h4><p>Because since <strong>React 16.8 (2018)</strong>, <strong>Hooks</strong> allow functional components to handle state, side effects, and lifecycle logic. This made functional components simpler, more composable, and easier to reason about than class components.</p><p>As Hooks became the default pattern, <strong>new projects stopped writing class components</strong>. By around <strong>2020</strong>, class components were effectively considered <strong>legacy for new development</strong> — still supported, but no longer recommended.</p><p>Modern React features and best practices are now <strong>hooks-first</strong>, so most contemporary codebases use functional components exclusively.</p><p>Now I don’t need to use as many folders as I did in 2019. Using fewer folders than the folder-heavy structures common in 2019 is considered a good practice today.</p><blockquote>Old Redux folders solved a <em>tooling problem</em>, not a design problem.</blockquote><h3>Why we had many folders before (2016–2019)</h3><p>Old Redux forced you to separate things because:</p><ul><li>Reducers were pure functions</li><li>Actions were plain objects</li><li>Types had to be constants</li><li>No code generation</li></ul><p>So we needed:</p><pre>actions/<br>reducers/<br>constants/</pre><p>This was <strong>mechanical separation</strong>, not architectural insight.</p><p>More folders existed because Redux was <strong>verbose</strong>, not because apps were complex.</p><p>Using fewer folders isn’t a bad practice. Older Redux needed many folders because of boilerplate. Modern tools like Redux Toolkit collapse that boilerplate safely. What matters is feature boundaries and change isolation, not folder count.</p><p>Contrast with 2019-era Redux architecture, Common 2019 structure:</p><pre>src/<br> ├─ actions/<br> │   └─ todoActions.ts<br> ├─ reducers/<br> │   ├─ todoReducer.ts<br> │   └─ index.ts<br> ├─ constants/<br> │   └─ actionTypes.ts<br> ├─ middleware/<br> │   └─ storage.ts<br> └─ store/<br>     └─ configureStore.ts</pre><h3>Problems with this approach</h3><ul><li>Logic for one feature is <strong>spread across many folders</strong></li><li>Boilerplate dominates business logic</li><li>Persistence is <strong>global and implicit</strong></li><li>Small features feel “heavy”</li><li>Refactors are expensive</li></ul><p>This structure came from <strong>framework-first thinking</strong>, not feature-first thinking.</p><p>Modern Redux architecture, why it uses fewer files:</p><p><strong>Overall architecture (big picture).</strong></p><p>This code demonstrates <strong>modern Redux usage with Redux Toolkit and React Hooks</strong>, where:</p><ul><li>Redux is responsible <strong>only for state management</strong></li><li>Features are <strong>colocated</strong></li><li>Persistence is <strong>explicit</strong>, not hidden in middleware</li><li>The entire app is understandable with <strong>three files</strong></li></ul><pre>todosSlice.ts   → feature logic (state + actions + reducer)<br>store.ts        → Redux configuration<br>App.tsx         → UI + user interactions</pre><p>This structure is simpler than 2019-era Redux, but not any less powerful. Everything here comes from my perspective as someone who doesn’t have any “real experience” with React.js yet and is just poking around, exploring things with ChatGPT. Hopefully, you’ll still get something useful out of it — especially if you’ve been in the same phase before and feel a bit nostalgic. And for real React.js developers, feel free to drop your actual wisdom.</p><h3>Let’s build the app!</h3><h4>Defining the Todo logic (todosSlice.ts)</h4><p>This file contains <strong>everything related to todos</strong>:</p><ul><li>what a todo looks like</li><li>where it is stored</li><li>how it can be changed</li></ul><h4>Defining a Todo</h4><pre>export interface Todo {<br>  id: string;<br>  title: string;<br>  completed: boolean;<br>}</pre><p>A todo is just an object with:</p><ul><li>a unique id</li><li>some text (title)</li><li>a completed flag</li></ul><p>No extra abstractions.</p><h4>Initial state</h4><pre>const initialState: Todo[] = [];</pre><p>At the beginning, we start with an empty list.</p><h4>Creating a slice</h4><pre>const todosSlice = createSlice({<br>  name: &#39;todos&#39;,<br>  initialState,<br>  reducers: { ... }<br>});</pre><p>A <strong>slice</strong> groups:</p><ul><li>state</li><li>actions</li><li>reducers</li></ul><p>into one place.</p><p>Think of it as a small module that owns the todo list and nothing else.</p><h4>Adding a todo</h4><pre>addTodo: {<br>  reducer(state, action) {<br>    state.push(action.payload);<br>  },<br>  prepare(title: string) {<br>    return {<br>      payload: {<br>        id: crypto.randomUUID(),<br>        title,<br>        completed: false,<br>      },<br>    };<br>  },<br>}</pre><p>Here’s what happens when we add a todo:</p><ol><li>The UI calls addTodo(&quot;Buy milk&quot;)</li><li>prepare() creates the full todo object</li><li>The reducer pushes it into the list</li></ol><p>The UI doesn’t need to worry about IDs or default values — Redux handles it.</p><h4>Toggling a todo</h4><pre>toggleTodo(state, action) {<br>  const todo = state.find((t) =&gt; t.id === action.payload);<br>  if (todo) todo.completed = !todo.completed;<br>}</pre><p>This reducer:</p><ul><li>finds a todo by its ID</li><li>flips the completed flag</li></ul><p>This is triggered by clicking a checkbox in the UI.</p><h4>Removing a todo</h4><pre>removeTodo(state, action) {<br>  return state.filter((t) =&gt; t.id !== action.payload);<br>}</pre><p>This simply removes a todo by ID.</p><h4>Exporting actions and reducer</h4><pre>export const { addTodo, toggleTodo, removeTodo } = todosSlice.actions;<br>export default todosSlice.reducer;</pre><p>These exports allow other parts of the app to:</p><ul><li>dispatch todo actions</li><li>register the todo reducer in the store</li></ul><h4>Creating the Redux store (store.ts)</h4><p>This file sets up the <strong>global state container</strong>.</p><pre>export const store = configureStore({<br>  reducer: {<br>    todos: todosReducer,<br>  },<br>});</pre><p>The global state now looks like this:</p><pre>{<br>  todos: Todo[]<br>}</pre><p>Each key in the reducer object controls a part of the state.</p><h4>Type helpers</h4><pre>export type RootState = ReturnType&lt;typeof store.getState&gt;;<br>export type AppDispatch = typeof store.dispatch;</pre><p>These are TypeScript helpers:</p><ul><li>RootState describes the full state shape</li><li>AppDispatch types the dispatch function</li></ul><p>They improve safety but don’t affect runtime behavior.</p><h4>Connecting Redux to the UI (App.tsx)</h4><p>Now we connect React to Redux.</p><h4>Reading data from the store</h4><pre>const todos = useSelector((state: RootState) =&gt; state.todos);</pre><p>This:</p><ul><li>reads the todo list from Redux</li><li>automatically re-renders the component when it changes</li></ul><h4>Dispatching actions</h4><pre>const dispatch = useDispatch&lt;AppDispatch&gt;();</pre><p>This gives the component a way to tell Redux:</p><blockquote><em>“Something happened. Update the state.”</em></blockquote><h4>Persisting todos to localStorage</h4><pre>useEffect(() =&gt; {<br>  localStorage.setItem(&#39;todos&#39;, JSON.stringify(todos));<br>}, [todos]);</pre><p>Every time the todo list changes:</p><ul><li>it is saved to localStorage</li></ul><p>This keeps data between page refreshes (saving only, not loading yet).</p><h4>Adding new todos</h4><pre>onKeyDown={(e) =&gt; {<br>  if (e.key === &#39;Enter&#39; &amp;&amp; e.currentTarget.value.trim()) {<br>    dispatch(addTodo(e.currentTarget.value));<br>    e.currentTarget.value = &#39;&#39;;<br>  }<br>}}</pre><p>When the user presses Enter:</p><ol><li>An action is dispatched</li><li>Redux updates the state</li><li>The UI re-renders automatically</li></ol><h4>Rendering the list</h4><pre>{todos.map((todo) =&gt; (<br>  ...<br>))}</pre><p>Each todo:</p><ul><li>displays its title</li><li>shows a checkbox</li><li>has a delete button</li></ul><h4>Toggling completion</h4><pre>onChange={() =&gt; dispatch(toggleTodo(todo.id))}</pre><p>Checkbox click → Redux action → state update → UI refresh.</p><h4>Removing a todo</h4><pre>onClick={() =&gt; dispatch(removeTodo(todo.id))}</pre><p>Button click → Redux action → item removed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Py6JVjpUSc6CgCOwxN3Auw.gif" /></figure><p>The full source code is available on <strong>StackBlitz</strong> for you to try out:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fstackblitz.com%2Fedit%2Fvitejs-vite-ljzgid4w%3Fembed%3D1%26file%3Dsrc%252FApp.tsx&amp;display_name=StackBlitz&amp;url=https%3A%2F%2Fstackblitz.com%2Fedit%2Fvitejs-vite-ljzgid4w%3Ffile%3Dsrc%252FApp.tsx&amp;image=https%3A%2F%2Fsocial-img.staticblitz.com%2Fprojects%2Fvitejs-vite-ljzgid4w%2F859b33d009ff4ee6f87ceeef35659ae9&amp;type=text%2Fhtml&amp;schema=stackblitz" width="745" height="400" frameborder="0" scrolling="no"><a href="https://medium.com/media/d9e6c0e94fe2aa663ea5d7f5552e38e9/href">https://medium.com/media/d9e6c0e94fe2aa663ea5d7f5552e38e9/href</a></iframe><h3>Final thoughts</h3><p>If you used Redux years ago, this might feel <em>too simple</em> — and that’s the point.</p><p>Redux Toolkit removes most of the ceremony:</p><ul><li>Fewer files</li><li>Less code</li><li>Same core idea</li></ul><p>And about Vite?</p><p>You don’t need to care much about it here. It’s just the tool that runs your app fast during development.</p><p>Thank you for reading!!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6400e39e0f8a" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>