<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: mthtclone</title>
    <description>The latest articles on DEV Community by mthtclone (@mthtclone).</description>
    <link>https://dev.to/mthtclone</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3255159%2F170b37bb-acf1-4db3-a996-5116df9a5c17.gif</url>
      <title>DEV Community: mthtclone</title>
      <link>https://dev.to/mthtclone</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mthtclone"/>
    <language>en</language>
    <item>
      <title>REST Isn’t Just About JSON Over HTTP</title>
      <dc:creator>mthtclone</dc:creator>
      <pubDate>Mon, 08 Sep 2025 21:05:16 +0000</pubDate>
      <link>https://dev.to/mthtclone/rest-isnt-just-about-json-over-http-2ilg</link>
      <guid>https://dev.to/mthtclone/rest-isnt-just-about-json-over-http-2ilg</guid>
      <description>&lt;p&gt;When most developers talk about building a REST API, what they usually mean is sending JSON over HTTP with a set of CRUD endpoints like &lt;code&gt;/users&lt;/code&gt; or &lt;code&gt;/orders&lt;/code&gt;. That approach works well in practice, which is why it’s so common. But according to Roy Fielding, the person who introduced the concept of REST in his doctoral dissertation, this isn’t really REST at all. That pattern has become so popular that “REST API” is almost shorthand for “any JSON API.”&lt;/p&gt;

&lt;p&gt;REST stands for &lt;strong&gt;Representational State Transfer&lt;/strong&gt;, and its principles go beyond HTTP verbs and resource URLs. Fielding emphasized one idea in particular that often gets overlooked: &lt;strong&gt;hypermedia&lt;/strong&gt;. His vision was that clients should be able to discover what actions are possible by following links included in the server’s responses, rather than hardcoding every endpoint path ahead of time. This principle is called &lt;strong&gt;HATEOAS&lt;/strong&gt; (Hypermedia as the Engine of Application State).&lt;/p&gt;

&lt;p&gt;Fielding went so far as to say that most of what the industry calls REST APIs today are not RESTful. They are &lt;em&gt;REST-like&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So what did Fielding actually mean? Let’s unpack it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Six Constraints of REST
&lt;/h2&gt;

&lt;p&gt;Fielding described REST as an &lt;strong&gt;architectural style&lt;/strong&gt; defined by a set of constraints. If an API follows all of them, it can be called RESTful. If it ignores some, it might still be useful, but it isn’t REST.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Client–Server Architecture&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;At its core, the client–server architecture is about &lt;strong&gt;separating concerns&lt;/strong&gt;. In a RESTful system, the client is responsible for the user interface and user experience, while the server handles data storage, business logic, and processing. This separation allows both sides to evolve independently. For example, you could redesign your web frontend or switch from a web app to a mobile app without touching the server, as long as the API contract remains consistent.&lt;/p&gt;

&lt;p&gt;This separation also encourages &lt;strong&gt;scalability&lt;/strong&gt;. Servers can focus purely on efficiently processing requests and managing resources, while clients handle how data is presented and interacted with. In practical terms, a request like &lt;code&gt;GET /users/1&lt;/code&gt; is handled entirely by the server, which retrieves the user data from a database and formats it into a response. The client doesn’t need to know &lt;em&gt;how&lt;/em&gt; the data is stored or computed. It only needs to know how to interpret and display the response.&lt;/p&gt;

&lt;p&gt;Another advantage is &lt;strong&gt;independent deployment&lt;/strong&gt;. Because the client and server are decoupled, teams can release new versions of one without requiring changes in the other. This flexibility reduces coordination overhead and allows for faster iteration.&lt;/p&gt;

&lt;p&gt;Finally, the client–server separation lays the groundwork for &lt;strong&gt;interoperability&lt;/strong&gt;. Multiple types of clients -- web browsers, mobile apps, IoT devices -- can interact with the same server using the same API. The server doesn’t care whether the request comes from a browser running JavaScript, a Python script, or a mobile app; it responds the same way, serving data consistently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Statelessness
&lt;/h3&gt;

&lt;p&gt;Statelessness is one of the defining constraints of REST, and it has a profound impact on how APIs are designed and scaled. In a stateless system, &lt;strong&gt;every request from a client must contain all the information necessary for the server to understand and process it&lt;/strong&gt;. The server does not store any client session or context between requests. Each interaction is independent, meaning the server treats it as a completely new request.&lt;/p&gt;

&lt;p&gt;For example, imagine a client wants to fetch the details of a user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /users/123
Authorization: Bearer abc123token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the request includes everything the server needs: the endpoint identifies the resource, and the authorization header provides the credentials. The server doesn’t need to “remember” anything about the client’s previous requests. If the client sends the next request to fetch the user’s orders, it must include all necessary context again—perhaps the same authentication token or other parameters.&lt;/p&gt;

&lt;p&gt;This design brings several practical benefits. First, it makes &lt;strong&gt;scaling much easier&lt;/strong&gt;. Because servers do not store session information, any server in a cluster can handle any incoming request. There’s no need to tie a client to a specific server, which simplifies load balancing and improves fault tolerance.&lt;/p&gt;

&lt;p&gt;Second, statelessness increases &lt;strong&gt;reliability&lt;/strong&gt;. If one server goes down, another can seamlessly handle the next request. There’s no risk of losing session state or requiring complicated session replication mechanisms.&lt;/p&gt;

&lt;p&gt;Finally, statelessness encourages &lt;strong&gt;clearer API design&lt;/strong&gt;. Clients must explicitly provide all necessary information, which forces developers to think carefully about what data is required and how to structure requests. While this may seem repetitive, it leads to more predictable and maintainable systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cacheability
&lt;/h3&gt;

&lt;p&gt;Cacheability is a fundamental REST constraint that directly impacts &lt;strong&gt;performance, scalability, and efficiency&lt;/strong&gt;. In a RESTful system, responses must clearly indicate whether they can be cached and for how long. By providing explicit cache control information, servers enable clients, and even intermediate proxies, to reuse responses without sending repetitive requests. This reduces server load, improves response times, and makes the system more scalable.&lt;/p&gt;

&lt;p&gt;For instance, imagine a client requests product information from an API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /products/123
Cache-Control: max-age=3600

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

&lt;/div&gt;



&lt;p&gt;This response tells the client that the data can be cached for one hour. If the same request is made again within that hour, the client can use the cached response instead of querying the server again. This reduces unnecessary traffic and speeds up user interactions.&lt;/p&gt;

&lt;p&gt;Cacheability also improves &lt;strong&gt;network efficiency&lt;/strong&gt; in larger architectures. In layered systems with proxies, CDNs, or load balancers, properly cacheable responses allow these intermediaries to serve repeated requests without hitting the origin server. For example, a static product catalog or frequently accessed user profile data can be cached at multiple layers, decreasing latency and conserving server resources.&lt;/p&gt;

&lt;p&gt;It’s important to note that not all responses are safe to cache. Dynamic or sensitive data, such as user-specific transactions or authentication details, must explicitly prevent caching with headers like &lt;code&gt;Cache-Control: no-store&lt;/code&gt;. Making this distinction ensures data integrity and security while still benefiting from caching where appropriate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Uniform Interface
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Uniform Interface&lt;/strong&gt; constraint is the cornerstone of REST and arguably the most important of all. Fielding designed REST around the idea that a consistent, standardized interface between clients and servers simplifies interactions, improves scalability, and reduces coupling. In other words, every client can interact with any server in a predictable way without needing intimate knowledge of its internal implementation.&lt;/p&gt;

&lt;p&gt;The uniform interface is built around four key principles. First, &lt;strong&gt;resource identification in requests&lt;/strong&gt;. Every resource is uniquely addressable through a URI. For example, &lt;code&gt;/users/1&lt;/code&gt; unambiguously refers to a specific user. This consistent identification allows clients to locate resources without guessing endpoints.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;manipulation through representations&lt;/strong&gt;. Clients do not directly manipulate resources on the server. Instead, they work with representations -- like JSON or XML -- that capture the current state of a resource. If you want to update a user’s profile, you send a JSON representation of the new state to the server, and the server interprets it to apply the changes. This separation keeps clients decoupled from the server’s internal data structures.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;self-descriptive messages&lt;/strong&gt;. Each request and response should contain enough information to describe how it should be processed. HTTP verbs (&lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;) communicate the intent of a request, while headers and payloads provide additional context. For example, sending a &lt;code&gt;PUT&lt;/code&gt; request with a JSON payload to &lt;code&gt;/users/1&lt;/code&gt; clearly indicates an update operation. The client does not need to embed hidden instructions or out-of-band knowledge.&lt;/p&gt;

&lt;p&gt;Finally, and perhaps most overlooked, is &lt;strong&gt;Hypermedia as the Engine of Application State (HATEOAS)&lt;/strong&gt;. Fielding envisioned APIs where clients discover available actions by following links embedded in resource representations, rather than hardcoding endpoint URLs. For example, a user object might include links to their orders:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
{
  "id": 1,
  "name": "Alice",
  "_links": {
    "self": { "href": "/users/1" },
    "orders": { "href": "/users/1/orders" }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The client doesn’t need prior knowledge of the orders endpoint; it can simply follow the link provided by the server. This makes APIs &lt;strong&gt;discoverable, evolvable, and resilient&lt;/strong&gt; to changes in URL structures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hypermedia as the Engine of Application State (HATEOAS)
&lt;/h3&gt;

&lt;p&gt;Hypermedia is arguably the most defining, yet most overlooked, constraint of REST. Fielding designed REST around the idea that &lt;strong&gt;clients should be able to navigate the application solely by following links provided dynamically by the server&lt;/strong&gt;, without needing prior knowledge of the API structure. This principle is known as &lt;strong&gt;HATEOAS&lt;/strong&gt;—&lt;em&gt;Hypermedia as the Engine of Application State&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In most APIs labeled “RESTful” today, clients hardcode the paths to endpoints: &lt;code&gt;/users/1/orders&lt;/code&gt;, &lt;code&gt;/products/42/reviews&lt;/code&gt;, and so on. While this works, it violates the core idea of REST. In a truly RESTful system, the client discovers these paths dynamically by following links embedded in the server’s responses. The server drives the application state, guiding the client through available actions.&lt;/p&gt;

&lt;p&gt;For example, consider a user resource returned by an API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "id": 1,
  "name": "Alice",
  "_links": {
    "self": { "href": "/users/1" },
    "orders": { "href": "/users/1/orders" },
    "update": { "href": "/users/1", "method": "PUT" }
  }
}

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

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;_links&lt;/code&gt; section tells the client what it can do next: retrieve orders, update the user, or simply follow the self-link. The client doesn’t need to guess endpoint URLs or rely on external documentation for navigation. If the server later reorganizes its endpoints, the client can still function as long as it continues to follow the provided links.&lt;/p&gt;

&lt;p&gt;This design has several major advantages. First, it makes APIs &lt;strong&gt;evolvable&lt;/strong&gt;. Servers can change URL structures or introduce new features without breaking existing clients. Second, it enhances &lt;strong&gt;discoverability&lt;/strong&gt;. Clients can explore an API like a web browser explores the web, learning available actions dynamically. Finally, it enforces a stronger &lt;strong&gt;separation of concerns&lt;/strong&gt;: the server controls application logic and available actions, while the client focuses on user interaction and presentation.&lt;/p&gt;

&lt;p&gt;Despite these benefits, hypermedia is rarely implemented in practice. Most developers consider it “too complex” or unnecessary when simple JSON endpoints suffice. But the reality is that hypermedia is what makes REST truly RESTful. Without it, an API is just HTTP + JSON masquerading as REST. HATEOAS ensures that clients remain decoupled from server implementations while still being able to navigate the system efficiently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layered System
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Layered System&lt;/strong&gt; constraint in REST allows an architecture to be composed of hierarchical layers, each with a specific role, without the client needing to know how many layers exist or what each layer does. In other words, a client interacts with the server as if it were a single, unified system, even if requests pass through multiple intermediaries such as proxies, gateways, or load balancers.&lt;/p&gt;

&lt;p&gt;The key idea is that clients are &lt;strong&gt;agnostic to the system’s internal structure&lt;/strong&gt;. They don’t need to know how many layers exist or what each does. They only care about receiving consistent responses. By enforcing this separation, RESTful architectures become more robust, scalable, and maintainable, especially in distributed systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code-on-Demand (Optional)
&lt;/h3&gt;

&lt;p&gt;The last of Fielding’s REST constraints is &lt;strong&gt;Code-on-Demand&lt;/strong&gt;, and it is the only one that is optional. This constraint allows servers to extend client functionality by sending executable code that the client can use dynamically. In other words, the server can temporarily enhance or customize the client’s behavior without requiring a new client release.&lt;/p&gt;

&lt;p&gt;A classic example is web browsers. When you visit a webpage, the server sends HTML, CSS, and JavaScript. The JavaScript is executable code that runs on the client side, enabling interactive features like dynamic forms, animations, or API calls. In REST terms, the server is providing code-on-demand, allowing the client to adapt its behavior on the fly.&lt;/p&gt;

&lt;p&gt;In API contexts, code-on-demand could be used more subtly. For instance, a server might send a small script that validates input, performs calculations, or handles specific business logic before sending data back. This allows the client to stay lightweight while leveraging server-provided functionality.&lt;/p&gt;

&lt;p&gt;While not widely used in most APIs, code-on-demand adds &lt;strong&gt;flexibility and extensibility&lt;/strong&gt;. Clients can remain generic and simple, while servers can provide the additional logic needed for specific operations. It also supports the principle of &lt;strong&gt;loose coupling&lt;/strong&gt;: clients do not need to be updated every time new functionality is added to the system—they simply receive the code they need from the server.&lt;/p&gt;

&lt;p&gt;However, because it introduces executable code on the client, code-on-demand must be used carefully to avoid &lt;strong&gt;security risks&lt;/strong&gt; or unintended side effects. That’s partly why it is optional and less commonly implemented in standard APIs.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Useful UNIX one-liner</title>
      <dc:creator>mthtclone</dc:creator>
      <pubDate>Sat, 23 Aug 2025 16:50:44 +0000</pubDate>
      <link>https://dev.to/mthtclone/useful-unix-one-liner-1109</link>
      <guid>https://dev.to/mthtclone/useful-unix-one-liner-1109</guid>
      <description>&lt;p&gt;Some of you have probably used UNIX commands without even realizing it. Windows has its old DOS commands, but UNIX commands are on another level. They’re designed to do one thing, and do it well. On top of that, they’re modular and compact, thanks to the pipe operator (&lt;code&gt;|&lt;/code&gt;), you can chain commands together and build powerful workflows out of simple parts.&lt;/p&gt;

&lt;p&gt;These are some useful UNIX commands I find useful for everyday tasks. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1) Remove string from filenames&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Say you are working in a sort of creative department, and you are given images that may have filenames like images_2135435431322.jpeg. Now, it would not be a good look or produce an impressionable impression on someone's else perception.&lt;/p&gt;

&lt;p&gt;You can quickly clean up filenames using this Unix one-liner:&lt;br&gt;
&lt;code&gt;&lt;br&gt;
for file in *.jpeg; do&lt;br&gt;
    mv "$file" "$(echo "$file" | sed 's/[0-9]\+//g')"&lt;br&gt;
done&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This loops over all .jpeg files in the current directory, and remove all numbers from the filename. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2) Count files by type&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Say you want to quickly want to check how many images, logs or documents you have without opening a GUI, this is how you would do it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ls *.png | wc -l&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This lists all PNG files, and count the number of that files. Here, you can replace .png with different file format. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3) Find the largest file&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Say your folder is big, and you want to locate huge files, and might possibly want to delete it to clean up the disk.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;du -sh * | sort -hr | head -5&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This shows the size of each file in human-readable format, sort the largest file, and show the top 5 largest files/folders.&lt;/p&gt;

&lt;p&gt;This is mainly good for &lt;strong&gt;quick checkups in your project folder&lt;/strong&gt;. On Windows (e.g., Git Bash / MINGW64), the &lt;code&gt;du&lt;/code&gt; command doesn’t support all Linux-style options like &lt;code&gt;-h&lt;/code&gt; (human-readable) and &lt;code&gt;-s&lt;/code&gt; (summary) in the same way, so the output might look different than on Linux. So you might want to use -k show the size of each file/folder in kilobytes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4) Batch rename extensions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Say you want to convert all &lt;code&gt;.jpeg&lt;/code&gt; files to &lt;code&gt;.jpg&lt;/code&gt; for consistency:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;for file in *.jpeg; do&lt;br&gt;
    mv "$file" "${file%.jpeg}.jpg"&lt;br&gt;
done&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is the same as number 1 before, except that this strips the .jpeg extension. &lt;br&gt;
This is perfect for standardizing filenames in folders.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5) Search for a string in all project files&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Say you write a helper function, and import it into different scripts. You want to locate which scripts are using this helper function or has this particulate function either for renaming it or understanding how it interacts with other parts of the code.&lt;/p&gt;

&lt;p&gt;Instead of opening every file manually, you can run:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;grep -rn "showErrorMessage" .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This can tell you where the function is defined, and used, and it helps you debug, refactor codes, etc. &lt;/p&gt;

</description>
      <category>linux</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>From Some to All The Basics of Logic in Computers</title>
      <dc:creator>mthtclone</dc:creator>
      <pubDate>Mon, 18 Aug 2025 12:43:28 +0000</pubDate>
      <link>https://dev.to/mthtclone/from-some-to-all-the-basics-of-logic-in-computers-1pd6</link>
      <guid>https://dev.to/mthtclone/from-some-to-all-the-basics-of-logic-in-computers-1pd6</guid>
      <description>&lt;p&gt;Logic is not paid attention much in Computer Science. It may be, but as a college kid, I only recently explored it because my professor lent me a book.. I read it while dealing with interpersonal issues that unfortunately these logic can't solve because this is the kind of logic I will not be discussing here. &lt;/p&gt;

&lt;p&gt;Logic is at the foundation of both mathematics and computer science. Whether you are writing code, proving theorems, or designing algorithms, you will often use logical concepts like predicates, sets, and the ideas of "some" and all.&lt;/p&gt;

&lt;p&gt;Now, one may ask: &lt;code&gt;why bother with logic at all?&lt;/code&gt; True, it’s not as immediately necessary as eating or drinking, but if a practice grounds you in reality, then theory makes you a better debugger. &lt;/p&gt;

&lt;p&gt;These logic are good at formalizing human language into a set of instructions a computer can understand. This is what logic all about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Predicate
&lt;/h2&gt;

&lt;p&gt;Predicate is a math construct and a function that treurns true or false based on a property. &lt;/p&gt;

&lt;p&gt;P:x -&amp;gt; {true, false} &lt;/p&gt;

&lt;p&gt;Say, P(x): "x is an even number"&lt;/p&gt;

&lt;p&gt;Then, P(4) -&amp;gt; True. P(5) -&amp;gt; false&lt;/p&gt;

&lt;p&gt;A predicate is concerned &lt;strong&gt;only with whether a property holds (true/false)&lt;/strong&gt; for a given input. It doesn’t care about the internal computation or method used to determine the truth. &lt;/p&gt;

&lt;p&gt;In code, predicates are typically implemented as boolean functions. Though, the function still does compute something under the good, it just doesn't matter for the logical concept. &lt;br&gt;
&lt;code&gt;&lt;br&gt;
def is_even(x):&lt;br&gt;
    return x % 2 == 0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Predicates can be classified into two types: &lt;strong&gt;concrete&lt;/strong&gt; and &lt;strong&gt;abstract&lt;/strong&gt;. A &lt;strong&gt;concrete predicate&lt;/strong&gt; directly evaluates a specific property of its input. For example, the function &lt;code&gt;is_even(x)&lt;/code&gt; checks whether a number is divisible by 2, producing a straightforward true or false result. In contrast, an &lt;strong&gt;abstract predicate&lt;/strong&gt; describes a property without specifying exactly how to verify it. It’s more conceptual and often used in theory or higher-level reasoning. For instance, the statement “x is prime” can be treated as a predicate even before we define the exact algorithm to check it.&lt;/p&gt;

&lt;p&gt;Implication&lt;/p&gt;

&lt;p&gt;Once we have predicates, or simple propositions, we often want to describe how one statement implies another. In logic, this is called an implication. &lt;/p&gt;

&lt;p&gt;Formally, an implication &lt;code&gt;P ⇒ Q&lt;/code&gt; (“P implies Q”) means that if &lt;code&gt;P&lt;/code&gt; is true, then &lt;code&gt;Q&lt;/code&gt; must also be true.&lt;/p&gt;

&lt;p&gt;P =&amp;gt; Q ("P implies Q")&lt;/p&gt;

&lt;p&gt;Some readers may connect the dot, and see that this is similar to propositional logic. &lt;/p&gt;

&lt;p&gt;Anyway, in programming, this concept maps directly to conditional statement like &lt;code&gt;if&lt;/code&gt; statement.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;def check_even_and_print(x):&lt;br&gt;
    if x % 2 == 0:  # P: x is even&lt;br&gt;
        print(f"{x} is even")  # Q: print statement executes&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Even more generally, any &lt;code&gt;if-else&lt;/code&gt; logic in programming is a way of encoding implications and conditional reasoning. &lt;/p&gt;

&lt;h2&gt;
  
  
  Set
&lt;/h2&gt;

&lt;p&gt;Predicates are untyped by default. In theory, they can take any kind of inputs. However, in practice, we often want to restrict the types of inputs a predicate can take. &lt;/p&gt;

&lt;p&gt;Sets are used to restrict the type of input. &lt;/p&gt;

&lt;p&gt;"c is a computer" -&amp;gt; c ∈ Computer&lt;/p&gt;

&lt;p&gt;Here, &lt;code&gt;c&lt;/code&gt; belongs to the set of all computers. Sets allow us to &lt;strong&gt;define the domain of discourse&lt;/strong&gt;, which is the collection of all objects we are considering for a particular discussion or predicate.&lt;/p&gt;

&lt;p&gt;In sets, there is something called "domain of discourse". What that means is that &lt;strong&gt;predicates themselves should not be part of the domain of discourse&lt;/strong&gt;, because this can lead to paradoxes and mathematical complications. The domain should contain only the objects the predicates are describing, not the predicates themselves.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Some" and "All"
&lt;/h2&gt;

&lt;p&gt;After defining predicates and sets, we often want to make statements about some or all elements of a set. This is where quantifiers come in.&lt;/p&gt;

&lt;p&gt;The universal quantifier, written as ∀x ∈ S, P(x), expresses that a predicate is true for every element in a set. &lt;/p&gt;

&lt;p&gt;The existential quantifier, written as ∃x ∈ S, P(x),  expresses that a predicate is true for &lt;strong&gt;at least one element&lt;/strong&gt; in a set.&lt;/p&gt;

&lt;p&gt;In programming, quantifiers often appear implicitly when we work with loops and conditional statements.&lt;/p&gt;

&lt;p&gt;To check if a predicate holds for all elements in a list or set, we loop through each element and ensure the condition is true for every item.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;numbers = [2, 4, 6, 8]&lt;br&gt;
all_even = all(x % 2 == 0 for x in numbers) &lt;br&gt;
print(all_even)&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Here, &lt;code&gt;all()&lt;/code&gt; checks the predicate for &lt;strong&gt;every element&lt;/strong&gt;, just like the universal quantifier.&lt;/p&gt;

&lt;p&gt;To check if a predicate holds for at least one element, we loop until we find a matching item. &lt;br&gt;
&lt;code&gt;&lt;br&gt;
numbers = [1, 3, 4, 7]&lt;br&gt;
some_even = any(x % 2 == 0 for x in numbers)  &lt;br&gt;
print(some_even)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here, &lt;code&gt;any()&lt;/code&gt; returns true as soon as it finds an element that satisfies the predicate, mirroring the existential quantifier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical
&lt;/h2&gt;

&lt;p&gt;Now that we have learned about predicates, implication, sets, and quantifiers, let's try making a simple login system by combining all of them.&lt;/p&gt;

&lt;p&gt;First, let's define our sets.  The set of all registered users (domain) could be like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;users = {&lt;br&gt;
    "alice": "password123", &lt;br&gt;
    "bob": "qwerty"&lt;br&gt;
    }&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We need two conditions to check if the user is registered, and that if the password matches to where it is being stored. These will be our predicates.&lt;/p&gt;

&lt;p&gt;`def is_registered(user):&lt;br&gt;
    return user in users&lt;/p&gt;

&lt;p&gt;def password_matches(user, pwd):&lt;br&gt;
    return users.get(user) == pwd`&lt;/p&gt;

&lt;p&gt;Here comes the implication,  &lt;code&gt;if-then&lt;/code&gt; logic. We only check the password if the user is registered:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;if is_registered(username):&lt;br&gt;
    if password_matches(username, password):&lt;br&gt;
        print("Login successful")&lt;br&gt;
    else:&lt;br&gt;
        print("Incorrect password")&lt;br&gt;
else:&lt;br&gt;
    print("User not found")&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here, the implication &lt;code&gt;is_registered(username) ⇒ password_matches(username, password)&lt;/code&gt; is implemented as a conditional: we only evaluate the second part if the first is true.&lt;/p&gt;

&lt;p&gt;As for quantifiers, these can be used when we want to extend the system. Say, Universal quantifier (all) ensure that all passwords meet a security requirement.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;all(len(p) &amp;gt;= 8 for p in users.values())  # ∀ password, length &amp;gt;= 8&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Existential quantifier (some) can check if at least one user has admin privileges.&lt;br&gt;
&lt;code&gt;&lt;br&gt;
some_admin = any(user == "admin" for user in users)  # ∃ user, admin&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;By combining these four concepts, we can formalize, reason about, and implement logic safely in a program. Predicates let us define conditions, implication guides conditional actions, sets define our domain, and quantifiers allow reasoning about collections of data. This is exactly how mathematical logic translates into practical computer science.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>learning</category>
    </item>
    <item>
      <title>TCP/IP, the Backbone of the Internet</title>
      <dc:creator>mthtclone</dc:creator>
      <pubDate>Wed, 23 Jul 2025 20:52:29 +0000</pubDate>
      <link>https://dev.to/mthtclone/tcpip-the-backbone-of-the-internet-385n</link>
      <guid>https://dev.to/mthtclone/tcpip-the-backbone-of-the-internet-385n</guid>
      <description>&lt;p&gt;_Part 2 of the series, Tracing the Internet _&lt;/p&gt;

&lt;p&gt;TCP/IP is the fundamental protocol suite that enables all the data flowing across the internet to reach its destination, and understanding it demystifies what really happens when you load a webpage, send an email, or stream a video. TCP/IP isn’t a single protocol but a layered system—or stack—of protocols, each responsible for a specific aspect of communication. These layers work together to move data seamlessly from one device to another, no matter the physical medium or network involved.&lt;/p&gt;

&lt;p&gt;At the lowest layer, known as the Link or Network Access Layer, TCP/IP handles the actual physical transmission of data. Whether through Ethernet cables, Wi-Fi signals, or fiber optics, this layer takes care of turning your bits into signals suitable for the hardware and then receiving them back on the other side. It handles hardware addressing with protocols like ARP (Address Resolution Protocol) that map IP addresses to physical MAC addresses.&lt;/p&gt;

&lt;p&gt;Above that sits the Internet Layer, where the core of TCP/IP’s orchestration happens with the Internet Protocol (IP). IP is the addressing and routing workhorse. Every device connected to a network is assigned a unique IP address—a digital equivalent of a home address. When you send data, the IP protocol wraps each chunk of data, or packet, with headers containing source and destination IPs, TTL (Time To Live) values, and other metadata essential for routing. IP then sends these packets out, letting routers along the way direct them across interconnected networks toward their destinations. Importantly, IP is connectionless and unreliable on its own; it does not establish connections or confirm delivery but works like a courier who sends packages and hopes they arrive safely.&lt;/p&gt;

&lt;p&gt;Two IP versions are widely used today. IPv4 is the original and most prevalent version, utilizing 32-bit addressing which looks like four decimal numbers separated by dots (e.g., 192.168.1.1). But since the explosive growth of internet-connected devices exhausted IPv4 address space, IPv6 was introduced. IPv6 uses 128-bit addresses written in hexadecimal, such as 2606:4700:4700::1111, offering a practically limitless pool of addresses to accommodate future growth.&lt;/p&gt;

&lt;p&gt;Sitting just above IP is the Transport Layer, which decides how data is delivered. It uses two main protocols, TCP and UDP, to meet different needs. TCP (Transmission Control Protocol) is the reliable, connection-oriented protocol. Before sending data, it performs a three-step handshake: the client sends a SYN request, the server replies with SYN-ACK, and the client confirms with ACK. This handshake establishes a session. TCP keeps track of packet order, retransmits lost packets, applies flow control to avoid overwhelming receivers, and mitigates network congestion to ensure smooth transmission. This makes TCP ideal for applications requiring accuracy and integrity—like web browsing (HTTP), email, and file transfers.&lt;/p&gt;

&lt;p&gt;UDP (User Datagram Protocol), in contrast, is lightweight and connectionless. It sends packets without establishing a session or guaranteeing delivery. This “fire and forget” approach reduces latency, making UDP better suited for applications like live video, voice calls, or online gaming, where occasional packet loss is acceptable but delays are not.&lt;/p&gt;

&lt;p&gt;Each packet of data isn’t just sent raw. Instead, it becomes wrapped in headers added by each layer in a process called encapsulation. Your original data is enclosed in a TCP or UDP header that adds port numbers, sequence info, and checksum fields for error checking. Then the IP header adds source and destination IP addresses, TTL value, flags, and protocol identifiers. Finally, the Link Layer header frames the packet for actual transmission across the media. When a packet reaches its destination, each layer removes its relevant header, reverses this process (decapsulation), and passes the payload upward until the original data reaches the application.&lt;/p&gt;

&lt;p&gt;Many familiar tools and commands rely on TCP/IP to function. For example, commands like ping and tracert leverage ICMP (Internet Control Message Protocol), a companion to IP that operates at the Internet Layer to provide diagnostic feedback on network reachability and path characteristics. Tcp/ip also underlies utilities like netstat, which displays active TCP connections; telnet or netcat (nc), which test TCP ports and services; and curl or wget, which transfer data over HTTP—an application layer protocol running atop TCP.&lt;/p&gt;

&lt;p&gt;TCP/IP’s enduring success comes from fundamental design principles. It’s decentralized and avoids any single point of failure. IP’s stateless approach means routers simply forward packets without needing to track every session, enabling them to scale efficiently. The modular and layered design means TCP/IP can operate over virtually any hardware—fiber, copper, wireless, satellite—making it adaptable. Additionally, TCP’s connection-oriented protocols guarantee reliable delivery where necessary, while UDP enables speed and efficiency for real-time applications.&lt;/p&gt;

&lt;p&gt;Part 2 Concluded. &lt;/p&gt;

</description>
      <category>networking</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Tracing the Internet — Part 1: ICMP, TTL, Ping &amp; Tracert</title>
      <dc:creator>mthtclone</dc:creator>
      <pubDate>Wed, 23 Jul 2025 16:39:51 +0000</pubDate>
      <link>https://dev.to/mthtclone/tracing-the-internet-part-1-icmp-ttl-ping-tracert-2dlj</link>
      <guid>https://dev.to/mthtclone/tracing-the-internet-part-1-icmp-ttl-ping-tracert-2dlj</guid>
      <description>&lt;p&gt;When your internet connection is slow or a device isn’t responding, most people run to familiar tools like ping, tracert or ipconfig. These are basic network diagnostics tools on Windows, but they are powerful tools despite their simplicity with command line interfaces.&lt;/p&gt;

&lt;p&gt;Before we get into using these tools, it’s essential to know some facts about Internet Control Message Protocol &amp;amp; Time to Live.&lt;/p&gt;

&lt;p&gt;The Internet Control Message Protocol is one of the protocols that operates at the Network Layer of the OSI model. Its primary use being to issue out if data transmission process — between two or more devices — is getting its destination and at the right time.&lt;/p&gt;

&lt;p&gt;If something goes wrong — like a packet can’t reach its destination, or takes too long — ICMP lets the sender know so the data can be resent.&lt;/p&gt;

&lt;p&gt;ICMP is simply a protocol for communicating information about data, but it does not manage data itself. That’s why IMCP is the backbone of diagnostic tools like ping and tracert. For example, when you use &lt;code&gt;ping&lt;/code&gt;, you’re actually sending ICMP Echo Requests to another device.&lt;/p&gt;

&lt;p&gt;It plays a crucial role in error reporting, testing reachability, and measuring response time&lt;/p&gt;

&lt;p&gt;Another thing to note, though, is when I mention ICMP operates at the network layer, this does not mean ICMP has have its own layer within OSI mode. Rather, IP works in conjunction with ICMP, ARP, RARP protocol process incoming or outgoing data.&lt;/p&gt;

&lt;p&gt;Let’s cover the concept of TTL (Time to Live), since TTL is important for understanding tracert.&lt;/p&gt;

&lt;p&gt;Each IP packet comes with a value called Time To Live (TTL) in IPv4 (or Hop Limit in IPv6) to ensure that these packets have a limited lifetime on the network. All IP packets come with 8 bit TTL or Hop Limit header fields which specify how many hops it can traverse on the path to their destination.&lt;/p&gt;

&lt;p&gt;Each time the packet passes through a router (Layer 3 device), its TTL value is reduced by 1. If TTL reaches 0 before the packet arrives, the router simply discards it. This is to prevent packets from endlessly circulating in routing loops.&lt;/p&gt;

&lt;p&gt;TTL is an 8-bit value, so the max possible TTL is 255. While it was originally intended to represent seconds, modern networks treat TTL purely as a hop counter.&lt;/p&gt;

&lt;p&gt;Think of TTL like a ‘gas tank’ for your packet — every router it hits uses a little fuel. Once the tank is empty, the trip is over.&lt;/p&gt;

&lt;p&gt;Default TTL and Hop Limit values vary between different operating systems, here are the defaults for a few:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Linux kernel 2.4 (circa 2001): 255 for TCP, UDP and ICMP
- Linux kernel 4.10 (2015): 64 for TCP, UDP and ICMP
- Windows XP (2001): 128 for TCP, UDP and ICMP
- Windows 10 (2015): 128 for TCP, UDP and ICMP
- Windows Server 2008: 128 for TCP, UDP and ICMP
- Windows Server 2019 (2018): 128 for TCP, UDP and ICMP
- MacOS (2001): 64 for TCP, UDP and ICMP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Since different operating systems use different default TTL values, you can often make an educated guess about the OS of a host by looking at the TTL value in a packet it sends — especially if you have a rough idea how many hops away it is.&lt;br&gt;
ping&lt;/p&gt;

&lt;p&gt;At its core, &lt;code&gt;ping&lt;/code&gt; is a command-line tool used to test connectivity between your computer and another device (like a server, website, or another machine on your network). It works by sending ICMP Echo Request packets to the destination and waiting for ICMP Echo Reply packets in return.&lt;/p&gt;

&lt;p&gt;If you get a reply, it means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The device is reachable.&lt;/li&gt;
&lt;li&gt;The network connection is alive (at least at that moment).&lt;/li&gt;
&lt;li&gt;You get a basic idea of latency (delay in milliseconds).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you don’t get a reply, it could mean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The host is down or unreachable.&lt;/li&gt;
&lt;li&gt;ICMP is being blocked by a firewall.&lt;/li&gt;
&lt;li&gt;There’s a DNS resolution issue.&lt;/li&gt;
&lt;li&gt;There’s a routing problem.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On window, the syntax for the ping command looks like this&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ping &amp;lt;hostname or IP address&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For example, if you ping command google.com, the following output might look like this&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pinging google.com [142.250.190.78] with 32 bytes of data:
Reply from 142.250.190.78: bytes=32 time=20ms TTL=115
Reply from 142.250.190.78: bytes=32 time=21ms TTL=115
Reply from 142.250.190.78: bytes=32 time=19ms TTL=115
Reply from 142.250.190.78: bytes=32 time=20ms TTL=115

Ping statistics for 142.250.190.78:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 19ms, Maximum = 21ms, Average = 20ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;bytes -&amp;gt; the size of the packet (usually 32 bytes on Windows)&lt;br&gt;
time -&amp;gt; How long it took to get a response (in milliseconds)&lt;br&gt;
TTL -&amp;gt; the Time To Live remaining (helps infer the number of hops&lt;br&gt;
Packet Loss -&amp;gt; it some pings don’t get replies, it shows up as lost packets&lt;/p&gt;

&lt;p&gt;A failed ping isn’t always a sign of a down server. Many modern firewalls or servers block ICMP traffic for security reasons. That’s why tools like &lt;code&gt;tracert&lt;/code&gt; can help further narrow things down.&lt;br&gt;
tracert&lt;/p&gt;

&lt;p&gt;While ping tells you if a device is reachable, it doesn’t tell you how your data gets there.&lt;br&gt;
That’s where &lt;code&gt;tracert&lt;/code&gt; (short for trace route) comes in.&lt;/p&gt;

&lt;p&gt;According to Microsoft’s own documentation, &lt;code&gt;tracert&lt;/code&gt; works by sending ICMP Echo packets to the destination with increasing TTL values. Each router along the way decreases that TTL by 1. When a router receives a packet with TTL = 0, it sends back an ICMP “Time Exceeded” message — which is how &lt;code&gt;tracert&lt;/code&gt; learns what that hop was.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The first packet starts with TTL = 1 and fails at the first hop.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The second goes out with TTL = 2, reaches the second hop, and fails there.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This continues until the destination is reached or the max TTL is hit.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not all routers respond to these expired packets. Some silently drop them (which is why you might see &lt;code&gt;* * *&lt;/code&gt; in your trace).&lt;br&gt;
By default, &lt;code&gt;tracert&lt;/code&gt; performs a DNS lookup on each IP it receives. If you don’t want that (and want faster results), use &lt;code&gt;-d&lt;/code&gt; to skip hostname resolution.&lt;/p&gt;

&lt;p&gt;On window, the syntax for the ping command looks like this&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tracert &amp;lt;hostname or IP address&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you use tracert command to google.com, it might looks like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tracing route to google.com [142.250.190.78]
over a maximum of 30 hops:

1 &amp;lt;1 ms &amp;lt;1 ms &amp;lt;1 ms 192.168.1.1
2 11 ms 8 ms 10 ms 10.70.1.1
3 20 ms 18 ms 19 ms 74.125.50.10
…
10 25 ms 27 ms 26 ms 142.250.190.78

Trace complete.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The number at the start is the &lt;strong&gt;hop count&lt;/strong&gt; — this is how many routers deep the packet is at that stage.&lt;/p&gt;

&lt;p&gt;The three time values (e.g. &lt;code&gt;11 ms&lt;/code&gt;, &lt;code&gt;8 ms&lt;/code&gt;, &lt;code&gt;10 ms&lt;/code&gt;) are &lt;strong&gt;response times&lt;/strong&gt; for three separate ICMP packets sent to that hop — it helps you see if there’s consistent delay or packet loss.&lt;/p&gt;

&lt;p&gt;The IP address at the end is the router or node the packet hit at that hop.&lt;/p&gt;

&lt;p&gt;There are cases where one of the hop might look like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2 * * * Request timed out.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This usually means your packet reached that hop, but the router didn’t send back an ICMP “Time Exceeded” message** in response.&lt;/p&gt;

&lt;p&gt;Some routers (usually enterprise firewalls or ISP routers ) are configured to drop ICMP traffic. They still foward your packet to the next hop, but they ignore the TTL-expired ICMP request and don’t reply&lt;/p&gt;

&lt;p&gt;A timeout does not necessarily mean a failure. If the trace continues after the timeout, it just means that hop didn’t respond, but your packet moves on.&lt;/p&gt;

&lt;p&gt;However, a subsequent timeout could indicate that&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a firewall blocking all outgoing ICMP replies.&lt;br&gt;
a downed router.&lt;br&gt;
or simply, your destination is unreachable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Part 1 concluded.&lt;/p&gt;

</description>
      <category>internet</category>
      <category>programming</category>
      <category>networking</category>
    </item>
    <item>
      <title>How to get your 'beloved' context menu back in Window 11</title>
      <dc:creator>mthtclone</dc:creator>
      <pubDate>Mon, 16 Jun 2025 19:20:20 +0000</pubDate>
      <link>https://dev.to/mthtclone/how-to-get-your-beloved-context-menu-back-in-window-11-5f7b</link>
      <guid>https://dev.to/mthtclone/how-to-get-your-beloved-context-menu-back-in-window-11-5f7b</guid>
      <description>&lt;p&gt;When Microsoft introduced Windows 11, it brought a sleek new interface, centered taskbar, and — for better or worse — a redesigned right-click (context) menu. While the new context menu looks modern and simplified, many power users quickly noticed that it hides some commonly used options behind an extra "Show more options" click. &lt;/p&gt;

&lt;p&gt;In Windows 11, the right-click context menu on files and folders is trimmed down by default. Key actions like "Properties," "Cut," "Copy," "Rename," and even third-party app integrations (like 7-Zip or WinRAR) are hidden under an extra layer. This can disrupt workflows, especially if you're used to quick access with a single click.&lt;/p&gt;

&lt;p&gt;The easiest way to get is to simply &lt;strong&gt;Hold the Shift key and right-click&lt;/strong&gt; to see the old context menus in Windows 11.&lt;/p&gt;

&lt;p&gt;You can restore the classic context menu permanently using either of these methods:&lt;/p&gt;

&lt;p&gt;Note: Editing the Windows Registry can be risky. Be sure to back it up or create a system restore point before proceeding.&lt;/p&gt;

&lt;p&gt;Press &lt;code&gt;Win + R&lt;/code&gt;, type &lt;code&gt;regedit&lt;/code&gt; to enter Registry Editor, and navigate to this folder&lt;br&gt;
`HKEY_CURRENT_USER\Software\Classes\CLSID &lt;/p&gt;

&lt;p&gt;Right click to CLSID, click New to create a new key, and name it &lt;code&gt;{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}.&lt;/code&gt; Then, finally, right click that newly created key to add another new key and name it &lt;code&gt;InprocServer32&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;In the right pane, you may want to leave the name to (Default), and the value blank.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpg8at2cc809ohudj4nc4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpg8at2cc809ohudj4nc4.png" alt=" " width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To take effect, go to task manager (shortcut: Ctrl + Shift + Esc), and find &lt;code&gt;Window Explorer&lt;/code&gt; and restart it.&lt;/p&gt;

&lt;p&gt;Whether you're tweaking files, using dev tools, or managing third-party apps, this little fix brings back the speed and familiarity of Windows 10.&lt;/p&gt;

</description>
      <category>microsoft</category>
    </item>
    <item>
      <title>How to setup ERPNext in Ubuntu via VM</title>
      <dc:creator>mthtclone</dc:creator>
      <pubDate>Tue, 10 Jun 2025 08:48:33 +0000</pubDate>
      <link>https://dev.to/mthtclone/how-to-setup-erpnext-in-ubuntu-via-vm-d42</link>
      <guid>https://dev.to/mthtclone/how-to-setup-erpnext-in-ubuntu-via-vm-d42</guid>
      <description>&lt;p&gt;ERPNext is a powerful open-source ERP platform, but installing it directly on your main computer can sometimes feel daunting or risky. Especially if one is not familiar with Linux distro (Ubuntu, here), and unfortunately, ERPNext only works on Ubuntu. Using a virtual machine lets you keep your host system clean while giving ERPNext its own dedicated environment to run and grow.&lt;/p&gt;

&lt;p&gt;In this guide, we will walk through the step-by-step process of creating an Ubuntu VM, installing all the prerequisites, and setting up ERPNext so you can start managing your business operations.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Bugs or issues you might encounter during the process are listed at the end of this guide. I do this to prevent disrupting the flow of the guide if I keep randomly mentioning them in between, and so this guide will assume that (ideally) you have a smooth installation process.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First, we need a virtual machine, and we'll be using Oracle VirtualBox. Download it here: &lt;a href="https://www.virtualbox.org/wiki/Downloads" rel="noopener noreferrer"&gt;https://www.virtualbox.org/wiki/Downloads&lt;/a&gt;&lt;br&gt;
Pick the installer for Windows (assuming most readers here are Windows users). The installation process is straightforward and follows the usual steps.&lt;br&gt;
Ubuntu 22 LTS&lt;/p&gt;

&lt;p&gt;Next, we select a Linux distribution -- Ubuntu. Other distros, and Ubuntu flavors might work, but ERPNext is best suited with Ubuntu. Here, I recommend Ubuntu 22 LTS because it is proven to be the most stable with ERPNext.&lt;/p&gt;

&lt;p&gt;Download Ubuntu 22 LTS here: &lt;a href="https://releases.ubuntu.com/jammy/" rel="noopener noreferrer"&gt;https://releases.ubuntu.com/jammy/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Creating Your Ubuntu Virtual Machine&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that VirtualBox is installed and ready, let's create your Ubuntu virtual machine. Open VirtualBox and click New to start building your digital sandbox. Give your VM a name, like Ubuntu_ERPNext, set the type to Linux, and pick Ubuntu 64-bit as the version (the VM will do this automatically for you).&lt;/p&gt;

&lt;p&gt;If your hostname is something like Ubuntu_ERPNext, change it simply to Ubuntu.&lt;/p&gt;

&lt;p&gt;Allocate at least 4 GB of RAM (4096 MB), assign 2 CPU cores, and for the virtual hard disk, I’ll go with the default 25 GB. Ubuntu isn’t as large as Windows, so you don’t need to worry about space here.&lt;/p&gt;

&lt;p&gt;For the network adapter, choose Bridged Adapter. This allows your VM to connect through your host machine’s network, which will be necessary when fetching resources and dependencies for ERPNext.&lt;/p&gt;

&lt;p&gt;Don’t forget to prioritize the hard drive in the boot order settings.&lt;/p&gt;

&lt;p&gt;After creating the VM, click Start to boot it up. The VM should load the Ubuntu installer from the ISO you attached. If you see the GRUB menu, choose Install Ubuntu and proceed. If the VM boots directly into the Live Environment (a fully functional trial version running from the virtual USB), simply double-click the Install Ubuntu icon on the desktop to start the installation.&lt;/p&gt;

&lt;p&gt;Follow the installer prompts to set your language, keyboard, timezone, and create your user account. When asked about installation type, select Erase disk and install Ubuntu — this affects only the VM’s virtual disk, so your main computer is safe.&lt;/p&gt;

&lt;p&gt;Once you start the installation, it will take about 10 minutes to complete. After it finishes, restart the VM and log into your fresh Ubuntu system.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Update Ubuntu and Install Prerequisites&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that you have Ubuntu installed and running inside your VM, it’s important to make sure your system is up-to-date and ready for ERPNext.&lt;/p&gt;

&lt;p&gt;Open the Terminal by pressing Ctrl + Alt + T, then run these commands to update your package lists and upgrade installed software:&lt;br&gt;
Here, if you find your terminal not opening, this is the most random solution I found for it. You just need to change the language to something else from UK to US, vice versa.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command refreshes the package information and installs any available updates to keep your system secure and stable.&lt;/p&gt;

&lt;p&gt;Once your system is updated, install each required package one by one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install -y curl
sudo apt install -y git
sudo apt install -y python3-dev
sudo apt install -y python3-pip
sudo apt install -y software-properties-common
sudo apt install -y xvfb libfontconfig wkhtmltopdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each of these tools plays a role in preparing your system:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl: Downloads files and interacts with APIs
git: Version control system to clone ERPNext source code
python3-dev: Python headers needed for compiling dependencies
python3-pip: Python package manager
software-properties-common: Adds useful utilities like add-apt-repository
xvfb &amp;amp; libfontconfig: Virtual framebuffer and font configuration for rendering PDFs
wkhtmltopdf: Converts HTML to PDF for report generation in ERPNext
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Next, ERPNext requires a database to function, so we’ll install the MariaDB server along with its client tools and development libraries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install -y mariadb-server
sudo apt install -y mariadb-client
sudo apt install -y libmysqlclient-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s what each of these packages does:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mariadb-server: The actual MariaDB database server used to store ERPNext data
mariadb-client: Command-line tools to interact with the MariaDB server
libmysqlclient-dev: Development libraries for MySQL-compatible clients, needed for building database integrations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For caching, queuing, and in-memory data storage, ERPNext also requires the Redis server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install -y redis-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, download and run the setup script from NodeSource to add the Node.js 22 repository to your system’s apt sources. This prepares your system for installing Node.js and the npm package manager:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -fsSL https://deb.nodesource.com/setup-22.x | sudo -E bash -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, install Node.js and Yarn:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install -y nodejs
sudo npm install -g yarn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what each command does:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;setup-22.x script: Adds the Node.js 22 repository to apt
nodejs: Installs Node.js runtime and npm package manager
yarn: Installs Yarn globally, a faster alternative to npm for managing JavaScript dependencies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;That's it for all the required dependencies.&lt;br&gt;
Setting up Frappe and ERPNext&lt;/p&gt;

&lt;p&gt;To install frappe-bench, it's important to first set up a Python virtual environment. On Debian/Ubuntu systems, Python enforces PEP 668 protections, which may prevent package installations outside a virtual environment.&lt;/p&gt;

&lt;p&gt;We'll start by creating a development directory and setting up the virtual environment inside it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Create a directory named frappe-dev
mkdir frappe-dev

# Navigate into the directory
cd frappe-dev

# Create a virtual environment named 'venv'
python3 -m venv venv

# Activate the virtual environment
source venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once activated, you’ll see (venv) appear in your terminal prompt — indicating that the virtual environment is now active. You can deactivate the environment anytime by running deactivate.&lt;/p&gt;

&lt;p&gt;With this in place, you’re now ready to install frappe-bench and continue the setup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install frappe-bench
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, initialize the Frappe bench by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bench init frappe-bench
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a new folder named frappe-bench with all the necessary files and configuration for your Frappe development environment.&lt;/p&gt;

&lt;p&gt;If you run into errors during initialization, it's likely that your system is missing some required build tools. Install them with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install -y pkg-config build-essential
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These packages provide essential system utilities and compilers needed to build Python and Node.js dependencies during the bench setup process.&lt;/p&gt;

&lt;p&gt;Most importantly, you need to download the ERPNext application into your bench environment. Run the following command inside your frappe-bench directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bench get-app erpnext https://github.com/frappe/erpnext
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command clones the ERPNext repository and makes it available for installation on your bench.&lt;/p&gt;

&lt;p&gt;After downloading the ERPNext app, you are ready to create your ERPNext site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bench new-site erp.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can name the site whatever you prefer; here, erp.local is just an example.&lt;/p&gt;

&lt;p&gt;When creating a new site, you will be prompted to set the MariaDB root password and the site’s Administrator password. However, at this point, these passwords may not yet be configured.&lt;/p&gt;

&lt;p&gt;By default, MySQL on Ubuntu uses the auth_socket plugin for the root user. This means instead of authenticating with a password, MySQL verifies that the user running the command matches the MySQL root user via the Unix socket. For example, if you are logged in as vboxuser, you are not MySQL's root user and cannot log in as root using a password, because MySQL expects socket-based authentication instead.&lt;/p&gt;

&lt;p&gt;Since MySQL on Ubuntu uses the auth_socket plugin by default, password-based login as root will fail—even if you're the admin. The recommended approach is to create a new MariaDB user with a password or change the root user to use password authentication.&lt;/p&gt;

&lt;p&gt;If not prompted automatically, you can manually set or change the password inside the MariaDB shell (sudo mysql) using:&lt;/p&gt;

&lt;p&gt;ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_secure_password';&lt;br&gt;
FLUSH PRIVILEGES;&lt;/p&gt;

&lt;p&gt;This changes the root user to use password authentication instead of auth_socket. After this, you can log in with the root password you just set.&lt;/p&gt;

&lt;p&gt;Earlier, we installed redis-server, but we haven’t enabled or started it yet. Let’s do that now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl start redis-server
sudo systemctl enable redis-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, configure Redis for bench by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bench setup redis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, you can create your ERPNext site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bench new-site erp.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the site is created, Frappe will automatically set it up. Once done, you can access the site by visiting:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://127.0.0.1:8000 — if you're accessing it from the same machine
http://192.168.100.73:8000 — — note that the last part of the IP, or host IP (e.g., .73) may vary depending on your device.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;On the login screen, use the default username Administrator and the Administrator password you set during bench new-site setup.&lt;/p&gt;

&lt;p&gt;And with that, your ERPNext system is up and running! You can now explore features like the Point of Sale (POS) system and begin configuring your workspace to suit your business needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Common Installation Issues&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;1) “User is not in the sudoers file” error&lt;/p&gt;

&lt;p&gt;If your username (e.g., vboxuser) isn't in the sudo group, you won't be able to run commands with sudo. To fix this, follow these steps to add yourself to the sudo group from a root shell:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reboot your system and enter the GRUB menu by pressing Esc or Shift during boot.
Select your Ubuntu entry and press e to edit it.
Find the line that starts with linux /boot/vmlinuz and add init=/bin/bash to the end of that line.
Press Ctrl + X or F10 to boot into a root shell.
Remount the filesystem as writable:
mount -o remount,rw /
Add your user to the sudo group:
usermod -aG sudo vboxuser
(Optional but recommended) Set a root password:
passwd
Finally, reboot the system normally:
exec /sbin/init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After this, you should be able to use sudo normally with your user account.&lt;/p&gt;

&lt;p&gt;2) CSS Files Not Loading (404 Errors)&lt;/p&gt;

&lt;p&gt;If your ERPNext login page or site loads without any styling — just plain HTML — and your browser console or terminal shows errors like:&lt;/p&gt;

&lt;p&gt;/assets/frappe/dist/css/login.bundle.620LYWTE.css - 404&lt;br&gt;
/assets/frappe/dist/css/website.bundle.TTBWK5JW.css - 404&lt;/p&gt;

&lt;p&gt;This happens because your site isn't running in production mode and the necessary CSS bundles haven’t been built yet.&lt;/p&gt;

&lt;p&gt;To fix it:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Run the following to build the required production files:
bench build --production
Then restart the bench:
bench start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you still face issues, make sure your file permissions are not blocking access. Run:&lt;/p&gt;

&lt;p&gt;sudo chmod 755 /home/vboxuser   # Replace with your actual username&lt;br&gt;
sudo chmod -R o+rx /home/frappe-dev&lt;/p&gt;

&lt;p&gt;This ensures that the ERPNext server has permission to access your assets directory.&lt;/p&gt;

</description>
      <category>ubuntu</category>
      <category>opensource</category>
      <category>linux</category>
      <category>virtualmachine</category>
    </item>
    <item>
      <title>Data Conversion</title>
      <dc:creator>mthtclone</dc:creator>
      <pubDate>Tue, 10 Jun 2025 08:31:19 +0000</pubDate>
      <link>https://dev.to/mthtclone/data-conversion-4hja</link>
      <guid>https://dev.to/mthtclone/data-conversion-4hja</guid>
      <description>&lt;p&gt;Data is simply a syllable that hardware uses to speak to each other. Why does this data need converting? Because the Tower of Babel is not real — no hardware speaks a single language (read: format). Conversion is translation. Compatibility. Survival. Data is not always native to the places it lands.&lt;/p&gt;

&lt;p&gt;Data conversion, at its core, is about changing data from one format, type, or structure into another so that it can be understood, processed, or stored differently. Think of it like moving water between containers. The shape of the container changes, but it’s still water — just restructured to fit where it needs to go. This is when data changes its outer shell; its packaging stays the same so different system can understand or display it. This happens at the programming level where data undergoes a deeper metamorphosis: a number becomes a string, a string becomes a boolean, and so on.&lt;/p&gt;

&lt;p&gt;Binary is the most basic language of computers. It only has two states: 1 &amp;amp; 0. These are simply denotations for possible electric states — high and low. Each digit (called a bit) represents a power of 2.&lt;/p&gt;

&lt;p&gt;Binary means base-2, so computers use the counting system of base-2, just as we use the counting system of base-10 because we have 10 digits.&lt;/p&gt;

&lt;p&gt;Base-10:&lt;/p&gt;

&lt;p&gt;253 = 2×100 + 5×10 + 3×1 = 2×10² + 5×10¹ + 3×10⁰&lt;/p&gt;

&lt;p&gt;Base-2:&lt;/p&gt;

&lt;p&gt;1101 = 1×2³ + 1×2² + 0×2¹ + 1×2⁰ = 8 + 4 + 0 + 1 = 13&lt;/p&gt;

&lt;p&gt;With just one bit, you can represent 2 possible values: 0 or 1. Add one more bit, and suddenly you have 4 values: 00, 01, 10, and 11. With three bits, the number jumps to 8 values, with four bits it doubles again to 16, and so on. In general, with n bits, you can represent 2n unique values.&lt;/p&gt;

&lt;p&gt;Bits rarely live alone. They group together in chunks called bytes — usually 8 bits per byte. One byte can represent 28=256 different values, enough to cover all standard ASCII characters, numbers, and more. This exponential growth forms the backbone of modern computing, from the smallest data pieces to the largest memory systems.&lt;/p&gt;

&lt;p&gt;Unfortunately, our ancestors didn't have 1 digit on each hand, thus nor they ever cared about thinking in binary. We, decimal thinkers, must have ways to translate into machine-speak (binary), and vice versa. How does a computer understand our decimal language? It doesn't. We must provide the translation. Every number we write must be converted into its binary equivalent so the machine can store and operate on.&lt;/p&gt;

&lt;p&gt;Decimal, 156 is 10011100 in binary format. How?&lt;br&gt;
We start from the highest power of 2 that fits into 156 and work our way down:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2⁷ = 128 → fits! Subtract 128 from 156, leaving 28.
2⁶ = 64 → too big for 28, skip it.
2⁵ = 32 → still too big for 28, skip.
2⁴ = 16 → fits! 28 - 16 = 12.
2³ = 8 → fits! 12 - 8 = 4.
2² = 4 → fits! 4 - 4 = 0.
2¹ = 2 → doesn't fit, skip.
2⁰ = 1 → doesn't fit, skip.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Putting it together:&lt;br&gt;
156 = 128 + 16 + 8 + 4 = 10011100&lt;/p&gt;

&lt;p&gt;But what if we want a more human-readable form of binary? What if we don’t want to count eight 1s and 0s every time we look at something?&lt;/p&gt;

&lt;p&gt;That’s where hexadecimal comes in.&lt;/p&gt;

&lt;p&gt;Hexadecimal is the shorthand language for binary. It's base-16, meaning it uses 16 different symbols:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F
Where A = 10, B = 11, C = 12, ..., F = 15.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why base-16? Because 1 hex digit = 4 binary bits. You can take a long binary string, split it into chunks of 4 bits, and replace each with a single hex digit.&lt;/p&gt;

&lt;p&gt;For example, take this binary number: 10101100&lt;br&gt;
Split it into two 4-bit chunks: 1010    1100&lt;/p&gt;

&lt;p&gt;Convert each chunk:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1010 = (1×2³) + (0×2²) + (1×2¹) + (0×2⁰) = 8 + 0 + 2 + 0 = 10 → A
1100 = (1×2³) + (1×2²) + (0×2¹) + (0×2⁰) = 8 + 4 + 0 + 0 = 12 → C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, 10101100 is AC in hexadecimal.&lt;/p&gt;

&lt;p&gt;Hexadecimal isn't merely a shorthand. Let's take a look a common place where you can see these labels.&lt;br&gt;
Memory Addresses&lt;/p&gt;

&lt;p&gt;When a computer runs a program, it stores data in its memory. Each byte in memory has its own unique number, called an address, so the computer can find and use the data it needs.&lt;/p&gt;

&lt;p&gt;Every piece of data in a computer’s memory has an address. These addresses are often huge numbers when written in decimal, but in hex, they become much cleaner and easier to read.&lt;/p&gt;

&lt;p&gt;Let's suppose that a memory address is this: 0x1A3F (0x is the prefix that signals that the number is in hexadecimal).&lt;br&gt;
If we apply our same method of conversion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0x1 = 0001  
0xA = 1010  
0x3 = 0011  
0xF = 1111
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, the memory address looks like this in binary: 0001 1010 0011 1111&lt;br&gt;
Each hex digit neatly represents 4 bits, making conversion and understanding much simpler.&lt;/p&gt;

&lt;p&gt;Computers use these addresses to access data quickly. Hexadecimal makes it easier to spot patterns and boundaries in memory addresses — something critical when debugging or working close to the hardware.&lt;/p&gt;

&lt;p&gt;In short, memory addresses are simply labels for locations in a computer’s memory, and those labels are commonly written in hexadecimal format because it’s a neat, compact way to represent the underlying binary addresses.&lt;br&gt;
A Heartfelt Letter from a Computer&lt;/p&gt;

&lt;p&gt;We’ve traced the metamorphosis of data — from raw binary to structured decimal, then into the refined shorthand of hexadecimal. Now, it takes on its most poetic form: the string.&lt;/p&gt;

&lt;p&gt;Legend has it there was once a protest among the metallic classes demanding their binary voices be heard. They refused to be bound by the cold, inhuman language of 1s and 0s.&lt;/p&gt;

&lt;p&gt;The academic elites, however, did not so easily grant the public the privilege of speaking to machines in human words — Homo Sapiens.&lt;/p&gt;

&lt;p&gt;The roads and buildings were taken and seized — party-line debates, philosophical crises, and whispered questions of whether this, perhaps, was a moral awakening.&lt;br&gt;
What is a String?&lt;/p&gt;

&lt;p&gt;A string is simply a sequence of characters - letters, numbers, punctuation marks, spaces, even symbols. It's how text is represented and stored in programming.&lt;/p&gt;

&lt;p&gt;We simply understand it as sentences. May it be a name, a paragraph, or maybe your favorite poem.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_I hide myself within my flower,
That fading from your Vase,
You, unsuspecting, feel for me -
Almost a loneliness.
(903) Emily Dickinson_
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In computer, each of those characters is encoded into numbers, and such numbers are stored in memories.&lt;/p&gt;

&lt;p&gt;The string, Hello is made up of five characters: 'H','e','l','l','o'. Each of these characters is stored as number, according to an encoding standard - like ASCII or Unicode.&lt;/p&gt;

&lt;p&gt;So, Hello in its binary form is 01001000 01100101 01101100 01101100 01101111, and in ASCII: [72, 101, 108, 108, 111]&lt;/p&gt;

&lt;p&gt;So the string Hello is stored in memory as a sequence of bytes. This is how computers interpret and store what we see as readable text.&lt;/p&gt;

&lt;p&gt;So next time you say 'Hello' to your computer, remember — to it, you’re speaking in byte-sized numbers.&lt;br&gt;
ASCII&lt;/p&gt;

&lt;p&gt;To turn human-readable characters into computer-readable numbers (remember, numbers are the only thing they understand!), we need a system. A formalism between machine and humans: the metalization of our flesh.&lt;/p&gt;

&lt;p&gt;Enter ASCII, the American Standard Code for Information Interchange. Created in the early 1960s, it became the original common tongue between humans and machines.&lt;/p&gt;

&lt;p&gt;ASCII assigns a unique number to each character. Just as in Morse code where "dot-dash" patterns represent letters, ASCII translates characters into numerical codes — which computers then convert into binary.&lt;/p&gt;

&lt;p&gt;Before ASCII existed, different manufacturers used different encodings, causing chaos when systems tried to talk to each other. Don't get it twisted. The Tower of Babel is still not real.&lt;/p&gt;

&lt;p&gt;ASCII gave everyone a shared alphabet of 128 characters. This is enough to cover all the English language, digits, punctuation, and control characters (like newline or tab).&lt;br&gt;
Another One Bytes the Dust&lt;/p&gt;

&lt;p&gt;So far, we have witnessed a metamorphosis of a spark to the curves of human language -- from binary to hex, to string, to ASCII -- the first bridge between two worlds, man and machine; flesh and silicon.&lt;/p&gt;

&lt;p&gt;Just as we understand another one's language if we develop a thought-form in their domain -- their language. We only understand computational processes only if we abstract and think like them, and vice versa. Programming is, in its essence, a data conversion.&lt;/p&gt;

&lt;p&gt;And maybe that's all communication ever was -- conversion. &lt;/p&gt;

</description>
      <category>programming</category>
    </item>
  </channel>
</rss>
