<?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: Jeremy Morgan</title>
    <description>The latest articles on DEV Community by Jeremy Morgan (@jeremycmorgan).</description>
    <link>https://dev.to/jeremycmorgan</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F48220%2F392b62cb-75f7-4107-9fc9-0c9e35794320.png</url>
      <title>DEV Community: Jeremy Morgan</title>
      <link>https://dev.to/jeremycmorgan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jeremycmorgan"/>
    <language>en</language>
    <item>
      <title>SQL to Cypher - 10 Queries You Already Know</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Wed, 05 Aug 2026 15:38:25 +0000</pubDate>
      <link>https://dev.to/jeremycmorgan/sql-to-cypher-10-queries-you-already-know-4m97</link>
      <guid>https://dev.to/jeremycmorgan/sql-to-cypher-10-queries-you-already-know-4m97</guid>
      <description>&lt;h2&gt;
  
  
  The query every backend developer has needed and nobody enjoys writing
&lt;/h2&gt;

&lt;p&gt;In March 2016, npm removed an 11-line package called left-pad. Within minutes, builds began failing across the JavaScript ecosystem. It broke thousands of projects, including tools like Babel. Many developers didn't choose left-pad directly; it was hidden in their dependencies and went unnoticed until it vanished.&lt;/p&gt;

&lt;p&gt;That incident points at a question you have probably asked about your own stack: what is actually in my dependency tree? Not just the 30 packages in your &lt;code&gt;package.json&lt;/code&gt;. Everything they pull in, and everything those pull in, all the way down.&lt;/p&gt;

&lt;p&gt;In a relational database, dependencies live in a self-referencing join table. "Everything, all the way down" means a recursive CTE. Here is that query on a snapshot of the npm registry. It finds the full runtime dependency tree of &lt;code&gt;express&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="k"&gt;RECURSIVE&lt;/span&gt; &lt;span class="n"&gt;closure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;depends_on_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;dependencies&lt;/span&gt;
  &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;package_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'express'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;dep_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'runtime'&lt;/span&gt;
  &lt;span class="k"&gt;UNION&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;depends_on_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;depth&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;closure&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;
  &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dep_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'runtime'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;transitive_deps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;max_depth&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;closure&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the result:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fktdkp7gregzoa7384ykh.webp" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fktdkp7gregzoa7384ykh.webp" alt="Query showing runtime dependencies" width="800" height="106"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It works. Here it shows 63 packages, 11 levels deep. But it is twelve lines, and every line matters. There is an anchor part, a recursive part, and a &lt;code&gt;UNION&lt;/code&gt; doing quiet work to remove duplicates. A graph asks the same question in two lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;:Package&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;name:&lt;/span&gt; &lt;span class="s1"&gt;'express'&lt;/span&gt;&lt;span class="ss"&gt;})&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:DEPENDS_ON&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dep&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;dep&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;transitive_deps&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is not a shortened excerpt. That is the whole query. It returns the same 63 packages.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa1esqmprj695t3s9f6b4.webp" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa1esqmprj695t3s9f6b4.webp" alt="Query showing runtime dependencies" width="799" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cypher is Neo4j's query language. For a SQL developer, it is less a new language than a new notation for questions you already know how to ask. This article proves that claim with ten translations. They run from "this is just SQL with arrows" up to the query above, plus one final twist that SQL has no clean answer for. By the end, you should be able to read Cypher on sight and write the first seven queries yourself, today.&lt;/p&gt;

&lt;h2&gt;
  
  
  The dataset, so you can check my work
&lt;/h2&gt;

&lt;p&gt;Every query runs against a fixed snapshot of npm. It starts with the top 5,000 most-used packages, then follows their runtime dependencies until the set is complete. The result is about 5,600 packages, their maintainers, and every dependency link among them. The exact same data exists twice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Relational (SQLite):&lt;/strong&gt; four tables. This is the shape the data naturally takes in a relational model.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0ksyjp6s2pxzkcko0p4o.webp" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0ksyjp6s2pxzkcko0p4o.webp" alt="Relational Diagram of our Model" width="800" height="546"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;packages(package_name, description, license, latest_version, weekly_downloads, deprecated)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dependencies(package_name, depends_on_name, dep_type, semver_range)&lt;/code&gt;, the join table&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;maintainers(username)&lt;/code&gt; and &lt;code&gt;package_maintainers(username, package_name)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Graph (Neo4j):&lt;/strong&gt; the same facts as nodes and relationships.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqt7kprrgh41qinrii55s.webp" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqt7kprrgh41qinrii55s.webp" alt="Graph Diagram of our Model" width="800" height="152"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;(:Package)&lt;/code&gt; and &lt;code&gt;(:Maintainer)&lt;/code&gt; nodes with the same properties&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;(:Package)-[:DEPENDS_ON {range}]-&amp;gt;(:Package)&lt;/code&gt; for runtime dependencies&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;(:Package)-[:DEV_DEPENDS_ON {range}]-&amp;gt;(:Package)&lt;/code&gt; for dev dependencies&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(:Maintainer)-[:MAINTAINS]-&amp;gt;(:Package)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  From join table to relationships
&lt;/h3&gt;

&lt;p&gt;Notice where the join table went. Each row of &lt;code&gt;dependencies&lt;/code&gt; became a relationship. Its columns split in an interesting way. The &lt;code&gt;semver_range&lt;/code&gt; is a fact about the dependency itself, so it became a property on the relationship. But &lt;code&gt;dep_type&lt;/code&gt; became the relationship's &lt;em&gt;type&lt;/em&gt;. Runtime and dev dependencies are different kinds of link, not different values in a column. Query 3 will show why that choice pays off.&lt;/p&gt;

&lt;p&gt;Note: this snapshot collapses versions. There is one node per package, and the links come from each package's &lt;code&gt;latest&lt;/code&gt; version. The semver ranges are saved as text but not resolved. So the graph answers "what does the current ecosystem depend on," not "what exact files does &lt;code&gt;npm install&lt;/code&gt; produce." Version-level modeling is a different and much bigger graph.&lt;/p&gt;

&lt;p&gt;Both databases, the CSVs, and the build pipeline are in the &lt;a href="https://github.com/JeremyMorgan/sql-to-cypher" rel="noopener noreferrer"&gt;companion repository&lt;/a&gt;. You can load the graph into a free &lt;a href="https://neo4j.com/product/auradb/" rel="noopener noreferrer"&gt;Aura&lt;/a&gt; instance by pasting &lt;a href="https://github.com/JeremyMorgan/sql-to-cypher/blob/main/load_aura.cypher" rel="noopener noreferrer"&gt;this script&lt;/a&gt;. Or download &lt;code&gt;npm.db&lt;/code&gt; and follow along in SQLite.&lt;/p&gt;

&lt;h2&gt;
  
  
  Queries 1 to 3: the automatic translations
&lt;/h2&gt;

&lt;p&gt;For filtering, sorting, and picking columns, Cypher works just like SQL. The main change is how you point at your data. Instead of FROM packages p, you write MATCH (p:Package). The parentheses draw a node, the label picks which kind, and p is an alias, doing the same job it does in SQL.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. SELECT with WHERE
&lt;/h3&gt;

&lt;p&gt;Start with every MIT-licensed package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;package_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;packages&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;license&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'MIT'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fekrh2t4kupxdbhf235w0.webp" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fekrh2t4kupxdbhf235w0.webp" alt="Results of Query from SQL" width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same query in Cypher:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;p:&lt;/span&gt;&lt;span class="n"&gt;Package&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;              &lt;span class="c1"&gt;// (1)&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;p.license&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'MIT'&lt;/span&gt;        &lt;span class="c1"&gt;// (2)&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;p.name&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p.description&lt;/span&gt;   &lt;span class="c1"&gt;// (3)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff04o7fe2xynu87cy1hjz.webp" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff04o7fe2xynu87cy1hjz.webp" alt="Results of Query from Cypher" width="800" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And as you can see the output is identical to the result of the SQL query. &lt;/p&gt;

&lt;h3&gt;
  
  
  2. ORDER BY and LIMIT
&lt;/h3&gt;

&lt;p&gt;Now the ten most-downloaded packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;package_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weekly_downloads&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;packages&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;weekly_downloads&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same question in Cypher:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;p:&lt;/span&gt;&lt;span class="n"&gt;Package&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;p.name&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p.weeklyDownloads&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;p.weeklyDownloads&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same keywords, same meaning. There is nothing to learn here. That is the point. &lt;/p&gt;

&lt;h3&gt;
  
  
  3. Your first JOIN becomes a pattern
&lt;/h3&gt;

&lt;p&gt;The direct runtime dependencies of &lt;code&gt;express&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;depends_on_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;semver_range&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;packages&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'express'&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dep_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'runtime'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Cypher:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;:Package&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;name:&lt;/span&gt; &lt;span class="s1"&gt;'express'&lt;/span&gt;&lt;span class="ss"&gt;})&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="py"&gt;d:&lt;/span&gt;&lt;span class="n"&gt;DEPENDS_ON&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;dep:&lt;/span&gt;&lt;span class="n"&gt;Package&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;dep.name&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d.range&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the first translation where the shape changes, not just the keywords. The &lt;code&gt;JOIN ... ON&lt;/code&gt; clause is gone. The connection between two packages is stored as a relationship, so the arrow &lt;code&gt;-[:DEPENDS_ON]-&amp;gt;&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; the join, already built.&lt;/p&gt;

&lt;p&gt;Look at what happened to &lt;code&gt;AND d.dep_type = 'runtime'&lt;/code&gt;. It disappeared. Runtime and dev dependencies are different relationship types, so asking for &lt;code&gt;DEPENDS_ON&lt;/code&gt; filters by itself. Want dev dependencies instead? Write &lt;code&gt;-[:DEV_DEPENDS_ON]-&amp;gt;&lt;/code&gt;. Want both? Write &lt;code&gt;-[:DEPENDS_ON|DEV_DEPENDS_ON]-&amp;gt;&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;In SQL, this is the filter you always have to remember, and the bug you ship when you forget it. In the graph, it became part of the &lt;em&gt;question's&lt;/em&gt; grammar.&lt;/p&gt;

&lt;p&gt;Both queries return &lt;strong&gt;28&lt;/strong&gt; rows. Express pulls in &lt;strong&gt;28&lt;/strong&gt; packages directly. Hold that number. Query 10 will tell you what it grows into.&lt;/p&gt;

&lt;h2&gt;
  
  
  Queries 4 to 6: aggregation without GROUP BY
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4. The join you write twice
&lt;/h3&gt;

&lt;p&gt;The dependencies of express's dependencies, two levels down, by hand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;d2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;depends_on_name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="n"&gt;d1&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="n"&gt;d2&lt;/span&gt;
  &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;d2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;depends_on_name&lt;/span&gt;
 &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;d2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dep_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'runtime'&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;d1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'express'&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;d1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dep_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'runtime'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same question in Cypher:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;:Package&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;name:&lt;/span&gt; &lt;span class="s1"&gt;'express'&lt;/span&gt;&lt;span class="ss"&gt;})&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:DEPENDS_ON&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;dep:&lt;/span&gt;&lt;span class="n"&gt;Package&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;dep.name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each extra level in SQL costs another self-join of the &lt;code&gt;dependencies&lt;/code&gt; table. You add &lt;code&gt;d3&lt;/code&gt;, &lt;code&gt;d4&lt;/code&gt;, &lt;code&gt;d5&lt;/code&gt;, each with its own &lt;code&gt;ON&lt;/code&gt; clause and its own &lt;code&gt;dep_type&lt;/code&gt; filter to not forget. &lt;/p&gt;

&lt;p&gt;In Cypher, depth is a number. Write &lt;code&gt;*2&lt;/code&gt; for exactly two hops, or &lt;code&gt;*1..3&lt;/code&gt; for one to three. This query is a preview. You can feel where hand-written depth stops working, and query 10 is waiting there. &lt;/p&gt;

&lt;h3&gt;
  
  
  5. GROUP BY is implicit
&lt;/h3&gt;

&lt;p&gt;Which packages have the most direct dependencies?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;dep_count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;packages&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dep_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'runtime'&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;dep_count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Cypher:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;p:&lt;/span&gt;&lt;span class="n"&gt;Package&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:DEPENDS_ON&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;p.name&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;depCount&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;depCount&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no &lt;code&gt;GROUP BY&lt;/code&gt; in Cypher. After a week, you will not miss it. The rule is simple. Any plain expression that appears next to an aggregate in &lt;code&gt;RETURN&lt;/code&gt; (or &lt;code&gt;WITH&lt;/code&gt;) becomes a grouping key. Since &lt;code&gt;p.name&lt;/code&gt; sits next to &lt;code&gt;count(*)&lt;/code&gt;, Cypher groups by it. This also removes SQL's most tedious error: the "column must appear in the GROUP BY clause" dance, where you repeat every selected column a second time.&lt;/p&gt;

&lt;p&gt;One more detail. The empty node &lt;code&gt;()&lt;/code&gt; is anonymous. We are counting edges to anything, so the target needs no name. Say only what you need.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. HAVING becomes WITH ... WHERE
&lt;/h3&gt;

&lt;p&gt;The load-bearing packages: the ones that more than 100 other packages depend on directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;depends_on_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;dependents&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dep_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'runtime'&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;depends_on_name&lt;/span&gt;
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;dependents&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same question in Cypher:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;p:&lt;/span&gt;&lt;span class="n"&gt;Package&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:DEPENDS_ON&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;dependents&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;dependents&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;p.name&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dependents&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;dependents&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things happened here. First, the arrow flipped. The pattern &lt;code&gt;&amp;lt;-[:DEPENDS_ON]-&lt;/code&gt; counts &lt;em&gt;incoming&lt;/em&gt; links: who depends on &lt;code&gt;p&lt;/code&gt;, not what &lt;code&gt;p&lt;/code&gt; depends on. Direction is visible in the pattern. SQL hides it in which column you group by. Quick, was it &lt;code&gt;package_name&lt;/code&gt; or &lt;code&gt;depends_on_name&lt;/code&gt;? &lt;/p&gt;

&lt;p&gt;Second, meet &lt;code&gt;WITH&lt;/code&gt;. It is the construct SQL never gave you: a pipe between query stages. Aggregate, then filter the result, then keep going. &lt;code&gt;HAVING&lt;/code&gt; exists in SQL only because &lt;code&gt;WHERE&lt;/code&gt; runs before aggregation. Cypher does not need a special keyword. You place the &lt;code&gt;WHERE&lt;/code&gt; after the aggregation in the pipeline. One mental model replaces two keywords.&lt;/p&gt;

&lt;p&gt;Reach for &lt;code&gt;WITH&lt;/code&gt; any time you catch yourself wanting a subquery or a second CTE stage. It covers most of both.&lt;/p&gt;

&lt;h2&gt;
  
  
  Queries 7 to 9: the patterns that replace subqueries
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7. LEFT JOIN ... IS NULL becomes OPTIONAL MATCH
&lt;/h3&gt;

&lt;p&gt;Leaf packages: in the dataset, but nothing else depends on them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;packages&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
&lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;
  &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;depends_on_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt;
 &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dep_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'runtime'&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The anti-join translates straight across. &lt;code&gt;OPTIONAL MATCH&lt;/code&gt; is exactly &lt;code&gt;LEFT JOIN&lt;/code&gt;: match if you can, bind &lt;code&gt;NULL&lt;/code&gt; if you cannot, then keep the rows where the match failed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;p:&lt;/span&gt;&lt;span class="n"&gt;Package&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;OPTIONAL&lt;/span&gt; &lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="py"&gt;d:&lt;/span&gt;&lt;span class="n"&gt;DEPENDS_ON&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;p.name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But the graph does not need the join at all. The &lt;code&gt;LEFT JOIN ... IS NULL&lt;/code&gt; pattern makes you assemble every non-match just to count that it is missing. The real question is simpler: &lt;em&gt;does anything depend on &lt;code&gt;p&lt;/code&gt;?&lt;/em&gt; An &lt;code&gt;EXISTS&lt;/code&gt; predicate in &lt;code&gt;WHERE&lt;/code&gt; asks exactly that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;p:&lt;/span&gt;&lt;span class="n"&gt;Package&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="ow"&gt;NOT&lt;/span&gt; &lt;span class="ow"&gt;EXISTS&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:DEPENDS_ON&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;()&lt;/span&gt; &lt;span class="ss"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;p.name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where the graph pulls ahead. &lt;code&gt;EXISTS { }&lt;/code&gt; is an existence check: it stops the moment one incoming &lt;code&gt;DEPENDS_ON&lt;/code&gt; is found and never enumerates the rest. Because Neo4j stores the relationship degree on every node, the question, does &lt;code&gt;p&lt;/code&gt; have any incoming &lt;code&gt;DEPENDS_ON&lt;/code&gt;, is answered by reading one number, without ever expanding a relationship or building a row to discard. It is a small query doing something the relational model has to work for, and a clean example of a graph-native advantage.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A fun detail about this dataset: the leaves are mostly the famous top-of-tree packages, like &lt;code&gt;express&lt;/code&gt;, &lt;code&gt;chalk&lt;/code&gt;, and &lt;code&gt;lodash&lt;/code&gt;. They start dependency trees rather than sit inside them. The snapshot contains what they depend on, not the millions of apps that depend on them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  8. EXISTS subqueries become pattern predicates
&lt;/h3&gt;

&lt;p&gt;Packages that depend on both &lt;code&gt;react&lt;/code&gt; and &lt;code&gt;vue&lt;/code&gt;. Rarer than you might think:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;packages&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;
  &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;depends_on_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'react'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dep_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'runtime'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;
  &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;depends_on_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'vue'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dep_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'runtime'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same query in Cypher:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;p:&lt;/span&gt;&lt;span class="n"&gt;Package&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="ow"&gt;EXISTS&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:DEPENDS_ON&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;:Package&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;name:&lt;/span&gt; &lt;span class="s1"&gt;'react'&lt;/span&gt;&lt;span class="ss"&gt;})&lt;/span&gt; &lt;span class="ss"&gt;}&lt;/span&gt;
  &lt;span class="ow"&gt;AND&lt;/span&gt; &lt;span class="ow"&gt;EXISTS&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:DEPENDS_ON&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;:Package&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;name:&lt;/span&gt; &lt;span class="s1"&gt;'vue'&lt;/span&gt;&lt;span class="ss"&gt;})&lt;/span&gt; &lt;span class="ss"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;p.name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same keyword as SQL, and you have already met it: query 7 used &lt;code&gt;NOT EXISTS { }&lt;/code&gt; to find packages that nothing depends on. Here it does the positive job, with far less machinery. A correlated SQL subquery is a full nested query. It has its own &lt;code&gt;FROM&lt;/code&gt;, its own filters, and its own correlation condition you wire up by hand. Cypher's &lt;code&gt;EXISTS { }&lt;/code&gt; takes a pattern. The correlation is free, because the pattern reuses the variable &lt;code&gt;p&lt;/code&gt; that is already bound. Ten lines become four, and the four read like a sentence.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By the way, if you're following along and running these queries yourself, the result is zero in this snapshot.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  9. The self-join
&lt;/h3&gt;

&lt;p&gt;Packages that share a maintainer with &lt;code&gt;lodash&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;pm2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;package_maintainers&lt;/span&gt; &lt;span class="n"&gt;pm1&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;package_maintainers&lt;/span&gt; &lt;span class="n"&gt;pm2&lt;/span&gt;
  &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;pm1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pm2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;pm1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'lodash'&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;pm2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'lodash'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Cypher:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;:Package&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;name:&lt;/span&gt; &lt;span class="s1"&gt;'lodash'&lt;/span&gt;&lt;span class="ss"&gt;})&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:MAINTAINS&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;:Maintainer&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:MAINTAINS&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;p:&lt;/span&gt;&lt;span class="n"&gt;Package&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;p.name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SQL joins the association table against itself. That takes two aliases, a join on the shared key, and an inequality to skip the starting row. The Cypher walks &lt;em&gt;through&lt;/em&gt; the shared maintainer instead. It goes into lodash from its maintainer, then back out to everything else that maintainer touches. There are no aliases and no inequality, since a path cannot reuse the relationship it arrived on. The query reads like the question itself: who else does lodash's maintainer maintain?&lt;/p&gt;

&lt;p&gt;This pattern (entity, through a shared link, to entity) is the skeleton of collaborative filtering, fraud-ring detection, and "people also bought." In SQL it is always a self-join on the association table. In a graph it is always this V-shaped walk. Learn it once here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Query 10: where the languages stop being comparable
&lt;/h2&gt;

&lt;p&gt;Back to the opening question, now with the numbers filled in. Express declares 28 direct dependencies. Its full runtime tree, the true answer to "what am I actually installing," is &lt;strong&gt;63 packages, reaching 11 levels deep&lt;/strong&gt;. The recursive CTE at the top of this article computes that correctly. I want to be precise about what is and is not hard about it.&lt;/p&gt;

&lt;p&gt;The naive CTE finishes just fine on this dataset. Dependency graphs are nearly free of cycles, and the &lt;code&gt;UNION&lt;/code&gt; step keeps the working set small by removing duplicates. This is a friendlier graph than, say, a social network. There, loops and highly connected nodes can make path-listing CTEs blow up.&lt;/p&gt;

&lt;p&gt;What are the honest differences? First, the CTE is a program and the pattern is an expression. Twelve lines describe &lt;em&gt;how&lt;/em&gt; to traverse: the anchor, the recursion, the dedup, the depth tracking. One line states &lt;em&gt;what&lt;/em&gt; you want.&lt;/p&gt;

&lt;p&gt;Second, and this is the one that matters in practice: now reverse the question. Not "what does express depend on," but the left-pad question. &lt;em&gt;What breaks if this package disappears?&lt;/em&gt; In SQL, that is a second CTE, a mirror image of the first. The recursion now runs along &lt;code&gt;package_name&lt;/code&gt; instead of &lt;code&gt;depends_on_name&lt;/code&gt;. The anchor flips. You maintain both queries forever:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="k"&gt;RECURSIVE&lt;/span&gt; &lt;span class="n"&gt;blast_radius&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;package_name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;dependencies&lt;/span&gt;
  &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;depends_on_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'debug'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;dep_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'runtime'&lt;/span&gt;
  &lt;span class="k"&gt;UNION&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;package_name&lt;/span&gt;
  &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;blast_radius&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
  &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;depends_on_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
                     &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dep_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'runtime'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;affected&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;blast_radius&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Cypher, reversing the question means reversing the arrow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;affected:&lt;/span&gt;&lt;span class="n"&gt;Package&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:DEPENDS_ON&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;:Package&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;name:&lt;/span&gt; &lt;span class="s1"&gt;'debug'&lt;/span&gt;&lt;span class="ss"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;affected&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;affected&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same query. Flipped arrow.&lt;/p&gt;

&lt;p&gt;This is not Cypher being shorter for its own sake. The query language has a native concept, &lt;em&gt;the path&lt;/em&gt;, that SQL lacks. Once paths are built in, "everything downstream," "everything upstream," "shortest chain between," and "is there any connection at all" become expressions instead of programs. &lt;/p&gt;

&lt;p&gt;That is the difference between a notation gap and a capability gap. It is also the clearest signal for &lt;strong&gt;when&lt;/strong&gt; a graph database is the right tool. If your hard queries are about how things connect, at unknown depth, then you are implementing algorithms in your query language that Cypher gives you as syntax.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cheat sheet
&lt;/h2&gt;

&lt;p&gt;The full mapping, for reference:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;You know this in SQL&lt;/th&gt;
&lt;th&gt;You write this in Cypher&lt;/th&gt;
&lt;th&gt;Translation difficulty&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FROM table alias&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MATCH (alias:Label)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;WHERE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;WHERE&lt;/code&gt; (or inline &lt;code&gt;{prop: value}&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SELECT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;RETURN&lt;/code&gt; (at the end)&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;ORDER BY&lt;/code&gt; / &lt;code&gt;LIMIT&lt;/code&gt; / &lt;code&gt;DISTINCT&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Same keywords&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;JOIN ... ON&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A relationship in the pattern: &lt;code&gt;-[:REL]-&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Shape change&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A type/discriminator column&lt;/td&gt;
&lt;td&gt;A relationship &lt;em&gt;type&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;Modeling shift&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GROUP BY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Implicit: plain terms next to aggregates&lt;/td&gt;
&lt;td&gt;Shape change&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;HAVING&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;WITH ... WHERE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Shape change&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LEFT JOIN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;OPTIONAL MATCH&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;EXISTS (subquery)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;EXISTS { pattern }&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Shape change&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-join on an association table&lt;/td&gt;
&lt;td&gt;The V-walk: &lt;code&gt;(a)&amp;lt;-[:R]-(x)-[:R]-&amp;gt;(b)&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Modeling shift&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recursive CTE&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;-[:REL*]-&amp;gt;&lt;/code&gt;, direction by arrow&lt;/td&gt;
&lt;td&gt;Different capability&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Look at the rightmost column. Most rows are automatic or close to it. You can read those today. A few rows each require one new idea: implicit grouping, the &lt;code&gt;WITH&lt;/code&gt; pipeline, or joins as stored relationships. Only the last row is truly new territory, and it is the row you came for.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to stay in SQL
&lt;/h2&gt;

&lt;p&gt;This comparison is only honest if it cuts both ways. Nothing here argues for replacing your relational database wholesale. In fact, several of these queries are evidence &lt;em&gt;against&lt;/em&gt; moving certain workloads:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flat filtering and aggregation&lt;/strong&gt; (queries 1, 2, and 5): SQL is at parity. Your team already knows it, and the tooling around it (BI layers, ORMs, decades of operational habit) is mature. A &lt;code&gt;GROUP BY&lt;/code&gt; over one table is not a graph problem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bulk reporting&lt;/strong&gt; over wide tables with few relationship hops is exactly what relational engines are tuned for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The modeling cost is real.&lt;/strong&gt; The graph's elegance was paid for at load time. Someone decided that &lt;code&gt;dep_type&lt;/code&gt; should be a relationship type, that maintainership should be an edge, and that versions should collapse. Change a decision, rebuild the graph. If your access patterns are stable, tabular, and shallow, that cost never pays off.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The signal to reach for a graph is specific. Your queries routinely chain three or more joins. The depth is variable or unknown ("all upstream dependencies," "how are these two things connected"). Or you find yourself writing recursive CTEs against self-referencing tables. That last one is the tell. If query 10 looks like something in your codebase, this article was written for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try all ten yourself
&lt;/h2&gt;

&lt;p&gt;Everything above is reproducible. The &lt;a href="https://github.com/JeremyMorgan/sql-to-cypher" rel="noopener noreferrer"&gt;companion repository&lt;/a&gt; has both databases prebuilt: &lt;code&gt;npm.db&lt;/code&gt; for SQLite, and one paste-and-run script that loads the graph into a free &lt;a href="https://neo4j.com/product/auradb/" rel="noopener noreferrer"&gt;Aura&lt;/a&gt; instance. The CSVs and the pipeline that built them are there too, if you want to regenerate the snapshot yourself. No setup appears in this article because none is needed to follow it. The repo README is the whole install.&lt;/p&gt;

&lt;p&gt;But the fastest route to &lt;em&gt;writing&lt;/em&gt; Cypher rather than reading it is a course with a graph already loaded and live checking. &lt;strong&gt;Cypher Fundamentals&lt;/strong&gt; is free, runs in the browser, and takes about an hour. It covers exactly the constructs in queries 1 through 8, and turns "I can read this" into "I wrote this" in one sitting:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://graphacademy.neo4j.com/courses/cypher-fundamentals" rel="noopener noreferrer"&gt;Cypher Fundamentals - Learn Cypher in 1 hour&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From there, &lt;strong&gt;Intermediate Cypher Queries&lt;/strong&gt; picks up the variable-length paths and the &lt;code&gt;WITH&lt;/code&gt; pipeline behind queries 6 and 10:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://graphacademy.neo4j.com/courses/cypher-intermediate-queries" rel="noopener noreferrer"&gt;Intermediate Cypher Queries&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: These courses are 100% and are offered to Neo4j users to help you get the most out of the product.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One teaser before you go, because query 10 probably raised the question. The dataset in this article is generic npm. Your &lt;code&gt;package-lock.json&lt;/code&gt; is the same graph shape, with your project as the root node. Converting it to this schema is a small script away. Running a blast-radius query against your own application's real dependency tree is a great next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is Cypher hard to learn if I already know SQL?&lt;/strong&gt;&lt;br&gt;
No, and this article is the argument. Most of the ten translations are simple keyword swaps. The ideas that take real learning are implicit grouping (query 5), the &lt;code&gt;WITH&lt;/code&gt; pipeline (query 6), and thinking of joins as stored relationships (query 3). This tends to click quickly for SQL developers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I have to give up SQL to use Neo4j?&lt;/strong&gt;&lt;br&gt;
No. The common production pattern is to use both. The relational database keeps the transactional, tabular workloads. The graph handles the relationship-heavy queries. The dataset in this article exists in both databases at once, built from the same CSVs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Cypher actually faster, or just shorter?&lt;/strong&gt;&lt;br&gt;
Shorter is what this article shows. Faster depends on the workload, and it deserves measurement. The structural argument goes like this: graph traversal follows stored pointers (called index-free adjacency) instead of recomputing joins at every hop. So cost scales with the part of the graph you touch, not the size of the tables you join. That difference grows with depth. For single-hop lookups, a well-indexed relational database is extremely hard to beat. And the naive recursive CTE handled this nearly cycle-free dataset without drama.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why did &lt;code&gt;dep_type&lt;/code&gt; become a relationship type instead of a property?&lt;/strong&gt;&lt;br&gt;
Because runtime and dev dependencies are different &lt;em&gt;kinds&lt;/em&gt; of connection, and queries almost always want one kind or the other. Making the difference structural means the common case needs no filter, and the forgotten-filter bug cannot happen. The semver range stayed a property because it is a fact about an edge you already selected, not a way of selecting edges. That is the general rule. Things you filter on want to be types. Things you read afterward want to be properties.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does Cypher work outside Neo4j?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Increasingly, yes. Cypher was the main input to GQL, the ISO-standard graph query language published in 2024. Open implementations of Cypher exist for several other engines. The skills transfer.&lt;/p&gt;

</description>
      <category>data</category>
      <category>database</category>
      <category>neo4j</category>
      <category>sql</category>
    </item>
    <item>
      <title>Six Degrees of Ayrton Senna: Learn Neo4j by Connecting 75 Years of Formula 1</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Thu, 23 Jul 2026 17:25:40 +0000</pubDate>
      <link>https://dev.to/jeremycmorgan/six-degrees-of-ayrton-senna-learn-neo4j-by-connecting-75-years-of-formula-1-1kol</link>
      <guid>https://dev.to/jeremycmorgan/six-degrees-of-ayrton-senna-learn-neo4j-by-connecting-75-years-of-formula-1-1kol</guid>
      <description>&lt;p&gt;One of my favorite things about F1 racing is the data behind it. F1 cars are the most complex and advanced in any racing series. They collect huge amounts of telemetry data. The tracks also gather data during events, and race engineers analyze it week after week. They study everything from weather, tire temperatures to corner exit speeds. Data drives the sport forward in a major way.&lt;/p&gt;

&lt;p&gt;While learning about graph databases and Neo4j I realized it was the perfect tool for answering a question I was curious about.  We've all seen or heard of "Six Degrees of Kevin Bacon" where nearly any actor can be traced back to the Footloose star. I wondered: could this work for F1 drivers? By comparison it's a much smaller dataset than famous actors. &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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fusvfp5h5mwl8kc3urzox.webp" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fusvfp5h5mwl8kc3urzox.webp" alt="Max Verstappen and Juan Manuel Fangio" width="800" height="596"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photos via Wikimedia Commons, licensed under CC BY‑SA 4.0.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Max Verstappen connected to Juan Manuel Fangio? Could a driver who retired in 1958, decades before Max was born, connect to him through a chain of teammates? And if so, how many links does it take?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This post is how I answered that, and it doubles as a gentle introduction to Neo4j and graph databases. By the end you'll have built a real graph of every F1 driver since 1950 on your own machine, and you'll run a query that answers my Verstappen-to-Fangio question in a single line. No prior graph experience needed. &lt;/p&gt;

&lt;p&gt;Let's get into it.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why this is a graph problem
&lt;/h2&gt;

&lt;p&gt;Before we start: My question isn't really about drivers. It's about the &lt;em&gt;connections between&lt;/em&gt; drivers.&lt;/p&gt;

&lt;p&gt;If all I wanted was a list of drivers, or each driver's win count, or how many races happened at Monza, a plain old relational table handles that beautifully. Even a spreadsheet can do it. Spreadsheets are wonderful at facts &lt;em&gt;about things&lt;/em&gt;. Where they start to sweat is questions about &lt;em&gt;relationships&lt;/em&gt; and  &lt;em&gt;chains of relationships&lt;/em&gt;. Specifically long relationship chains.&lt;/p&gt;

&lt;p&gt;Think about what "is Verstappen connected to Fangio?" actually requires. You don't know in advance whether the answer is three hops or nine. So in SQL you'd be writing a recursive common table expression that joins a results table to itself, over and over, to a depth you can't predict, while trying not to drown in duplicate paths. &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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyms4tpb48wcg5g6ge3mn.webp" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyms4tpb48wcg5g6ge3mn.webp" alt="SQLite out of Memory" width="423" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I tried do this very thing and locked up the application trying. It's possible to do queries like this, but they rarely run fast, if they run at all. Relational databases weren't designed for things like this. &lt;/p&gt;

&lt;p&gt;A graph database flips the whole thing around. Instead of storing drivers in one table and hoping to reconstruct their connections later with joins, it stores the &lt;strong&gt;connections themselves&lt;/strong&gt; as useful entities. That's the one idea underneath everything else in this post:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In a graph database, the relationships are first class data. They're not something you compute at query time. They're something you store, traverse, and count directly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That single design choice is what turns this tough question into a one liner. Let me show you the model before we build it.&lt;/p&gt;


&lt;h2&gt;
  
  
  The property graph model, in four pieces
&lt;/h2&gt;

&lt;p&gt;Neo4j uses the &lt;strong&gt;Labeled Property Graph&lt;/strong&gt; model. It sounds fancy; it's just four building blocks. I'll introduce each one using our F1 data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nodes&lt;/strong&gt; are the things in your domain. The entities. For us, that's drivers and teams. In a diagram you draw them as circles. &lt;code&gt;Ayrton Senna&lt;/code&gt; is a node. &lt;code&gt;McLaren&lt;/code&gt; is a node.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Labels&lt;/strong&gt; are the &lt;em&gt;type&lt;/em&gt; of a node, written with a colon: &lt;code&gt;:Driver&lt;/code&gt;, &lt;code&gt;:Constructor&lt;/code&gt;. (Constructor is just F1's official word for "team".) Labels are how Neo4j knows a Senna node is a driver and a McLaren node is a team. By convention they're written in PascalCase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Relationships&lt;/strong&gt; are the connections between nodes, and this is where graphs shine. Every relationship has a type in SCREAMING_SNAKE_CASE, a direction, and a start and end node. &lt;code&gt;Senna DROVE_FOR McLaren&lt;/code&gt; is a relationship. Crucially, that connection is stored in the database. Neo4j keeps a pointer from one node to the next. This is why hopping across relationships stays fast even when your graph gets huge. The cost of following one relationship remains small, whether your database has a thousand nodes or a billion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Properties&lt;/strong&gt; are key-value pairs you can hang on &lt;em&gt;either&lt;/em&gt; a node or a relationship. A &lt;code&gt;:Driver&lt;/code&gt; node has &lt;code&gt;forename: 'Ayrton'&lt;/code&gt;, &lt;code&gt;surname: 'Senna'&lt;/code&gt;, &lt;code&gt;nationality: 'Brazilian'&lt;/code&gt;. Here's something that might be surprising if you come from a table world: a &lt;em&gt;relationship&lt;/em&gt; can carry properties too. Our &lt;code&gt;DROVE_FOR&lt;/code&gt; relationship will carry &lt;code&gt;season: 1988&lt;/code&gt;, because &lt;em&gt;which season&lt;/em&gt; someone drove for a team is a fact about the connection, not about the driver or the team on their own.&lt;/p&gt;

&lt;p&gt;That last point is worth thinking about, because it was an "aha" moment for relational-to-graph thinking. Senna drove for McLaren, but &lt;em&gt;when&lt;/em&gt; he did it doesn't belong to Senna and doesn't belong to McLaren. It belongs to the link between them. Put it on the relationship and a whole category of modeling headaches evaporates.&lt;/p&gt;

&lt;p&gt;Here's our entire starting model:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F604u64rnika7pncj9mdb.webp" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F604u64rnika7pncj9mdb.webp" alt="Data Model Ayrton Senna" width="800" height="317"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;:Driver&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;forename:&lt;/span&gt; &lt;span class="s1"&gt;'Ayrton'&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="py"&gt;surname:&lt;/span&gt; &lt;span class="s1"&gt;'Senna'&lt;/span&gt;&lt;span class="ss"&gt;})&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:DROVE_FOR&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;season&lt;/span&gt;&lt;span class="dl"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1988&lt;/span&gt;&lt;span class="ss"&gt;}]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;:Constructor&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;name:&lt;/span&gt; &lt;span class="s1"&gt;'McLaren'&lt;/span&gt;&lt;span class="ss"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two circles, one labeled arrow between them. If you want to make that concrete right now, open &lt;a href="https://arrows.neo4jlabs.com" rel="noopener noreferrer"&gt;Arrows&lt;/a&gt; (a free browser diagramming tool) and draw it. Click to make a node, give it a label and some properties, drag from its edge to a second node to create the relationship. It's helpful to sketch your schema there before writing any code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Design for the question you want to ask
&lt;/h2&gt;

&lt;p&gt;Before building anything, I did the single most useful thing you can do when modeling a graph: I wrote down the question I actually wanted to answer, &lt;em&gt;first&lt;/em&gt;, and let it drive every decision afterward.&lt;/p&gt;

&lt;p&gt;My question — "how are two drivers connected through shared teammates?" This tells me exactly what my graph needs. It needs drivers. It needs some notion of two drivers &lt;em&gt;being teammates&lt;/em&gt;. Everything else is optional scaffolding.&lt;/p&gt;

&lt;p&gt;But notice the dataset doesn't hand me "teammate" directly. It gives me who drove for which team in which season. Two drivers are teammates when they drove for the &lt;em&gt;same team&lt;/em&gt; in the &lt;em&gt;same season&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;So my plan has a nice shape to it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Load &lt;code&gt;Driver&lt;/code&gt; and &lt;code&gt;Constructor&lt;/code&gt; nodes.&lt;/li&gt;
&lt;li&gt;Connect them with &lt;code&gt;DROVE_FOR&lt;/code&gt; relationships (one per driver, per team, per season).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Derive&lt;/strong&gt; a brand-new &lt;code&gt;TEAMMATE_OF&lt;/code&gt; relationship between any two drivers who share a team and season.&lt;/li&gt;
&lt;li&gt;Walk the &lt;code&gt;TEAMMATE_OF&lt;/code&gt; web to answer my question.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In step three we are creating relationships that weren't in the raw data, by reasoning about the graph you already have. This is one of my favorite things about working in Neo4j, and you'll see why shortly. Let's build.&lt;/p&gt;




&lt;h2&gt;
  
  
  What you'll need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Neo4j Desktop&lt;/strong&gt; — free, from &lt;a href="https://neo4j.com/download/" rel="noopener noreferrer"&gt;neo4j.com/download&lt;/a&gt;. I'm on the current version (Desktop 2.x) on a Mac; Windows and Linux are the same journey.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The dataset&lt;/strong&gt; — the "Formula 1 World Championship (1950–2024)" dataset by Rohan Rao on &lt;a href="https://www.kaggle.com/datasets/rohanrao/formula-1-world-championship-1950-2020" rel="noopener noreferrer"&gt;Kaggle&lt;/a&gt;. Free Kaggle account, one download, clean CSVs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An afternoon.&lt;/strong&gt; Realistically a couple of hours, most of it spent going "oh that's cool" at the results.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No prior Cypher.&lt;/strong&gt; I'll explain every query as we go. Cypher is Neo4j's query language and it's genuinely readable. If you already know SQL you'll be nodding along within minutes.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A quick note on the data:&lt;/strong&gt; For about a decade, the go-to source for F1 data was the Ergast API. It shut down at the end of 2024. The Kaggle dataset we're using preserves Ergast's exact structure as downloadable CSVs, and if you later want live current-season data, the community-run &lt;strong&gt;Jolpica-F1 API&lt;/strong&gt; (&lt;code&gt;api.jolpi.ca/ergast/f1/&lt;/code&gt;) serves the same schema. Build against the CSVs today; top up from Jolpica whenever you like. Nothing in this tutorial changes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once Neo4j Desktop is installed: under local instances, click &lt;code&gt;create instance&lt;/code&gt; to create a new local instance.&lt;/p&gt;

&lt;p&gt;Give it a name and a password you'll remember, and start it. Then open the &lt;strong&gt;Query&lt;/strong&gt; tool (in Desktop 2.x this is where you run Cypher — it's the modern replacement for what older tutorials call "Neo4j Browser"). That's our workbench.&lt;/p&gt;

&lt;p&gt;We need four files from the Kaggle download: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;drivers.csv&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;constructors.csv&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;races.csv&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;results.csv&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can stage these files for import by placing them in our imports folder. Select your local instance, and look for the &lt;code&gt;...&lt;/code&gt; button. &lt;/p&gt;

&lt;p&gt;Select &lt;code&gt;Open&lt;/code&gt; then &lt;code&gt;Instance folder&lt;/code&gt;:&lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3ntkahzuqxr9ppbgj6hb.webp" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3ntkahzuqxr9ppbgj6hb.webp" alt="Neo4j Desktop Import" width="799" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the folder for your Neo4j instance. Next select the &lt;code&gt;import&lt;/code&gt; folder. This is where you want to place the files.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa42aunkgwgqlvjjyu1ml.webp" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa42aunkgwgqlvjjyu1ml.webp" alt="Neo4j Desktop Import" width="469" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;macOS&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/Users/[your username]/neo4j-community-2026.x/import
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Windows&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C:\Neo4j\import
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Linux&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/var/lib/neo4j/import
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that the files are in the import folder, we can access them with Cypher later.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Constraints first
&lt;/h2&gt;

&lt;p&gt;Before loading a single row, I created uniqueness constraints. A constraint guarantees you'll never accidentally create two copies of the same driver. Neo4j automatically builds an index behind each one, which makes all the lookups during import dramatically faster.&lt;/p&gt;

&lt;p&gt;In Neo4j Desktop you can run queries by selecting query from the left hand panel and entering your queries in the window in the upper right. &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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnozxp7ratlfwqa4x7s6h.webp" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnozxp7ratlfwqa4x7s6h.webp" alt="Neo4j Query Window" width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's the query to create the constraints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="n"&gt;driver_id&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="ow"&gt;NOT&lt;/span&gt; &lt;span class="ow"&gt;EXISTS&lt;/span&gt;
&lt;span class="n"&gt;FOR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;d:&lt;/span&gt;&lt;span class="n"&gt;Driver&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="n"&gt;REQUIRE&lt;/span&gt; &lt;span class="n"&gt;d.driverId&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt;&lt;span class="ss"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="n"&gt;constructor_id&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="ow"&gt;NOT&lt;/span&gt; &lt;span class="ow"&gt;EXISTS&lt;/span&gt;
&lt;span class="n"&gt;FOR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;c:&lt;/span&gt;&lt;span class="n"&gt;Constructor&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="n"&gt;REQUIRE&lt;/span&gt; &lt;span class="n"&gt;c.constructorId&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt;&lt;span class="ss"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="n"&gt;race_id&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="ow"&gt;NOT&lt;/span&gt; &lt;span class="ow"&gt;EXISTS&lt;/span&gt;
&lt;span class="n"&gt;FOR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;r:&lt;/span&gt;&lt;span class="n"&gt;Race&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="n"&gt;REQUIRE&lt;/span&gt; &lt;span class="n"&gt;r.raceId&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt;&lt;span class="ss"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;SHOW CONSTRAINTS&lt;/code&gt; to confirm all three landed. That's your data-integrity seatbelt fastened.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Load the nodes
&lt;/h2&gt;

&lt;p&gt;Now we bring in the entities. &lt;code&gt;LOAD CSV&lt;/code&gt; reads a file row by row; &lt;code&gt;MERGE&lt;/code&gt; is Cypher's "create this if it doesn't already exist, otherwise match the existing one" command. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Drivers:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;LOAD&lt;/span&gt; &lt;span class="k"&gt;CSV&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="k"&gt;HEADERS&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="s1"&gt;'https://raw.githubusercontent.com/JeremyMorgan/Six-Degrees-Senna/main/import/drivers.csv'&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;
&lt;span class="k"&gt;MERGE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;d:&lt;/span&gt;&lt;span class="n"&gt;Driver&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;driverId:&lt;/span&gt; &lt;span class="nf"&gt;toInteger&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row.driverId&lt;/span&gt;&lt;span class="ss"&gt;)})&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;d.forename&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row.forename&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;d.surname&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row.surname&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;d.fullName&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row.forename&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;row.surname&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;d.nationality&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row.nationality&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;d.dob&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;row.dob&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'\\N'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="nf"&gt;date&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row.dob&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="ss"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That &lt;code&gt;CASE WHEN row.dob &amp;lt;&amp;gt; '\\N'&lt;/code&gt; is guarding against a quirk you'll hit constantly with this dataset: missing values are stored as the literal text &lt;code&gt;\N&lt;/code&gt;. If you don't filter them out, you'll end up with drivers whose birthday is the string "backslash-N", which is exactly as useful as it sounds. Consider that your first real-world data-cleaning lesson, delivered by Formula 1.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Constructors:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;LOAD&lt;/span&gt; &lt;span class="k"&gt;CSV&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="k"&gt;HEADERS&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="s1"&gt;'https://raw.githubusercontent.com/JeremyMorgan/Six-Degrees-Senna/main/import/constructors.csv'&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;
&lt;span class="k"&gt;MERGE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;c:&lt;/span&gt;&lt;span class="n"&gt;Constructor&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;constructorId:&lt;/span&gt; &lt;span class="nf"&gt;toInteger&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row.constructorId&lt;/span&gt;&lt;span class="ss"&gt;)})&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;c.name&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row.name&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;c.nationality&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row.nationality&lt;/span&gt;&lt;span class="ss"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Races&lt;/strong&gt; (we mostly need these to know which season a result belongs to, but full Race nodes cost nothing and set you up for future projects):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;LOAD&lt;/span&gt; &lt;span class="k"&gt;CSV&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="k"&gt;HEADERS&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="s1"&gt;'https://raw.githubusercontent.com/JeremyMorgan/Six-Degrees-Senna/main/import/races.csv'&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;
&lt;span class="k"&gt;MERGE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;r:&lt;/span&gt;&lt;span class="n"&gt;Race&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;raceId:&lt;/span&gt; &lt;span class="nf"&gt;toInteger&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row.raceId&lt;/span&gt;&lt;span class="ss"&gt;)})&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;r.year&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;toInteger&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row.year&lt;/span&gt;&lt;span class="ss"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;r.round&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;toInteger&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row.round&lt;/span&gt;&lt;span class="ss"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;r.name&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row.name&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;r.date&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;date&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row.date&lt;/span&gt;&lt;span class="ss"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quick check: you should see something in the ballpark of 861 drivers, 212 constructors, and 1,100-plus races:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="nf"&gt;labels&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="ss"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="ss"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5v5jkw2hr57ap8iri3dq.webp" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5v5jkw2hr57ap8iri3dq.webp" alt="Cypher Query Results" width="637" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If those numbers look right, you've just loaded three-quarters of a century of motorsport into a graph. We haven't done anything clever yet, but we're about to.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Connect drivers to teams
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;results.csv&lt;/code&gt; file has one row per driver, per race — around 26,000 rows. I don't want 26,000 relationships cluttering my graph. I want one clean fact per driver, per team, per season: &lt;em&gt;this person drove for this team that year&lt;/em&gt;. So I aggregate as I load.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="nc"&gt;:auto&lt;/span&gt;
&lt;span class="k"&gt;LOAD&lt;/span&gt; &lt;span class="k"&gt;CSV&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="k"&gt;HEADERS&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="s1"&gt;'https://raw.githubusercontent.com/JeremyMorgan/Six-Degrees-Senna/main/import/results.csv'&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;
&lt;span class="k"&gt;CALL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;d:&lt;/span&gt;&lt;span class="n"&gt;Driver&lt;/span&gt;  &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;driverId:&lt;/span&gt;  &lt;span class="nf"&gt;toInteger&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row.driverId&lt;/span&gt;&lt;span class="ss"&gt;)})&lt;/span&gt;
  &lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;c:&lt;/span&gt;&lt;span class="n"&gt;Constructor&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;constructorId:&lt;/span&gt; &lt;span class="nf"&gt;toInteger&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row.constructorId&lt;/span&gt;&lt;span class="ss"&gt;)})&lt;/span&gt;
  &lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;r:&lt;/span&gt;&lt;span class="n"&gt;Race&lt;/span&gt;    &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;raceId:&lt;/span&gt;    &lt;span class="nf"&gt;toInteger&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row.raceId&lt;/span&gt;&lt;span class="ss"&gt;)})&lt;/span&gt;
  &lt;span class="k"&gt;MERGE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="py"&gt;s:&lt;/span&gt;&lt;span class="n"&gt;DROVE_FOR&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;season:&lt;/span&gt; &lt;span class="n"&gt;r.year&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="py"&gt;constructorId:&lt;/span&gt; &lt;span class="n"&gt;c.constructorId&lt;/span&gt;&lt;span class="ss"&gt;}]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;s.entries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;s.wins&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;row.positionOrder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;
  &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;MATCH&lt;/span&gt;  &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;s.entries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s.entries&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;s.wins&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s.wins&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;row.positionOrder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;
&lt;span class="ss"&gt;}&lt;/span&gt; &lt;span class="ow"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;TRANSACTIONS&lt;/span&gt; &lt;span class="n"&gt;OF&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt; &lt;span class="n"&gt;ROWS&lt;/span&gt;&lt;span class="ss"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's a lot of learning packed into that one statement, so let's unpack it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;MERGE (d)-[:DROVE_FOR {season, constructorId}]-&amp;gt;(c)&lt;/code&gt;&lt;/strong&gt; is the key move. The &lt;em&gt;first&lt;/em&gt; time we see Senna-at-McLaren-in-1988, this creates the relationship. Every &lt;em&gt;subsequent&lt;/em&gt; race that season just finds the existing one and bumps its counters. Twenty-six thousand rows collapse into roughly 3,600 clean driver-season-team facts. This is the graph-modeling principle in action: &lt;strong&gt;store relationships at the granularity you plan to query.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;ON CREATE&lt;/code&gt; / &lt;code&gt;ON MATCH&lt;/code&gt;&lt;/strong&gt; let you do one thing when the relationship is brand new and a different thing when it already exists — here, initialize the counters versus increment them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;:auto&lt;/code&gt; and &lt;code&gt;IN TRANSACTIONS OF 2000 ROWS&lt;/code&gt;&lt;/strong&gt; tell Neo4j to commit the import in batches rather than one giant transaction, which keeps memory happy on a big file.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Version note:&lt;/strong&gt; &lt;code&gt;CALL (row) { … }&lt;/code&gt; is the modern syntax (Neo4j 5.23 and up) for passing a variable into a subquery. If your Neo4j is older, you'll get a syntax error on that line — use the legacy form &lt;code&gt;CALL { WITH row … }&lt;/code&gt; instead. And don't copy an abbreviated snippet with &lt;code&gt;...&lt;/code&gt; in the middle into the Query editor; Cypher will try to parse the dots. Use the full block above.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's make sure it worked by looking at a career I know:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;d:&lt;/span&gt;&lt;span class="n"&gt;Driver&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;surname:&lt;/span&gt;&lt;span class="s1"&gt;'Senna'&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="py"&gt;forename:&lt;/span&gt;&lt;span class="s1"&gt;'Ayrton'&lt;/span&gt;&lt;span class="ss"&gt;})&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="py"&gt;s:&lt;/span&gt;&lt;span class="n"&gt;DROVE_FOR&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;c:&lt;/span&gt;&lt;span class="n"&gt;Constructor&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;c.name&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;team&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s.season&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;season&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s.wins&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;wins&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;season&lt;/span&gt;&lt;span class="ss"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuz4cairqrc2i6qsikhbo.webp" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuz4cairqrc2i6qsikhbo.webp" alt="Ayrton Senna Record" width="711" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Toleman in '84, Lotus '85 to '87, McLaren '88 to '93, Williams in '94. If that's what you see, your graph is alive and correct.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Derive the teammate network.
&lt;/h2&gt;

&lt;p&gt;Everything so far was setup. This is the payoff of graph thinking.&lt;/p&gt;

&lt;p&gt;Nowhere in the data does it say "Senna and Prost were teammates." But we can &lt;em&gt;derive&lt;/em&gt; that: two drivers are teammates if they each have a &lt;code&gt;DROVE_FOR&lt;/code&gt; relationship to the &lt;strong&gt;same constructor&lt;/strong&gt; with the &lt;strong&gt;same season&lt;/strong&gt;. And in Cypher, describing that pattern is close to describing it in English:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;d1:&lt;/span&gt;&lt;span class="n"&gt;Driver&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="py"&gt;r1:&lt;/span&gt;&lt;span class="n"&gt;DROVE_FOR&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;c:&lt;/span&gt;&lt;span class="n"&gt;Constructor&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="py"&gt;r2:&lt;/span&gt;&lt;span class="n"&gt;DROVE_FOR&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;d2:&lt;/span&gt;&lt;span class="n"&gt;Driver&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;r1.season&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r2.season&lt;/span&gt;
  &lt;span class="ow"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;d1.driverId&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;d2.driverId&lt;/span&gt;
&lt;span class="k"&gt;MERGE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d1&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="py"&gt;t:&lt;/span&gt;&lt;span class="n"&gt;TEAMMATE_OF&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;season:&lt;/span&gt; &lt;span class="n"&gt;r1.season&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="py"&gt;team:&lt;/span&gt; &lt;span class="n"&gt;c.name&lt;/span&gt;&lt;span class="ss"&gt;}]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d2&lt;/span&gt;&lt;span class="ss"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read that &lt;code&gt;MATCH&lt;/code&gt; line like a picture: driver one points to a constructor, and driver two points to the &lt;em&gt;same&lt;/em&gt; constructor from the other side. The &lt;code&gt;WHERE&lt;/code&gt; says "same season." And then we &lt;code&gt;MERGE&lt;/code&gt; a shiny new &lt;code&gt;TEAMMATE_OF&lt;/code&gt; relationship between them. &lt;/p&gt;

&lt;p&gt;We just created around 10,000 relationships that didn't exist in the source data, purely by reasoning about the shape of the graph.&lt;/p&gt;

&lt;p&gt;Two small things worth understanding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;d1.driverId &amp;lt; d2.driverId&lt;/code&gt;&lt;/strong&gt; stops us creating each pairing twice (Senna→Prost &lt;em&gt;and&lt;/em&gt; Prost→Senna). By only linking the lower ID to the higher one, each pair gets a single relationship. When we query it, we'll just ignore direction — because "teammate" goes both ways, and Cypher happily traverses a relationship in either direction when you leave the arrowhead off.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A deliberately imperfect definition, and why I'm keeping it.&lt;/strong&gt; "Same team, same season" isn't &lt;em&gt;exactly&lt;/em&gt; "raced side by side." Midseason driver swaps mean, for example, that Senna and David Coulthard both count as 1994 Williams drivers. Coulthard was Senna's replacement, and they never actually raced as teammates. I could tighten this up by deriving teammate links per-race instead of per-season. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm keeping the looser version on purpose, for two reasons. First, it makes the network richer and more connected across eras, which is the whole point. Second, &lt;strong&gt;every graph model is an argument about what a relationship&lt;/strong&gt; &lt;strong&gt;&lt;em&gt;means&lt;/em&gt;&lt;/strong&gt;. There's no universally correct answer; there's only the definition that serves your question. Naming that trade-off out loud is important.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Answer the question
&lt;/h2&gt;

&lt;p&gt;Here it is. The reason I built the whole thing. Two drivers separated by half a century, and one line of Cypher to connect them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;max:&lt;/span&gt;&lt;span class="n"&gt;Driver&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;surname:&lt;/span&gt;&lt;span class="s1"&gt;'Verstappen'&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="py"&gt;forename:&lt;/span&gt;&lt;span class="s1"&gt;'Max'&lt;/span&gt;&lt;span class="ss"&gt;}),&lt;/span&gt;
  &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;fangio:&lt;/span&gt;&lt;span class="n"&gt;Driver&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;surname:&lt;/span&gt;&lt;span class="s1"&gt;'Fangio'&lt;/span&gt;&lt;span class="ss"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;MATCH&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;shortestPath&lt;/span&gt;&lt;span class="ss"&gt;((&lt;/span&gt;&lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:TEAMMATE_OF&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fangio&lt;/span&gt;&lt;span class="ss"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="ss"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That &lt;code&gt;*&lt;/code&gt; after &lt;code&gt;TEAMMATE_OF&lt;/code&gt; is the star of the show. It means "follow this relationship any number of times" — a &lt;strong&gt;variable-length path&lt;/strong&gt;. &lt;code&gt;shortestPath&lt;/code&gt; then finds the tightest chain of teammate links between the two drivers. This is the exact query that would've been a page of recursive SQL. In Cypher it fits on a napkin.&lt;/p&gt;

&lt;p&gt;When you run it, the Query tool draws the answer as a chain of driver nodes, each link labeled with the team and season that connects them. This is how close Max really is to Fangio.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2n6kpw2s5bv39fg1triu.webp" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2n6kpw2s5bv39fg1triu.webp" alt="Neo4j Desktop Result Verstappen to Fangio" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once that lands, you'll want to push further. Here are the three queries I couldn't stop running.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Every driver's "Senna number"&lt;/strong&gt; — like the Bacon number, but for F1. How many teammate-hops is each driver from Ayrton Senna?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;senna:&lt;/span&gt;&lt;span class="n"&gt;Driver&lt;/span&gt; &lt;span class="ss"&gt;{&lt;/span&gt;&lt;span class="py"&gt;surname:&lt;/span&gt;&lt;span class="s1"&gt;'Senna'&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="py"&gt;forename:&lt;/span&gt;&lt;span class="s1"&gt;'Ayrton'&lt;/span&gt;&lt;span class="ss"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;d:&lt;/span&gt;&lt;span class="n"&gt;Driver&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;senna&lt;/span&gt;
&lt;span class="k"&gt;MATCH&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;shortestPath&lt;/span&gt;&lt;span class="ss"&gt;((&lt;/span&gt;&lt;span class="n"&gt;senna&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:TEAMMATE_OF&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;..25&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="ss"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;sennaNumber&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;drivers&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;sennaNumber&lt;/span&gt;&lt;span class="ss"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The shape of those results is the real insight: almost the entire history of the sport sits within a handful of hops of Senna. That's a "small-world network," demonstrated with race cars.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The most connected drivers in history&lt;/strong&gt; — the human bridges holding the whole web together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;d:&lt;/span&gt;&lt;span class="n"&gt;Driver&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:TEAMMATE_OF&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;other:&lt;/span&gt;&lt;span class="n"&gt;Driver&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;d.fullName&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;teammates&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;teammates&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="ss"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Watch who tops this list: long career journeymen and team-hoppers, not necessarily the champions. Connectedness rewards longevity and movement, not podiums. I find that interesting. The people stitching F1's social fabric together are often not the ones holding the trophies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it really all one network?&lt;/strong&gt; Are there isolated islands of drivers?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="k"&gt;MATCH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="py"&gt;d:&lt;/span&gt;&lt;span class="n"&gt;Driver&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;NOT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;:TEAMMATE_OF&lt;/span&gt;&lt;span class="ss"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;unconnectedDrivers&lt;/span&gt;&lt;span class="ss"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A small handful of true loners from F1's chaotic early days, and then one enormous connected web containing basically everyone else. Seventy-five years, one family.&lt;/p&gt;




&lt;h2&gt;
  
  
  What you just learned (it wasn't really about F1)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The property graph model&lt;/strong&gt; — nodes, labels, relationships, and properties, including the quietly powerful idea that a &lt;em&gt;relationship&lt;/em&gt; can carry properties of its own.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Designing for questions, not entities&lt;/strong&gt; — writing the question first and letting it shape the model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;LOAD CSV&lt;/code&gt;, &lt;code&gt;MERGE&lt;/code&gt;, and constraints&lt;/strong&gt; — the everyday mechanics of getting real data into Neo4j cleanly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deriving new relationships&lt;/strong&gt; — creating structure that wasn't in your source data by reasoning about the graph you already have.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Variable-length paths and &lt;code&gt;shortestPath&lt;/code&gt;&lt;/strong&gt; — the thing graphs do effortlessly and relational databases do through gritted teeth.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And here's the part that matters beyond motorsport: swap the dataset and every one of these skills transfers directly. The teammate network is structurally identical to a fraud ring, a supply chain, a social graph, an org chart, or the knowledge graph behind an AI application. "Who is connected to whom, and how?" is one of the most valuable questions in software, and you now know how to ask it.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://github.com/JeremyMorgan/Six-Degrees-Senna" rel="noopener noreferrer"&gt;Download the code here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to go next
&lt;/h2&gt;

&lt;p&gt;If this clicked for you the best next move is to get the fundamentals properly, in order. That's exactly what &lt;strong&gt;&lt;a href="https://graphacademy.neo4j.com/" rel="noopener noreferrer"&gt;GraphAcademy&lt;/a&gt;&lt;/strong&gt; is for. It's Neo4j's free, hands-on learning platform.&lt;/p&gt;

&lt;p&gt;A path I'd suggest, roughly in this order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://graphacademy.neo4j.com/courses/neo4j-fundamentals" rel="noopener noreferrer"&gt;Neo4j Fundamentals&lt;/a&gt;&lt;/strong&gt; — the property graph model, cemented, with exercises.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://graphacademy.neo4j.com/courses/cypher-fundamentals" rel="noopener noreferrer"&gt;Cypher Fundamentals&lt;/a&gt;&lt;/strong&gt; — everything we hand-waved past today, done properly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://graphacademy.neo4j.com/courses/importing-fundamentals" rel="noopener noreferrer"&gt;Importing data with Cypher&lt;/a&gt;&lt;/strong&gt; — &lt;code&gt;LOAD CSV&lt;/code&gt; and friends, beyond our quick version.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For future articles I'm thinking: turn this same graph into a fair fight, deriving "who-beat-whom" links between teammates and running an algorithm called PageRank to settle the greatest-of-all-time argument without ever touching the points table.&lt;/p&gt;

</description>
      <category>database</category>
      <category>neo4j</category>
      <category>cypher</category>
      <category>graph</category>
    </item>
    <item>
      <title>I attended POST/CON 2025. Here are my thoughts</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Mon, 16 Jun 2025 16:54:10 +0000</pubDate>
      <link>https://dev.to/jeremycmorgan/i-attended-postcon-2025-here-are-my-thoughts-2d70</link>
      <guid>https://dev.to/jeremycmorgan/i-attended-postcon-2025-here-are-my-thoughts-2d70</guid>
      <description>&lt;p&gt;I just returned from POST/CON 25, and I'm left with one big impression: Postman gets it. &lt;/p&gt;

&lt;p&gt;They get that we're not just managing APIs. We're building complex systems, and increasingly, those systems involve AI. And as AI technologies race ahead Postman is right there to help you keep up.&lt;/p&gt;

&lt;p&gt;I've been using Postman for years, and I was thrilled to be invited to POST/CON 2025 in Los Angeles. It was an amazing experience, and I want to share some of the highlights.&lt;/p&gt;

&lt;p&gt;If you want the full rundown of the conference, you can &lt;a href="https://fnf.dev/4mSSgP1" rel="noopener noreferrer"&gt;check out the official recap here&lt;/a&gt;. I want to share my personal highlights and thoughts on the event.&lt;/p&gt;

&lt;h2&gt;
  
  
  Day 1: Full day workshop - "Mastering AI agent Automation with Postman Flows"
&lt;/h2&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%2Fqop6uctlnx4le2hc5g0q.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%2Fqop6uctlnx4le2hc5g0q.png" alt="Postman POST/CON 2025 Highlights" width="799" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There I learned:&lt;/p&gt;

&lt;p&gt;🔥 How easy it is to connect things together with flow&lt;/p&gt;

&lt;p&gt;🔥 How to tie together AI agents into a seamless workflow and deploy it&lt;/p&gt;

&lt;p&gt;🔥 Learn best practices for design&lt;/p&gt;

&lt;p&gt;Then a fireside chat with Ryan Reynolds and Justine Davis that had almost nothing to do with code and everything to do with building great products that solve real problems, and taking care of people.&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%2F6ra9i24064zry0t7a0jp.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%2F6ra9i24064zry0t7a0jp.png" alt="Postman POST/CON 2025 Highlights" width="800" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Day 2: Keynote and Sessions
&lt;/h2&gt;

&lt;p&gt;Attended the Keynote where I learned about&lt;/p&gt;

&lt;p&gt;🛠️ Postman VS code extensions&lt;/p&gt;

&lt;p&gt;🛠️ GitHub Integration&lt;/p&gt;

&lt;p&gt;🛠️ Postman Insights (lots of great analytics)&lt;/p&gt;

&lt;p&gt;🛠️ AI Agent Builder&lt;/p&gt;

&lt;p&gt;🛠️ Model Comparison Template&lt;/p&gt;

&lt;p&gt;🛠️ MCP Server Generator (REALLY)&lt;/p&gt;

&lt;p&gt;and so much more. You can &lt;a href="https://fnf.dev/4mSSgP1" rel="noopener noreferrer"&gt;get all the details here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sessions
&lt;/h3&gt;

&lt;p&gt;I attended some amazing sessions, where I learned a ton about&lt;/p&gt;

&lt;p&gt;🧠 Agent Orchestration using API-driven workflows&lt;/p&gt;

&lt;p&gt;🧠 Building multi-agent experiences with Agent Builder&lt;/p&gt;

&lt;p&gt;🧠 Automating API Testing in CI/CD pipelines with CircleCI and Postman&lt;/p&gt;

&lt;p&gt;🧠 Composable API Ecosystems and the MCP Protocol&lt;/p&gt;

&lt;p&gt;and tons of great lightning talks.&lt;/p&gt;

&lt;h2&gt;
  
  
  One of the best conferences I've attended
&lt;/h2&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%2Fgkh9luv4swi8vpp0uqk5.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%2Fgkh9luv4swi8vpp0uqk5.png" alt="Postman POST/CON 2025 Highlights" width="800" height="551"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The energy at this conference was amazing. It's one of the best I've attended. Postman is at the forefront of tech. They've created great tools to keep YOU ahead of the game. They focus on building their product well and help you create your best products, too.&lt;/p&gt;

&lt;p&gt;I highly suggest going to the next POST/CON. If you do, let me know and let's meet up! &lt;/p&gt;

&lt;p&gt;Thank you so much to Postman for sending me to this conference. Now, if you'll excuse me, I have some new tools to try out!&lt;/p&gt;

&lt;p&gt;-- Jeremy&lt;/p&gt;

</description>
      <category>programming</category>
      <category>javascript</category>
      <category>api</category>
    </item>
    <item>
      <title>Running DeepSeek R1 Locally on a Raspberry Pi</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Sat, 15 Feb 2025 00:09:53 +0000</pubDate>
      <link>https://dev.to/jeremycmorgan/running-deepseek-r1-locally-on-a-raspberry-pi-1gh8</link>
      <guid>https://dev.to/jeremycmorgan/running-deepseek-r1-locally-on-a-raspberry-pi-1gh8</guid>
      <description>&lt;p&gt;DeepSeek R1 shook the Generative AI world, and everyone even remotely interested in AI rushed to try it out. It is a great model, IMO. As you may know, I love to run models locally, and since this is an open-source model, of course, I had to try it out. It works great on my Mac Studio and 4090 machines. &lt;/p&gt;

&lt;p&gt;But can it run on this? A silly little Raspberry Pi? &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%2F5re7fnzjehiajfjjzr0r.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%2F5re7fnzjehiajfjjzr0r.png" alt="" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I received a few emails and private messages asking about this and had to try it out. In this tutorial, we'll walk through how to run DeepSeek R1 models on a Raspberry Pi 5 and evaluate their performance. Whether you want to get into running LLMs locally or build some edge AI stuff, this could be a fun tutorial to try out. &lt;/p&gt;

&lt;p&gt;Here it is in video form if you prefer that:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/8ZEAmfv_-Z4"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;So let's get started. Here's what you need:&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Prerequisites&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Hardware&lt;/strong&gt;:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Raspberry Pi 5 (8GB or 16GB RAM recommended).&lt;/li&gt;
&lt;li&gt;MicroSD card with Raspberry Pi OS (64-bit) installed.&lt;/li&gt;
&lt;li&gt;Stable power supply and internet connection.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Software&lt;/strong&gt;:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Basic familiarity with Raspberry Pi OS and terminal commands.&lt;/li&gt;
&lt;li&gt;Docker (optional, for containerized applications).&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Here's the machine I tried it with:&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%2F8nqy5c0xi8zudktn1blp.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%2F8nqy5c0xi8zudktn1blp.png" alt="" width="799" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Step 1: Configure Your Raspberry Pi&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Enable Remote Desktop (Optional)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To simplify GUI interactions, enable Remote Desktop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;xrdp &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start xrdp
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;xrdp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set the Pi to auto-login to the desktop GUI. &lt;/p&gt;

&lt;p&gt;Type in &lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo raspi-config&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;And select 1 System Options&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%2Fc77vvdz1nnnds013vf2f.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%2Fc77vvdz1nnnds013vf2f.png" alt="" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then select S5 Boot/Auto Login&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%2Fffxacpsz0b373o30yr3w.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%2Fffxacpsz0b373o30yr3w.png" alt="" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and choose B3 Desktop (Desktop GUI, requiring user to login)&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%2F6iuxsqewqx0y1yd88tth.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%2F6iuxsqewqx0y1yd88tth.png" alt="" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, if you want, you can log into the desktop remotely using RDP and access a desktop. &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%2Fadzo59qvg2lvq2oiy691.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%2Fadzo59qvg2lvq2oiy691.png" alt="" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: on my Raspberry Pi I could not get any browsers to run properly. They would not display in a readable form, I'll be looking it and trying to fix that at some point. &lt;/p&gt;

&lt;p&gt;Your browser may also look like this:&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%2F4hr176ihnb4ky9rkea3h.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%2F4hr176ihnb4ky9rkea3h.png" alt="" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Step 2: Install Ollama&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Ollama is a tool for running LLMs locally. Since Raspberry Pi uses ARM64 architecture, download the Ollama Linux ARM64 build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://ollama.com/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F6q4emoj1rzjwhkr0lb05.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%2F6q4emoj1rzjwhkr0lb05.png" alt="" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that it will say&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WARNING: No NVIDIA/AMD GPU detected. Ollama will run in CPU-only mode.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is because the Raspberry Pi's GPU is not CUDA compatible. However, we can see how it runs on just the CPU. &lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Step 3: Run DeepSeek R1 Models&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Test the 1.5B Parameter Model&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Let's start with the smallest model available to try it out. That would be the &lt;a href="https://ollama.com/library/deepseek-r1:1.5b" rel="noopener noreferrer"&gt;deepseek-r1 1.5b model&lt;/a&gt; model, which has 1.5 billion parameters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama run deepseek-r1:1.5b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example Prompt&lt;/strong&gt;:&lt;br&gt;
&lt;br&gt;
 &amp;nbsp;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&amp;gt;&amp;gt;&amp;gt; Tell me a funny joke about Python.

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

&lt;/div&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%2Fwooqqb5raakxyfqcsu2i.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%2Fwooqqb5raakxyfqcsu2i.png" alt="" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance Notes&lt;/strong&gt;: &amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt;: ~6.12 tokens/second. &amp;nbsp;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RAM Usage&lt;/strong&gt;: ~3GB. &amp;nbsp;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CPU&lt;/strong&gt;: Consistently maxed at 99%. &amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So that's not too bad. It's not great, but it might be useful for prototyping and experimenting. You could use this for many tasks as long as it isn't real-time chat or something immediately interactive.&lt;/p&gt;

&lt;p&gt;Let's try a bigger model. We know it will be slower, but I want to see if it's possible.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Test the 7B Parameter Model (Optional)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For this test, we'll try the &lt;a href="https://ollama.com/library/deepseek-r1:7b" rel="noopener noreferrer"&gt;deepseek-r1 7B parameter&lt;/a&gt; model. This one is considerably bigger and is a pretty decent model for many projects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama run deepseek-r1:7b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Performance Notes&lt;/strong&gt;: &amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt;: ~1.43 tokens/second (extremely slow). &amp;nbsp;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RAM Usage&lt;/strong&gt;: ~6GB (requires 8GB+ Pi). &amp;nbsp;&lt;/li&gt;
&lt;/ul&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%2Faw4ltnjlpcrl51jz4b7a.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%2Faw4ltnjlpcrl51jz4b7a.png" alt="" width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This one is really slow and barely usable. But it's still impressive that you can run a 7B parameter model on a Raspberry Pi, in my opinion. There's not much use for it, but it's possible. &lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Step 4: Deploy a Dockerized Chat Application&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let's try running a dockerized chat application. This is an application I built for &lt;a href="https://www.youtube.com/watch?v=8ZEAmfv_-Z4" rel="noopener noreferrer"&gt;a previous YouTube video&lt;/a&gt;. It's a VueJS application that uses the DeepSeek R1 models. &lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/JeremyMorgan/DeepSeek-Chat-Demo" rel="noopener noreferrer"&gt;source code is available here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Here's how to run it on a Pi:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Clone the Demo App&lt;/strong&gt; (replace with your own project):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/JeremyMorgan/DeepSeek-Chat-Demo
&lt;span class="nb"&gt;cd &lt;/span&gt;deepseek-chat-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Build and Run with Docker&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Access the app at &lt;code&gt;http://localhost:5173&lt;/code&gt; and test prompts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hey! It runs! Awesome. The responsiveness isn't too bad, it's a little slow but usable. &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%2Frrszxq8b55y40ede05l2.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%2Frrszxq8b55y40ede05l2.png" alt="" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Step 5: Experiment with a Raspberry Pi Cluster (Extra Bonus Round!)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I decided to drop this on my Raspberry Cluster just to try it out. While this doesn't improve speed (LLMs run on single nodes), it's a fun experiment for distributed workloads.&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%2F31zgrfzc6kmg4yszfg4l.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%2F31zgrfzc6kmg4yszfg4l.png" alt="" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These Raspberry Pis are all 8GB models instead of the 16GB. Here's how you can set it up:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Set Up Kubernetes&lt;/strong&gt; using &lt;code&gt;micorok8s&lt;/code&gt; or similar tools.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Deploy the App&lt;/strong&gt; by creating via a YAML manifest (deepseek-deployment.yaml):&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deepseek-deployment&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deepseek&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deepseek&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deepseek&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; affinity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; podAntiAffinity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; requiredDuringSchedulingIgnoredDuringExecution&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - labelSelector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deepseek&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; topologyKey&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kubernetes.io/hostname"&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deepseek&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jeremymorgan/deepseek-1-5b-chat-demo:ARM64&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;11435&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; hostPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;11435&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a service (deepseek-service.yaml):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deepseek-service&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NodePort&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deepseek&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; - name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;80 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt; &lt;span class="c1"&gt;# service port (cluster-internal)&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;80 &amp;nbsp; &amp;nbsp;&lt;/span&gt; &lt;span class="c1"&gt;# container port&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; nodePort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;30080 &amp;nbsp; &amp;nbsp;# external port on every node&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; - name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;chat&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;11436 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;# service port (cluster-internal)&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;11436 &amp;nbsp;# container port&lt;/span&gt;
&lt;span class="na"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; nodePort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;31144 &amp;nbsp; &amp;nbsp;# external port on every node&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The responses remain slow, as clustering doesn't parallelize model inference. However, the performance difference between 8GB and 16GB is not noticeable with the 1.5B parameter model. &lt;/p&gt;

&lt;p&gt;You can grab the Docker image from here and check it out:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hub.docker.com/r/jeremymorgan/deepseek-1-5b-chat-demo/" rel="noopener noreferrer"&gt;https://hub.docker.com/r/jeremymorgan/deepseek-1-5b-chat-demo/&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Key Takeaways&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;So here's what you'll learn while deploying DeepSeek models to the Raspberry Pi 5.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Feasibility&lt;/strong&gt;: &amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;1.5B model&lt;/strong&gt; runs acceptably on an 8-16GB Raspberry Pi 5 for lightweight tasks. &amp;nbsp;&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;7B model&lt;/strong&gt; will run, but is impractical due to speed (1.43 tokens/sec). &amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Use Cases&lt;/strong&gt;: &amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Educational experiments.&lt;/li&gt;
&lt;li&gt;Prototyping edge AI applications. &amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Optimization Tips&lt;/strong&gt;: &amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use quantized models (e.g., 4-bit GGUF) for better performance. &amp;nbsp;&lt;/li&gt;
&lt;li&gt;Avoid GUI overhead by running Ollama headless. &amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;While DeepSeek R1 won't replace cloud-based LLMs on a Raspberry Pi, it's a fun way to explore AI on budget hardware. Consider upgrading to a Jetson Nano or used GPU server for better performance. &lt;/p&gt;

&lt;p&gt;It's a fun experiment!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Results&lt;/strong&gt;: &amp;nbsp;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Model Size&lt;/th&gt;
&lt;th&gt;Tokens/sec&lt;/th&gt;
&lt;th&gt;RAM Usage&lt;/th&gt;
&lt;th&gt;Usability&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.5B &amp;nbsp;&lt;/td&gt;
&lt;td&gt;~6.12&lt;/td&gt;
&lt;td&gt;3GB&lt;/td&gt;
&lt;td&gt;Basic Q&amp;amp;A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7B &lt;/td&gt;
&lt;td&gt;~1.43 &lt;/td&gt;
&lt;td&gt;6GB &lt;/td&gt;
&lt;td&gt;Not recommended&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Try it yourself and see how it goes, if you have any comments or questions &lt;a href="https://x.com/intent/follow?screen_name=JeremyCMorgan" rel="noopener noreferrer"&gt;Yell at me!!&lt;/a&gt;&lt;/p&gt;




</description>
    </item>
    <item>
      <title>Review: The New NVIDIA Jetson Orin Nano</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Tue, 24 Dec 2024 00:57:02 +0000</pubDate>
      <link>https://dev.to/jeremycmorgan/review-the-new-nvidia-jetson-orin-nano-4ci7</link>
      <guid>https://dev.to/jeremycmorgan/review-the-new-nvidia-jetson-orin-nano-4ci7</guid>
      <description>&lt;p&gt;Hello, friends! If you're a reader of my nerdy articles you've probably heard about NVIDIA's Jetson. It's a great platform for prototyping apps and putting AI at the edge. &lt;/p&gt;

&lt;p&gt;I got lucky and got my hands on the newest, very affordable Jetson, the Jetson Orin Nano. &lt;/p&gt;

&lt;p&gt;Today, we’ll dive into everything from unboxing this little gem to testing its performance with AI models. Ready to explore what makes this device so cool? Let’s get started!&lt;/p&gt;

&lt;p&gt;If you'd rather see a video version of this review here it is: &lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/JRhAMHxlo3E"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;




&lt;h3&gt;
  
  
  What's Inside the Box?
&lt;/h3&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%2Fe2nzgnk8vhbcy33w4lex.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%2Fe2nzgnk8vhbcy33w4lex.png" alt="NVIDIA Jetson Orin Nano" width="799" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First impressions matter, and the Orin Nano’s packaging is as clean and straightforward as you’d expect. Here’s what you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A robust power supply with both European and American plugs.&lt;/li&gt;
&lt;li&gt;A quick start manual (kinda)&lt;/li&gt;
&lt;li&gt;And, of course, the star of the show: the Jetson Orin Nano.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You do need to purchase an SD card for it, aas it's not shipped with one.&lt;/p&gt;

&lt;p&gt;The device is sleek, lightweight, and full of potential. It includes HDMI, USB, Ethernet, GPIO, and video input ports. Whether you're making an AI robot or building computer vision stuff (I know I will), this device has you covered.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Specs: Why It’s Called a "Raspberry Pi on Steroids"
&lt;/h3&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%2Fxgbu2rg46ntmjvocmtrg.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%2Fxgbu2rg46ntmjvocmtrg.png" alt="NVIDIA Jetson Orin Nano" width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s talk hardware. Look at what's packed into this small device:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CPU&lt;/strong&gt;: A six-core ARM Cortex 64-bit processor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPU&lt;/strong&gt;: NVIDIA Ampere architecture, tuned for AI workloads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RAM&lt;/strong&gt;: 8 GB of high-speed memory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connectivity&lt;/strong&gt;: Ethernet and wireless ready.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage Options&lt;/strong&gt;: NVMe support for all your AI model needs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it as a supercharged Raspberry Pi with a serious focus on AI.&lt;/p&gt;




&lt;h3&gt;
  
  
  Setting It Up: The Good, The Tricky, and The Rewarding
&lt;/h3&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%2Fccj0vmubx26d4pl5q3vq.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%2Fccj0vmubx26d4pl5q3vq.png" alt="NVIDIA Jetson Orin Nano" width="799" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Getting the Orin Nano up and running wasn’t exactly plug-and-play, but it wasn’t rocket science either. Here’s how it went down:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Firmware Update&lt;/strong&gt;: Before diving in, I updated the firmware to version 36.x. This step required temporarily installing Jetpack 5.1.3. Then, you update the firmware from there. (Pro tip: don’t skip this. You want the new firmware and Jetpack)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jetpack 6.1 Installation&lt;/strong&gt;: After the firmware update, I installed Jetpack 6.1, NVIDIA’s tailored OS for the Jetson lineup. It’s smooth, intuitive, and optimized for AI tasks.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you're purchasing this devcie, then burning SD cards and flashing firmware shouldn't be a problem.&lt;/p&gt;




&lt;h3&gt;
  
  
  Performance Tests: How Does It Handle AI Models?
&lt;/h3&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%2Fksio7jutzx7sdpaou31q.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%2Fksio7jutzx7sdpaou31q.png" alt="NVIDIA Jetson Orin Nano" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s where the fun begins—I tested the Orin Nano with AI models using &lt;strong&gt;Ollama&lt;/strong&gt;, a platform designed for running large language models (LLMs).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ollama.com" rel="noopener noreferrer"&gt;Check out Ollama here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s what I discovered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1 Billion Parameter Models&lt;/strong&gt;: Smooth sailing! These models ran effortlessly, perfect for tasks like chatbots or real-time applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3 Billion Parameter Models&lt;/strong&gt;: Still impressive, though with slightly longer loading times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;7 Billion Parameter Models&lt;/strong&gt;: Houston, we have a problem. The Orin Nano hit its limits here, occasionally freezing or locking up.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While it’s not designed for massive models, this performance is impressive for a device in this price range.&lt;/p&gt;

&lt;p&gt;You can view the &lt;a href="https://youtu.be/JRhAMHxlo3E?si=sWhFLwRx5Dgu7bO4&amp;amp;t=768" rel="noopener noreferrer"&gt;performance tests I did in this video&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Pros and Cons: The Real Deal
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What I Loved&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Compact and Lightweight&lt;/strong&gt;: Perfect for edge AI projects where space is a premium.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Impressive Performance&lt;/strong&gt;: At $250, you’re getting serious bang for your buck.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quiet Operation&lt;/strong&gt;: Even under load, it’s quiet—a big plus for home projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User-Friendly OS&lt;/strong&gt;: Jetpack is intuitive and packed with features.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What Needs Improvement&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Limits on Larger Models&lt;/strong&gt;: It’s not a deal-breaker, but don’t expect it to handle anything beyond 7 billion parameters comfortably.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Occasional Glitches&lt;/strong&gt;: Some random lockups and an odd “system throttled due to overcurrent” error. I'm looking into it. Manageable, but worth noting.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Final Verdict: Is It Worth It?
&lt;/h3&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%2Ft1vj9lxns2qsxa0hdnjl.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%2Ft1vj9lxns2qsxa0hdnjl.png" alt="NVIDIA Jetson Orin Nano" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Absolutely. The NVIDIA Jetson Orin Nano is a fantastic choice for developers exploring AI at the edge or prototyping innovative solutions. &lt;/p&gt;

&lt;p&gt;It’s not built for heavy-duty production workloads, but for $250, it’s hard to beat the value and potential.&lt;/p&gt;




&lt;h3&gt;
  
  
  What’s Next?
&lt;/h3&gt;

&lt;p&gt;I'll explore the Orin Nano's features more in upcoming projects, so stay tuned. If you're interested in edge AI or want to try out large language models, this device is a perfect start.&lt;/p&gt;

&lt;p&gt;Have questions or suggestions for tests? Just drop a comment or message me on social media. Let's see what this small device can really do!&lt;/p&gt;

&lt;p&gt;Happy experimenting! 🚀&lt;/p&gt;

&lt;p&gt;You can order the NVIDIA Jetson Orin Nano from the following places (Though right now there is no stock, check back!)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://amzn.to/4gq4QS8" rel="noopener noreferrer"&gt;Amazon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.arrow.com/en/products/945-13766-0000-000/nvidia?nvid=em-945-13766-0005-000" rel="noopener noreferrer"&gt;Arrow Electronics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sparkfun.com/products/22098?nvid=em-945-13766-0005-000" rel="noopener noreferrer"&gt;Sparkfun&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.seeedstudio.com/NVIDIAr-Jetson-Orintm-Nano-Developer-Kit-p-5617.html?nvid=em-945-13766-0005-000" rel="noopener noreferrer"&gt;Seeed Studio&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Questions, comments? Want more details? &lt;a href="https://x.com/intent/follow?screen_name=JeremyCMorgan" rel="noopener noreferrer"&gt;Yell at me&lt;/a&gt;!!&lt;/p&gt;

&lt;p&gt;Video version of this tutorial:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/JRhAMHxlo3E"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>iot</category>
      <category>development</category>
    </item>
    <item>
      <title>How to Make a Retro 2D JavaScript Game Part 3</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Thu, 19 Dec 2024 19:39:26 +0000</pubDate>
      <link>https://dev.to/jeremycmorgan/how-to-make-a-retro-2d-javascript-game-part-3-1154</link>
      <guid>https://dev.to/jeremycmorgan/how-to-make-a-retro-2d-javascript-game-part-3-1154</guid>
      <description>&lt;p&gt;Let’s make the game more fun with scoring and difficulty progression.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Adding a Score&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Modify the &lt;code&gt;create&lt;/code&gt; function to display a score:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scoreText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Score: 0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;24px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you'll see a score in the upper left hand corner of the screen:&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%2Fy0djnizu099w9fxxp419.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%2Fy0djnizu099w9fxxp419.png" alt="How to make a 2D JavaScript Game" width="800" height="699"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update the score when the player catches an item. In the update function where we created collision detection, add the following to update the score:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scoreText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Score: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So change this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Phaser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Geom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Intersects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;RectangleToRectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBounds&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBounds&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Caught an item!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Phaser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Between&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;750&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Phaser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Geom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Intersects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;RectangleToRectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBounds&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBounds&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Caught an item!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Phaser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Between&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;750&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scoreText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Score: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now every time you catch a block, the score updates:&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%2Fqv6cd7shwjz9iry8yxi6.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%2Fqv6cd7shwjz9iry8yxi6.png" alt="How to make a 2D JavaScript Game" width="800" height="699"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Increasing Difficulty&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Let's make this more difficult and make the items fall faster as the score increases:&lt;/p&gt;

&lt;p&gt;In our create function, add this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemSpeed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in our update() function, delete this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="c1"&gt;// Move falling item&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And replace it with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemSpeed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemSpeed&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Going faster! Speed is now: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemSpeed&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, every time you get 500 points, your speed increases, and it gets more difficult!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Retro Feel Enhancements&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;So let's add some graphics to this to make it more exciting. &lt;/p&gt;

&lt;p&gt;I just drew up these images, don't judge me. &lt;/p&gt;

&lt;p&gt;in preload, add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Load the player sprite&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;player&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pail.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then remove this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Player (Blue rectangle)&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;550&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x0000ff&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And replace it with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;   &lt;span class="c1"&gt;// Replace rectangle with sprite&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sprite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;550&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;player&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setScale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Adjust this value if needed to match desired size&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's turn the falling objects into apples. &lt;/p&gt;

&lt;p&gt;In preload(), add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apple&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apple.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Loa&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In create(), delete this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="c1"&gt;// Falling item (Green rectangle)&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x00ff00&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and replace it with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="c1"&gt;// Apple sprite&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sprite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apple&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setScale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Adjust scale if needed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now you'll see a different look!&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%2Fsnkyoqan4sytcy96kc23.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%2Fsnkyoqan4sytcy96kc23.png" alt="How to make a 2D JavaScript Game" width="800" height="603"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we see an apple and a pail, but it's in a dark room. Let's enhance our look by adding in a background. &lt;/p&gt;

&lt;p&gt;In preload():&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;background&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;background.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Load background image&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and in create():&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="c1"&gt;// Add background first so it appears behind other sprites&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;background&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Position at center of game (800/2, 600/2)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And let's make the score black so we can see it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scoreText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Score: 0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;24px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now save it and reload it:&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%2Fhdffu894ugybzvu392ks.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%2Fhdffu894ugybzvu392ks.png" alt="How to make a 2D JavaScript Game" width="800" height="599"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hey that looks awesome!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Final Thoughts&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Congratulations! 🎉 You’ve built a working &lt;em&gt;"Catch the Items"&lt;/em&gt; game using Phaser 3.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Next Steps&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Customize the shapes with images or sprites.&lt;/li&gt;
&lt;li&gt;Add sound effects.&lt;/li&gt;
&lt;li&gt;Experiment with game parameters like speed and item spawn rates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep practicing, and have fun creating your games. The possibilities are endless—go make something awesome! 🚀&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: If you'd rather have a video tutorial, here it is:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/rCgDvYNoaoc"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/JeremyMorgan/Catch-The-Apples" rel="noopener noreferrer"&gt;Source Code&lt;/a&gt;&lt;br&gt;
&lt;a href="https://jeremymorgan.itch.io/catch-the-apples" rel="noopener noreferrer"&gt;Playable Version&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>gamedev</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to Make a Retro 2D JavaScript Game Part 2</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Thu, 19 Dec 2024 19:36:10 +0000</pubDate>
      <link>https://dev.to/jeremycmorgan/how-to-make-a-retro-2d-javascript-game-part-2-6hg</link>
      <guid>https://dev.to/jeremycmorgan/how-to-make-a-retro-2d-javascript-game-part-2-6hg</guid>
      <description>&lt;p&gt;Let’s make this game interactive! We’ll add a player, movement controls, and falling items.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: If you'd rather have a video tutorial, here it is:&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Adding Placeholder Graphics&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Update the &lt;code&gt;create&lt;/code&gt; function to add shapes representing the player and falling items:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Player (Blue rectangle)&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;550&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x0000ff&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Falling item (Green rectangle)&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x00ff00&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Enable physics&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;physics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;existing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;physics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;existing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Player controls&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cursors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keyboard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createCursorKeys&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2. Moving the Player Left and Right&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Add movement logic to the &lt;code&gt;update&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Move player left&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cursors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isDown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Move player right&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cursors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isDown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The player can now move left and right using arrow keys!&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Adding Simple Collision Logic&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We need to update our config:&lt;/p&gt;

&lt;p&gt;change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;   &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Phaser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AUTO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Auto-detect WebGL or Canvas&lt;/span&gt;
   &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;// Game width&lt;/span&gt;
   &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="c1"&gt;// Game height&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To this, to add physics and gravity to our scene.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Phaser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AUTO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;physics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;arcade&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nx"&gt;arcade&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nl"&gt;gravity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make the falling item reset its position when it reaches the bottom:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Move falling item&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Reset item position&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Phaser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Between&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;750&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Random x-position&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Check for overlap&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Phaser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Geom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Intersects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;RectangleToRectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBounds&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBounds&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Caught an item!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Phaser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Between&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;750&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you'll see a screen that looks like this: and you should see green blocks falling. You can also move the player with your arrow keys:&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%2Fn70dximrbvhny7ac4udx.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%2Fn70dximrbvhny7ac4udx.png" alt="How to make a 2D JavaScript Game" width="800" height="698"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📝 &lt;strong&gt;Recap&lt;/strong&gt;: You added player movement, falling items, and basic collision detection. Your game is interactive! Now on to &lt;a href="https://dev.to/jeremycmorgan/how-to-make-a-retro-2d-javascript-game-part-3-1154"&gt;part 3&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Note: If you'd rather have a video tutorial, here it is:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/gFrix6Bz-C0"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/JeremyMorgan/Catch-The-Apples" rel="noopener noreferrer"&gt;Source Code&lt;/a&gt;&lt;br&gt;
&lt;a href="https://jeremymorgan.itch.io/catch-the-apples" rel="noopener noreferrer"&gt;Playable Version&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>gamedev</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Make a Retro 2D JavaScript Game Part 1</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Thu, 19 Dec 2024 19:34:38 +0000</pubDate>
      <link>https://dev.to/jeremycmorgan/how-to-make-a-retro-2d-javascript-game-part-1-4mba</link>
      <guid>https://dev.to/jeremycmorgan/how-to-make-a-retro-2d-javascript-game-part-1-4mba</guid>
      <description>&lt;p&gt;Welcome, aspiring game developers! 🚀 In this beginner-friendly guide, we’ll build a simple, retro-themed &lt;em&gt;"Catch the Items"&lt;/em&gt; game using &lt;strong&gt;Phaser 3&lt;/strong&gt;, a powerful JavaScript game development framework. This series of tutorials is designed for absolute beginners, so don’t worry if you’re new to coding or Phaser—you’re in good hands.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: If you'd rather have a video tutorial, here it is:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/WkiZSpFJozM"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Tutorial 1: Project Setup &amp;amp; Basics&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let’s start by setting up the environment, introducing key JavaScript concepts, and creating our first Phaser scene.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; In many of our tutorials we use Node/Vite to set up our games. But I want to keep this as simple as possible. To run this you can install the &lt;a href="https://www.npmjs.com/package/serve" rel="noopener noreferrer"&gt;NPM package serve&lt;/a&gt; or just open the document with Chrome. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. What is Phaser 3?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Phaser 3 is a popular &lt;strong&gt;2D game development framework&lt;/strong&gt; for creating browser-based games using JavaScript. It’s beginner-friendly, flexible, and powerful—perfect for making retro-inspired games like this one!&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;2. Setting Up Your Development Environment&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To keep things simple, we’ll use Phaser via its &lt;strong&gt;CDN link&lt;/strong&gt;. Here’s the setup:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create a project folder&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make a new folder on your computer, e.g., &lt;code&gt;catch-game&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Inside the folder, create a file named &lt;code&gt;index.html&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Add the basic HTML structure&lt;/strong&gt;:&lt;br&gt;
Paste the following code into your &lt;code&gt;index.html&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Catch the Items&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;// Phaser Game Configuration&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Phaser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AUTO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Auto-detect WebGL or Canvas&lt;/span&gt;
            &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;// Game width&lt;/span&gt;
            &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="c1"&gt;// Game height&lt;/span&gt;
            &lt;span class="na"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;preload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;preload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;game&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Phaser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Game&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;preload&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Preload assets (none yet)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Add game objects here&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;250&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello, Phaser!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;32px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Game loop (empty for now)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Run your game&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Open the &lt;code&gt;index.html&lt;/code&gt; file in any browser (Chrome is recommended).&lt;/li&gt;
&lt;li&gt;You should see a simple canvas with the text &lt;strong&gt;"Hello, Phaser!"&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&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%2Ftwv0zl2tqnuxd4uieumi.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%2Ftwv0zl2tqnuxd4uieumi.png" alt="How to make a 2D game in JavaScript" width="800" height="699"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🎉 &lt;strong&gt;Congratulations&lt;/strong&gt;! You’ve set up Phaser and displayed your first scene!&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;3. JavaScript Basics for Phaser&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Before diving deeper, let’s quickly review some JavaScript concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Variables&lt;/strong&gt;: Store data.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;   &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;playerName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PhaserHero&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Functions&lt;/strong&gt;: Reusable blocks of code.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;   &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;greetPlayer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Welcome to the game!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="nf"&gt;greetPlayer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Objects&lt;/strong&gt;: Collections of properties and methods.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;   &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hero&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;jump&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Player jumps!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;};&lt;/span&gt;
   &lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;jump&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll use these concepts as you develop your game in Phaser.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;4. Creating a Minimal Phaser Scene&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Modify the &lt;code&gt;create&lt;/code&gt; function to display a basic game canvas and some text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;250&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Catch the Items!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;32px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xff0000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Red square&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Reload the browser—you should see a red square in the center of the screen.&lt;/li&gt;
&lt;/ul&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%2Ft782cb7w82yy6cfzlgge.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%2Ft782cb7w82yy6cfzlgge.png" alt=" " width="800" height="699"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What does create() mean?
&lt;/h3&gt;

&lt;p&gt;Phaser uses three core functions to manage the game lifecycle: preload, create, and update. &lt;/p&gt;

&lt;p&gt;Let's break down what each function does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;preload()&lt;/strong&gt;: This function is called before the game starts. It's where you load your game assets like images, sounds, and more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;create()&lt;/strong&gt;: This function is called after the assets are loaded. It's where you create your game objects, set up the game world, and define initial game settings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;update()&lt;/strong&gt;: This function is called repeatedly throughout the game loop. It's where you update the game state, handle user input, and make things happen in your game world.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll be using these functions extensively as we build our games in this tutorial and future tutorials. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📝 &lt;strong&gt;Recap&lt;/strong&gt;: You’ve set up a Phaser game, learned some JavaScript basics, and displayed simple shapes on the canvas. Great start! Now on to &lt;a href="https://dev.to/jeremycmorgan/how-to-make-a-retro-2d-javascript-game-part-2-6hg"&gt;part 2&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://github.com/JeremyMorgan/Catch-The-Apples" rel="noopener noreferrer"&gt;Source Code&lt;/a&gt;&lt;br&gt;
&lt;a href="https://jeremymorgan.itch.io/catch-the-apples" rel="noopener noreferrer"&gt;Playable Version&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>gamedev</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Get Started with Python</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Mon, 16 Dec 2024 18:39:36 +0000</pubDate>
      <link>https://dev.to/jeremycmorgan/get-started-with-python-5djj</link>
      <guid>https://dev.to/jeremycmorgan/get-started-with-python-5djj</guid>
      <description>&lt;p&gt;Hey there, fellow geeks and future coders! Welcome to &lt;strong&gt;Part 1&lt;/strong&gt; of our series, "Learn Python"! If you've ever wanted to learn Python but felt overwhelmed by where to start, you’re in the right place. We’re going to break it down in easy, bite-sized chunks, walking you through each concept step by step. So grab your coffee (or your favorite beverage), and let’s dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Python?
&lt;/h2&gt;

&lt;p&gt;First off, why should you learn Python? Well, Python is one of the easiest programming languages to get started with. It’s used everywhere—web development, data science, automation, artificial intelligence, you name it! Whether you’re automating boring tasks or building the next big app, Python has your back.&lt;/p&gt;

&lt;p&gt;But the best part? &lt;strong&gt;Python is super beginner-friendly&lt;/strong&gt;. Its syntax (fancy word for how code is written) is clean and straightforward, so you can focus more on &lt;em&gt;what&lt;/em&gt; you want to do rather than &lt;em&gt;how&lt;/em&gt; to do it.&lt;/p&gt;

&lt;p&gt;Pretty cool, right?&lt;/p&gt;

&lt;h3&gt;
  
  
  What Can You Build with Python?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Websites (ever heard of Django or Flask?)&lt;/li&gt;
&lt;li&gt;Automation scripts (goodbye repetitive tasks!)&lt;/li&gt;
&lt;li&gt;Data analysis and machine learning models&lt;/li&gt;
&lt;li&gt;Games (even 2D ones like the classics!)&lt;/li&gt;
&lt;li&gt;IoT projects (you know, like controlling lights with a Raspberry Pi)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Okay, enough hype—let’s get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Setting Up Python
&lt;/h2&gt;

&lt;p&gt;Before we can write any Python code, we need to set up our environment. Don’t worry, this is easier than it sounds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install Python
&lt;/h3&gt;

&lt;p&gt;First, you'll need to install Python if you don't have it already. Go to the official Python website &lt;a href="https://python.org" rel="noopener noreferrer"&gt;python.org&lt;/a&gt;, download the latest version, and follow the instructions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For Windows&lt;/strong&gt;: During installation, make sure to check the box that says “Add Python to PATH.” This will let you run Python from anywhere on your system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For macOS/Linux&lt;/strong&gt;: Python usually comes pre-installed, but if you need the latest version, you can install it via a package manager like Homebrew (&lt;code&gt;brew install python3&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;If you want, you can also &lt;a href="https://www.jeremymorgan.com/tools/run-python/" rel="noopener noreferrer"&gt;run Python in a Web Browser&lt;/a&gt; here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Verify the Installation
&lt;/h3&gt;

&lt;p&gt;Once installed, open a terminal (or Command Prompt on Windows) and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see something like &lt;code&gt;Python 3.x.x&lt;/code&gt;, congratulations! Python is ready to roll.&lt;/p&gt;

&lt;h3&gt;
  
  
  Running Python Code
&lt;/h3&gt;

&lt;p&gt;You can run Python code in two ways:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Interactive Mode&lt;/strong&gt;: Just type &lt;code&gt;python&lt;/code&gt; in your terminal, and you can start writing Python code line-by-line. This is great for quick tests.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Demo idea:&lt;/em&gt; Try it out right now! Type &lt;code&gt;python&lt;/code&gt; in your terminal and then type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;   &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Testing in interactive mode!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hit enter, and you’ll see the result immediately. This is a fun way to experiment.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Script Mode&lt;/strong&gt;: Write your Python code in a &lt;code&gt;.py&lt;/code&gt; file (like &lt;code&gt;hello.py&lt;/code&gt;), then run it by typing:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   python hello.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Your First Python Program
&lt;/h2&gt;

&lt;p&gt;Alright, let’s write your very first Python program. We’re going to create the classic “Hello, World!” program.&lt;/p&gt;

&lt;h3&gt;
  
  
  Write Your Code
&lt;/h3&gt;

&lt;p&gt;Open your favorite text editor (VSCode, Sublime, or even Notepad), and type the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, World!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the file as &lt;code&gt;hello.py&lt;/code&gt;, then run it from the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python hello.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boom! You should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hello, World!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎉 &lt;strong&gt;Congrats, you just wrote your first Python program!&lt;/strong&gt; 🎉&lt;/p&gt;

&lt;h3&gt;
  
  
  Make It Interactive (Optional Demo)
&lt;/h3&gt;

&lt;p&gt;Want to take this a step further? Try prompting the user for input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s your name? &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Nice to meet you, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save it as &lt;code&gt;hello_interactive.py&lt;/code&gt; and run it. When prompted, type your name and see how Python responds! This little demo shows how Python can interact with users, making it feel more like a conversation and less like static code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Understanding the Basics
&lt;/h2&gt;

&lt;p&gt;Let’s go over some fundamental concepts in Python. These are building blocks that we’ll use in the next parts of this series.&lt;/p&gt;

&lt;h3&gt;
  
  
  Variables
&lt;/h3&gt;

&lt;p&gt;Think of variables as boxes where you can store information, like numbers or text.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# This is a variable storing a number
&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;

&lt;span class="c1"&gt;# This is a variable storing a string (text)
&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use these variables later in your code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;My name is&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;I am&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;years old&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Data Types
&lt;/h3&gt;

&lt;p&gt;Python has several data types you’ll use frequently:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Integers&lt;/strong&gt;: Whole numbers (e.g., &lt;code&gt;42&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Floats&lt;/strong&gt;: Decimal numbers (e.g., &lt;code&gt;3.14&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strings&lt;/strong&gt;: Text (e.g., &lt;code&gt;"Hello, World!"&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Booleans&lt;/strong&gt;: &lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can even check the type of any variable with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# Outputs: &amp;lt;class 'int'&amp;gt;
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;# Outputs: &amp;lt;class 'str'&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Comments
&lt;/h3&gt;

&lt;p&gt;Sometimes you need to add notes to your code. Python ignores comments, so they’re just for you (or anyone else reading the code).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# This is a comment. Python won't run this.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Math Operations
&lt;/h3&gt;

&lt;p&gt;Python can handle math like a calculator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Addition
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Subtraction
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Multiplication
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Division
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Make a Simple Calculator (Demo)
&lt;/h3&gt;

&lt;p&gt;Now that you know variables and math, let’s make a tiny calculator program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;num1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter a number: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;num2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter another number: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Sum:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Product:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run this, and you can quickly see Python doing something practical—performing math operations on the fly!&lt;/p&gt;

&lt;h3&gt;
  
  
  A Quick Variable Experiment
&lt;/h3&gt;

&lt;p&gt;Try this short experiment to understand how strings can be combined:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;, World!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This shows you how variables can evolve as your program runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Next Steps
&lt;/h2&gt;

&lt;p&gt;Now that you've got Python set up and written your first program, you're ready to take the next step. In &lt;strong&gt;Part 2&lt;/strong&gt; of this series, we’ll explore &lt;strong&gt;conditions and loops&lt;/strong&gt;, where Python will start making decisions for you and performing repetitive tasks. It’s going to be fun!&lt;/p&gt;

&lt;h3&gt;
  
  
  Practice Challenge
&lt;/h3&gt;

&lt;p&gt;Before we wrap up, try writing a Python script that does the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stores your name in a variable.&lt;/li&gt;
&lt;li&gt;Prints a greeting like "Hello, [Your Name]!"&lt;/li&gt;
&lt;li&gt;Multiplies two numbers and prints the result.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s a hint for the multiplication part:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Got it? Awesome! You’re on your way to becoming a Python pro. 🚀&lt;/p&gt;

&lt;p&gt;See you in &lt;strong&gt;Part 2&lt;/strong&gt;, where we’ll make Python even more powerful!&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>AI New Hotness for December 13th, 2024</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Sat, 14 Dec 2024 05:22:53 +0000</pubDate>
      <link>https://dev.to/jeremycmorgan/ai-new-hotness-for-december-13th-2024-22jn</link>
      <guid>https://dev.to/jeremycmorgan/ai-new-hotness-for-december-13th-2024-22jn</guid>
      <description>&lt;p&gt;Welcome to this week's edition of the AI New Hotness Newsletter, where we talk about new and exciting stuff to happen in the world of Generative AI, particularly for software developers. It’s a fast moving, wacky world for sure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reminder:&lt;/strong&gt; This is also &lt;a href="https://www.linkedin.com/pulse/ai-new-hotness-december-13th-2024-jeremy-morgan-8c4kc/" rel="noopener noreferrer"&gt;available on LinkedIn&lt;/a&gt; if you'd rather receive it there.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI in the News
&lt;/h2&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%2Feykp9b452u7nxxm4rxl7.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%2Feykp9b452u7nxxm4rxl7.png" alt="" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Introducing ChatGPT Pro
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;OpenAI releases ChatGPT Pro, a subscription service with powerful new features&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;OpenAI has released a new subscription service called ChatGPT Pro. This service provides unlimited access to OpenAI's most advanced models, including o1, o1-mini, GPT-4o, and Advanced Voice. It also includes o1 pro mode, which uses more compute to provide more reliable and accurate answers to difficult questions. ChatGPT Pro is designed for researchers, engineers, and other professionals who need to use AI for complex tasks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Details:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ChatGPT Pro provides unlimited access to OpenAI's most advanced models, including o1, o1-mini, GPT-4o, and Advanced Voice.&lt;br&gt;
It also includes o1 pro mode, which uses more compute to provide more reliable and accurate answers to difficult questions.&lt;br&gt;
ChatGPT Pro is designed for researchers, engineers, and other professionals who need to use AI for complex tasks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it Matters:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ChatGPT Pro is a powerful new tool that can be used for a variety of tasks, including writing, research, and development. With its unlimited access to OpenAI's most advanced models, ChatGPT Pro can help you to be more productive and creative.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://openai.com/index/introducing-chatgpt-pro/" rel="noopener noreferrer"&gt;Click here to read more&lt;/a&gt;
&lt;/h3&gt;




&lt;h3&gt;
  
  
  Make Movies with Text!  This AI Writes Videos for You
&lt;/h3&gt;

&lt;p&gt;OpenAI Unveils Sora, a Powerful New Video Generation Model&lt;/p&gt;

&lt;p&gt;OpenAI has released a new AI model called Sora that can create realistic videos from just a text description. This means you can create movies, explainer videos, or even home videos using just your imagination and some text!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Details:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sora can generate videos in a variety of styles, from photorealistic to cartoonish. It can also be used to create videos with special effects or to animate existing images.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it Matters:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sora is a powerful new tool that could revolutionize the way videos are created. It could make it possible for anyone to create professional-quality videos, even if they don't have any filmmaking experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://openai.com/index/sora-is-here/" rel="noopener noreferrer"&gt;Click here to read more&lt;/a&gt;
&lt;/h3&gt;




&lt;h3&gt;
  
  
  Unleash Your Creativity with Amazon Nova, the Powerful New AI
&lt;/h3&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%2Fsvkpq6iqv72zauzah2ys.jpg" 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%2Fsvkpq6iqv72zauzah2ys.jpg" alt="Amazon Nova" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generate Stunning Videos and Images, and More!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Do you ever feel limited by your imagination?  Amazon Nova is here to help!  This new generation of AI can be used to generate all sorts of creative content, from videos and images to who-knows-what-else.  Amazon Nova is also being used to improve the customer shopping experience on Amazon.  Keep reading to learn more about how Amazon Nova can help you!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Details:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Amazon Nova is a new generation of foundation models that can be used to generate creative content.&lt;/li&gt;
&lt;li&gt;Amazon Nova is also being used to improve the customer shopping experience on Amazon.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it Matters:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Amazon Nova is a powerful new tool that can be used to generate creative content and improve the customer shopping experience.  If you're looking for a way to boost your creativity or make shopping on Amazon even easier, then Amazon Nova is definitely worth checking out.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.aboutamazon.com/news/aws/amazon-nova-artificial-intelligence-bedrock-aws" rel="noopener noreferrer"&gt;Click here to read more&lt;/a&gt;
&lt;/h3&gt;




&lt;h3&gt;
  
  
  Google Releases Revolutionary AI Model, Gemini 2.0
&lt;/h3&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%2Fmmp35ysirzy5ewb4cyzp.jpg" 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%2Fmmp35ysirzy5ewb4cyzp.jpg" alt="" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google unveils its latest AI model, Gemini 2.0, promising to revolutionize the field of AI agent creation. Gemini 2.0 boasts advanced capabilities that push the boundaries of what's possible in AI. But with great power comes great responsibility, and Google emphasizes its commitment to developing AI responsibly, with safety and security at the forefront.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Details:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gemini 2.0 is more capable than previous versions, with native image and audio output and tool use.&lt;/li&gt;
&lt;li&gt;Gemini 2.0 Flash is available to developers and trusted testers, with wider availability planned for early next year.&lt;/li&gt;
&lt;li&gt;Google is exploring agentic experiences with Gemini 2.0, including Project Astra, Project Mariner, and Jules.&lt;/li&gt;
&lt;li&gt;Google is committed to building AI responsibly, with safety and security as key priorities.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it Matters:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Gemini 2.0 has the potential to revolutionize various fields by enabling the creation of powerful and intelligent AI agents. Google's commitment to responsible AI development ensures these advancements are made with safety and security in mind.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://blog.google/technology/google-deepmind/google-gemini-ai-update-december-2024/" rel="noopener noreferrer"&gt;Click here to read more&lt;/a&gt;
&lt;/h3&gt;




&lt;h3&gt;
  
  
  Apple's New AI Can Turn Your Thoughts Into Emojis!
&lt;/h3&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%2Feqlz2qk8uprbwz6sv2zt.jpg" 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%2Feqlz2qk8uprbwz6sv2zt.jpg" alt="Apple New AI" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tired of boring emojis? Apple Intelligence has just received a major upgrade, bringing you Image Playground and Genmoji to revolutionize the way you express yourself.&lt;/p&gt;

&lt;p&gt;Image Playground lets you unleash your creativity and create unique images using your imagination. It's like having a mini art studio right on your device!&lt;/p&gt;

&lt;p&gt;Genmoji takes emojis to a whole new level. Generate custom emojis that perfectly capture your mood or personality.&lt;/p&gt;

&lt;p&gt;Apple Intelligence is available now as a free software update, so you can start creating and expressing yourself in exciting new ways. But hurry, this update is only available for iPhone 16 and later, iPad with A17 Pro or M1 and later, and Mac with M1 and later!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it Matters:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apple Intelligence's new features offer a fun and creative way to express yourself through images and emojis. It's a free update available for compatible devices, so there's no reason not to try it out!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.apple.com/newsroom/2024/12/apple-intelligence-now-features-image-playground-genmoji-and-more/" rel="noopener noreferrer"&gt;Click here to read more&lt;/a&gt;
&lt;/h3&gt;




&lt;h3&gt;
  
  
  Apple Secretly Developing AI Chip to Rival NVIDIA
&lt;/h3&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%2Fiqxmt09aawx4w25s2iud.jpg" 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%2Fiqxmt09aawx4w25s2iud.jpg" alt="Apple Secretly Developing AI Chip to Rival NVIDIA" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Apple is reportedly working with Broadcom to develop its own AI chip, code-named Baltra, to power its AI services and reduce reliance on Nvidia. This move positions Apple alongside other tech giants like Google in the race to develop cutting-edge AI hardware.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Details:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apple is developing its first server chip specifically for AI processing.&lt;/li&gt;
&lt;li&gt;This move aims to reduce reliance on Nvidia's high-priced and often unavailable processors.&lt;/li&gt;
&lt;li&gt;Baltra is expected to be ready for mass production by 2026.&lt;/li&gt;
&lt;li&gt;Apple and Broadcom have a history of collaboration, including a recent multi-billion-dollar deal for 5G components.&lt;/li&gt;
&lt;li&gt;This development highlights the growing importance of AI hardware and the increasing competition in the AI chip market.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://finance.yahoo.com/news/apple-working-ai-chip-broadcom-141956432.html" rel="noopener noreferrer"&gt;Click here to read more&lt;/a&gt;
&lt;/h3&gt;




&lt;h3&gt;
  
  
  Talk to Santa AND See Him Live!
&lt;/h3&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%2Fppjb4ewa0jxy6ea8jb8o.jpg" 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%2Fppjb4ewa0jxy6ea8jb8o.jpg" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OpenAI just dropped a major update for the holiday season! You can now chat with Santa Claus in real-time using video calls and screen sharing. This new "Advanced Voice Mode" feature allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ask Santa anything: Get advice on beard care, hear about life at the North Pole, or have him tell you a story!&lt;/li&gt;
&lt;li&gt;See Santa's jolly face: Experience the magic of Christmas firsthand with live video chat.&lt;/li&gt;
&lt;li&gt;Get help with tricky responses: Brainstorm the perfect reply to a friend's Christmas message using screen sharing.&lt;/li&gt;
&lt;li&gt;This feature is rolling out now:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Available on mobile apps first, then desktop apps and web.&lt;br&gt;
Free for everyone to chat with Santa on the first try, even if you've used your voice limit.&lt;br&gt;
Full access to video and screen sharing for Plus, Pro, and Teams users (Europe rollout coming soon).&lt;br&gt;
Enterprise and EDU plans get access early next year.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.youtube.com/watch?v=NIQDnWlwYyQQ" rel="noopener noreferrer"&gt;Click here to read more&lt;/a&gt;
&lt;/h3&gt;




&lt;h3&gt;
  
  
  Anthropic's New AI Model: Is it Worth the Hype (and the Higher Price)?
&lt;/h3&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%2F671maej5aav4i0dxihbt.jpg" 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%2F671maej5aav4i0dxihbt.jpg" alt="Anthropic's New AI Model" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Claude 3.5 Haiku is here, but does it live up to the promise?&lt;/p&gt;

&lt;p&gt;Anthropic has released Claude 3.5 Haiku, a powerful new AI model that boasts improved coding, data analysis, and content moderation capabilities. However, this upgrade comes with a higher price tag, sparking debate among developers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Details:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Claude 3.5 Haiku surpasses its predecessor, 3 Opus, in key areas, offering enhanced performance in coding, data extraction, and content moderation.&lt;/p&gt;

&lt;p&gt;It can generate longer pieces of text and boasts a more up-to-date knowledge base.&lt;br&gt;
However, 3.5 Haiku lacks image analysis capabilities, limiting its versatility compared to other Anthropic models.&lt;br&gt;
The model's release was initially met with controversy due to an unexpected price increase.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://techcrunch.com/2024/12/12/anthropics-3-5-haiku-model-comes-to-claude-users/" rel="noopener noreferrer"&gt;Click here to read more&lt;/a&gt;
&lt;/h3&gt;




&lt;h2&gt;
  
  
  AI Tools
&lt;/h2&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%2Fbs47jr2jqla0frhste4p.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%2Fbs47jr2jqla0frhste4p.png" alt="" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Engaging Video Training Content in Minutes with Lupo
&lt;/h3&gt;

&lt;p&gt;Lupo is a platform that helps businesses create high-quality video training content quickly and easily. With Lupo, you can use Markdown and Marp to create courses, and even leverage their agency services if needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why you might need this tool:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create high-quality video training content quickly and easily&lt;/li&gt;
&lt;li&gt;Use Markdown and Marp to create courses&lt;/li&gt;
&lt;li&gt;Leverage their agency services if needed&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://lupo.ai/" rel="noopener noreferrer"&gt;Click here to read more&lt;/a&gt;
&lt;/h3&gt;




&lt;h3&gt;
  
  
  Want to Build AI Tools Like a Pro? This Low-Code Platform Makes it Easy (Even Without Coding Skills!)
&lt;/h3&gt;

&lt;p&gt;AISmartCube is a low-code AI tool platform that allows users to build AI tools without any coding required. The platform provides access to global large models, various plugins, a shared knowledge base, and ready-to-use tools and assistants. It also offers flexible pricing with points and a free credit allowance.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://aismartcube.com/" rel="noopener noreferrer"&gt;Click here to read more&lt;/a&gt;
&lt;/h3&gt;




&lt;h3&gt;
  
  
  Want to run any program automatically?
&lt;/h3&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%2Ftlvrqb43bhsddy999axd.jpg" 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%2Ftlvrqb43bhsddy999axd.jpg" alt="Pinokio" width="799" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pinokio is a browser that lets you install, run, and programmatically control any application, automatically. You can use Pinokio scripts, which are shared by the community, to automate tasks or create new functionalities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why you might need this tool:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With Pinokio, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automate repetitive tasks&lt;/li&gt;
&lt;li&gt;Create custom functionalities for your favorite applications&lt;/li&gt;
&lt;li&gt;Be more productive by letting Pinokio handle the boring stuff&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://pinokio.computer/" rel="noopener noreferrer"&gt;Click here to read more&lt;/a&gt;
&lt;/h3&gt;




&lt;h3&gt;
  
  
  Build Stunning Websites in 3D, Without Code - Dora!
&lt;/h3&gt;

&lt;p&gt;&lt;a href="/images/newsletter/12-13-24/www_dora_run_.jpg" class="article-body-image-wrapper"&gt;&lt;img src="/images/newsletter/12-13-24/www_dora_run_.jpg" alt="Article Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dora is a no-code platform that allows you to create 3D animated websites. With Dora, you can create beautiful and engaging websites without having to write any code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why you might need this tool:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create stunning and unique websites that will stand out from the competition.&lt;br&gt;
No coding required, so even those with no coding experience can create professional websites.&lt;br&gt;
Large community of users to help you learn and grow.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.dora.run/" rel="noopener noreferrer"&gt;Click here to read more&lt;/a&gt;
&lt;/h3&gt;




&lt;h3&gt;
  
  
  Build Websites and Landing Pages in Minutes - No Coding Required!
&lt;/h3&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%2Fatg76dghze8cza350wd4.jpg" 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%2Fatg76dghze8cza350wd4.jpg" alt="Sitekick AI" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sitekick AI is an AI-powered tool that allows you to create landing pages and websites easily. It can generate text, images, and code for your website, so you don't need any coding or design skills.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why you might need this tool:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Easy to use&lt;/strong&gt;: Sitekick AI does not require any coding or design skills, so it is perfect for people who do not have any experience with web development.&lt;br&gt;
&lt;strong&gt;Affordable&lt;/strong&gt;: Sitekick AI is affordable, and it has a 30-day money-back guarantee, so you can try it out risk-free.&lt;br&gt;
&lt;strong&gt;Saves time&lt;/strong&gt;: Sitekick AI can help you create websites and landing pages quickly and easily, so you can save time and focus on other important tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.sitekick.ai/" rel="noopener noreferrer"&gt;Click here to read more&lt;/a&gt;
&lt;/h3&gt;




&lt;h2&gt;
  
  
  Learn about AI
&lt;/h2&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%2Fv16fax03oocsgg07o08q.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%2Fv16fax03oocsgg07o08q.png" alt="Learn about AI" width="799" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Learn Anything Faster with the Power of AI
&lt;/h3&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%2Fzz6dqu1hu0ew7tgbyalw.jpg" 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%2Fzz6dqu1hu0ew7tgbyalw.jpg" alt="Kodekloud AI" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;KodeKloud has recently released an AI tutor that can personalize the training for you, providing real-time feedback and guides to craft a custom learning sequence just for you. Each task is validated for accuracy and it supports multiple languages. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Personalized learning&lt;/strong&gt;: The AI-powered learning suite tailors the learning experience to your individual needs and goals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-time feedback&lt;/strong&gt;: The AI Assistant provides real-time feedback on your progress, so you can identify and address any areas of difficulty.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Custom learning sequences&lt;/strong&gt;: The AI Tutor creates a custom learning sequence for any tech topic you want to master.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accuracy validation&lt;/strong&gt;: Each task is validated for accuracy, so you can be sure that you are learning the correct information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multilingual support&lt;/strong&gt;: The AI Assistant supports multiple languages, so you can learn in your preferred language.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://kodekloud.com/ai" rel="noopener noreferrer"&gt;Click here to read more&lt;/a&gt;
&lt;/h3&gt;




&lt;h3&gt;
  
  
  Build a Multimodal AI Agent with Gemini 2.0
&lt;/h3&gt;

&lt;p&gt;In this tutorial, we'll build a Multimodal AI Agent using Google's Gemini 2.0 Flash model that can simultaneously analyze videos and conduct web searches. This powerful combination allows the agent to provide comprehensive responses by understanding both visual content and related web information.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.theunwindai.com/p/build-a-multimodal-ai-agent-with-gemini-2-0" rel="noopener noreferrer"&gt;Click here to read more&lt;/a&gt;
&lt;/h3&gt;




&lt;h3&gt;
  
  
  Learn AI Assisted Development
&lt;/h3&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%2Fuv8tpsu82pqe7qqzhmev.jpg" 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%2Fuv8tpsu82pqe7qqzhmev.jpg" alt=" " width="799" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A course built by yours truly, you can learn AI-assisted programming, project planning, backend and frontend development, plus documentation using tools like ChatGPT, GitHub Copilot, BlackboxAI, Tabnine, and Cursor&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://kodekloud.com/courses/ai-assisted-development" rel="noopener noreferrer"&gt;Click here to read more&lt;/a&gt;
&lt;/h3&gt;




&lt;p&gt;Thanks for reading!!&lt;/p&gt;

&lt;p&gt;I started this newsletter to share all the cool stuff I’m finding in AI over time. Keep updated on the latest stuff with this newsletter. I'm glad you're here.&lt;/p&gt;

&lt;p&gt;Share this on your LinkedIn page if you think your friends might be interested in this stuff.&lt;/p&gt;

&lt;p&gt;BTW Check out &lt;a href="https://bit.ly/JMYouTubeLive" rel="noopener noreferrer"&gt;my YouTube Channel&lt;/a&gt; for more cool stuff with Generative AI. Tips, tutorials, reviews of AI tools and more.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>chatgpt</category>
    </item>
    <item>
      <title>Python Basic Syntax and Indentation: The Complete Beginner's Guide</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Thu, 12 Dec 2024 00:21:51 +0000</pubDate>
      <link>https://dev.to/jeremycmorgan/python-basic-syntax-and-indentation-the-complete-beginners-guide-4ecb</link>
      <guid>https://dev.to/jeremycmorgan/python-basic-syntax-and-indentation-the-complete-beginners-guide-4ecb</guid>
      <description>&lt;p&gt;When you're first learning to program, Python stands out for a special reason: it's designed to be read almost like English. Unlike other programming languages that use lots of symbols and brackets, Python relies on simple, clean formatting that makes your code look like a well-organized document.&lt;/p&gt;

&lt;p&gt;Think of Python's syntax like the grammar rules of a language. Just as English has rules about how to structure sentences to make meaning clear, Python has rules about how to write code so both humans and computers can understand it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Python's Basic Syntax
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Building Blocks
&lt;/h3&gt;

&lt;p&gt;Let's start with the simplest elements of Python syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# This is a comment - Python ignores anything after the '#' symbol
&lt;/span&gt;&lt;span class="n"&gt;student_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;    &lt;span class="c1"&gt;# A variable holding text (string)
&lt;/span&gt;&lt;span class="n"&gt;student_age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;         &lt;span class="c1"&gt;# A variable holding a number (integer)
&lt;/span&gt;
&lt;span class="c1"&gt;# Using variables in a sentence (string formatting)
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, my name is &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;student_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; and I&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;m &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;student_age&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; years old.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we're using several basic elements of Python:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Comments (lines starting with #)&lt;/li&gt;
&lt;li&gt;Variables (student_name and student_age)&lt;/li&gt;
&lt;li&gt;String formatting (the f"..." syntax)&lt;/li&gt;
&lt;li&gt;The print function&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Basic Operations
&lt;/h3&gt;

&lt;p&gt;Python can perform calculations and comparisons just like a calculator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Basic math operations
&lt;/span&gt;&lt;span class="n"&gt;total_score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;95&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;87&lt;/span&gt;    &lt;span class="c1"&gt;# Addition
&lt;/span&gt;&lt;span class="n"&gt;average&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total_score&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="c1"&gt;# Division
&lt;/span&gt;
&lt;span class="c1"&gt;# Comparisons
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;student_age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;student_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; can take advanced classes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Heart of Python: Understanding Indentation
&lt;/h2&gt;

&lt;p&gt;Here's where Python gets truly unique: instead of using brackets or special symbols to group code together, Python uses indentation. This might seem strange at first, but it makes Python code exceptionally clear and readable.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Indentation Creates Structure
&lt;/h3&gt;

&lt;p&gt;Think of indentation like the way you might organize a detailed outline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;make_sandwich&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1. Get two slices of bread&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# First level
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;has_cheese&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2. Add cheese&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;           &lt;span class="c1"&gt;# Second level
&lt;/span&gt;        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3. Add tomatoes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;         &lt;span class="c1"&gt;# Still second level
&lt;/span&gt;    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2. Add butter&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;           &lt;span class="c1"&gt;# Second level in else block
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4. Put the slices together&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Back to first level
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each indented block tells Python "these lines belong together." It's like creating a sub-list in an outline – everything indented under "if has_cheese:" is part of that condition.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Rules of Indentation
&lt;/h3&gt;

&lt;p&gt;Let's look at the key rules for Python indentation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_grade&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Rule 1: Use exactly 4 spaces for each indentation level
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Excellent!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Perfect score!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Rule 2: Aligned blocks work together
&lt;/span&gt;    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Good job!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Keep it up!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# This line is part of the elif block
&lt;/span&gt;
    &lt;span class="c1"&gt;# Rule 3: Unindented lines end the block
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Processing complete&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# This runs regardless of score
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Nested Indentation: Going Deeper
&lt;/h3&gt;

&lt;p&gt;As your programs get more complex, you'll often need multiple levels of indentation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;is_raining&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# First level: inside function
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Second level: inside if
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;is_raining&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Third level: nested condition
&lt;/span&gt;            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;It&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s warm but raining&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Take an umbrella&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;It&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s a warm, sunny day&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Perfect for outdoors&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;It&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s cool outside&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Take a jacket&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Complex Structures and Indentation
&lt;/h3&gt;

&lt;p&gt;Let's look at a more complex example that shows how indentation helps organize code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_student_grades&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;            &lt;span class="c1"&gt;# First level loop
&lt;/span&gt;        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Checking &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s grades...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;grade&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;grades&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="c1"&gt;# Second level loop
&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;grade&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;              &lt;span class="c1"&gt;# Third level condition
&lt;/span&gt;                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Outstanding!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;grade&lt;/span&gt;

        &lt;span class="n"&gt;average&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;grades&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

        &lt;span class="c1"&gt;# Back to first loop level
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;average&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Honor Roll&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;attendance&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;95&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# Another level
&lt;/span&gt;                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Perfect Attendance Award&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Common Patterns and Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Handling Multiple Conditions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Good: Clear and easy to follow
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_eligibility&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;grade&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attendance&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Too young&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;grade&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Grades too low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;attendance&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Attendance too low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Eligible&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Avoid: Too many nested levels
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_eligibility_nested&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;grade&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attendance&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;grade&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;attendance&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Eligible&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Attendance too low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Grades too low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Too young&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Working with Functions and Classes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;grades&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_grade&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;grade&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Notice the consistent indentation in methods
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;grade&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;grade&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;grades&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;grade&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Grade &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;grade&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; added&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Grade must be between 0 and 100&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Grade must be a number&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Common Mistakes and How to Fix Them
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Indentation Errors
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# WRONG - Inconsistent indentation
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Great job!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;# Error: no indentation
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Keep it up!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# Error: inconsistent indentation
&lt;/span&gt;
&lt;span class="c1"&gt;# RIGHT - Proper indentation
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Great job!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Keep it up!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Mixing Tabs and Spaces
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# WRONG - Mixed tabs and spaces (don't do this!)
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_average&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;    &lt;span class="c1"&gt;# This line uses a tab
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="c1"&gt;# This line uses spaces
&lt;/span&gt;        &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Practice Exercise: Putting It All Together
&lt;/h2&gt;

&lt;p&gt;Try writing this program to practice indentation and syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;grade_assignment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;late_days&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Start with the base score
&lt;/span&gt;    &lt;span class="n"&gt;final_score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;

    &lt;span class="c1"&gt;# Check if the assignment is late
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;late_days&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;late_days&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Deduct 2 points per late day
&lt;/span&gt;            &lt;span class="n"&gt;final_score&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;late_days&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Maximum lateness penalty
&lt;/span&gt;            &lt;span class="n"&gt;final_score&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;

    &lt;span class="c1"&gt;# Ensure score doesn't go below 0
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;final_score&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;final_score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="c1"&gt;# Determine letter grade
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;final_score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;final_score&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;final_score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;B&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;final_score&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;final_score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;C&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;final_score&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;F&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;final_score&lt;/span&gt;

&lt;span class="c1"&gt;# Test the function
&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;95&lt;/span&gt;
&lt;span class="n"&gt;late_days&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="n"&gt;letter_grade&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;final_score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;grade_assignment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;late_days&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Original Score: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Late Days: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;late_days&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Final Score: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;final_score&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Letter Grade: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;letter_grade&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Python uses indentation to understand code structure&lt;/li&gt;
&lt;li&gt;Always use 4 spaces for each level of indentation&lt;/li&gt;
&lt;li&gt;Be consistent with your indentation throughout your code&lt;/li&gt;
&lt;li&gt;Simpler, flatter code structure is usually better than deeply nested code&lt;/li&gt;
&lt;li&gt;Proper indentation makes code more readable and helps prevent errors&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;Now that you understand Python's basic syntax and indentation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Practice writing simple programs focusing on proper indentation&lt;/li&gt;
&lt;li&gt;Learn about different data types (strings, numbers, lists)&lt;/li&gt;
&lt;li&gt;Explore functions and classes&lt;/li&gt;
&lt;li&gt;Study loops and control structures&lt;/li&gt;
&lt;li&gt;Start working with Python modules and libraries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember: Good indentation habits form the foundation of becoming a skilled Python programmer. Take your time to master these concepts, and the rest will follow naturally!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorials</category>
      <category>python</category>
      <category>programming</category>
    </item>
    <item>
      <title>Understanding Python Syntax and Variables</title>
      <dc:creator>Jeremy Morgan</dc:creator>
      <pubDate>Tue, 03 Dec 2024 18:57:44 +0000</pubDate>
      <link>https://dev.to/jeremycmorgan/understanding-python-syntax-and-variables-1m0m</link>
      <guid>https://dev.to/jeremycmorgan/understanding-python-syntax-and-variables-1m0m</guid>
      <description>&lt;p&gt;Hey there, Python enthusiasts! If you’re diving into the world of Python or brushing up your skills, mastering Python’s syntax and variables is a fantastic place to start. Python is known for its simplicity and readability, making it a top choice for developers of all levels. In this guide, we’ll unravel the basics of Python syntax and variables with plenty of practical examples and best practices. So, grab a coffee (or your favorite beverage) and let’s dive in!&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Python Syntax and Variables Matter
&lt;/h2&gt;

&lt;p&gt;First things first—why should we care about syntax and variables in Python? Here’s the deal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Readability&lt;/strong&gt;: Python’s clean, intuitive syntax means less time decoding code and more time solving problems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency&lt;/strong&gt;: Proper use of variables keeps your code efficient and streamlined.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debugging&lt;/strong&gt;: A solid grasp of syntax helps you pinpoint errors faster than a debugger.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: Writing clear, organized code ensures that your projects can grow without turning into a tangled mess.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Convinced? Great. Let’s start with the basics.&lt;/p&gt;




&lt;h2&gt;
  
  
  Python Syntax Basics
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Indentation: Python’s Secret Sauce
&lt;/h3&gt;

&lt;p&gt;In Python, indentation isn’t just for looks—it’s how you define blocks of code. Forget braces (&lt;code&gt;{}&lt;/code&gt;) and semicolons—just align your code with consistent spacing.&lt;/p&gt;

&lt;p&gt;Here’s an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, Python!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it. The &lt;code&gt;print&lt;/code&gt; statement is indented to show it belongs to the &lt;code&gt;if&lt;/code&gt; block. Forget to indent, or mix spaces and tabs, and Python will call you out with a syntax error.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comments: Talk to Your Future Self
&lt;/h3&gt;

&lt;p&gt;Comments in your code are lifesavers when you revisit it months (or years) later. Python supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single-line comments&lt;/strong&gt;: Start with &lt;code&gt;#&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-line comments&lt;/strong&gt;: Enclose with triple quotes (&lt;code&gt;'''&lt;/code&gt; or &lt;code&gt;"""&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s how:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Single-line comment
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
Multi-line comment
spanning several lines.
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Python is Case-Sensitive
&lt;/h3&gt;

&lt;p&gt;Python distinguishes between &lt;code&gt;Variable&lt;/code&gt;, &lt;code&gt;variable&lt;/code&gt;, and &lt;code&gt;VARIABLE&lt;/code&gt;. Keep this in mind to avoid pesky bugs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Variables in Python
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Are Variables?
&lt;/h3&gt;

&lt;p&gt;Think of variables as labeled storage containers for your data. Python is dynamically typed, so you don’t need to declare types upfront. Here’s a quick example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;  &lt;span class="c1"&gt;# Integer
&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;3.14&lt;/span&gt;  &lt;span class="c1"&gt;# Float
&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, World!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# String
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Naming Variables
&lt;/h3&gt;

&lt;p&gt;To keep your code clean and readable, follow these rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Rules&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with a letter or underscore, not a number.&lt;/li&gt;
&lt;li&gt;Use only letters, numbers, and underscores—no spaces or special characters.&lt;/li&gt;
&lt;li&gt;Avoid Python keywords like &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;class&lt;/code&gt;, or &lt;code&gt;def&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Conventions&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;snake_case&lt;/strong&gt; (e.g., &lt;code&gt;user_name&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Choose meaningful names—&lt;code&gt;score&lt;/code&gt; is better than &lt;code&gt;s&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Assigning Values
&lt;/h3&gt;

&lt;p&gt;Assigning values is as simple as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;  &lt;span class="c1"&gt;# Multiple assignments
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Common Python Data Types
&lt;/h2&gt;

&lt;p&gt;Here’s a rundown of Python’s built-in data types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Numeric&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;int&lt;/code&gt;: Whole numbers (e.g., &lt;code&gt;42&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;float&lt;/code&gt;: Decimal numbers (e.g., &lt;code&gt;3.14&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Strings&lt;/strong&gt;: Enclosed in single, double, or triple quotes:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;  &lt;span class="n"&gt;greeting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, Python!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Booleans&lt;/strong&gt;: &lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;  &lt;span class="n"&gt;is_active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lists&lt;/strong&gt;: Ordered, mutable collections:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;  &lt;span class="n"&gt;fruits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;apple&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;banana&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cherry&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dictionaries&lt;/strong&gt;: Key-value pairs:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;  &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;age&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Performing Operations with Variables
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Arithmetic
&lt;/h3&gt;

&lt;p&gt;Python handles math like a champ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Addition
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Subtraction
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Multiplication
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Division
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Strings
&lt;/h3&gt;

&lt;p&gt;You can concatenate or repeat strings easily:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; Smith&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Alice Smith
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# AliceAliceAlice
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Logical Operations
&lt;/h3&gt;

&lt;p&gt;Logical operators (&lt;code&gt;and&lt;/code&gt;, &lt;code&gt;or&lt;/code&gt;, &lt;code&gt;not&lt;/code&gt;) are super handy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# False
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# True
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# False
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;p&gt;Write clean, efficient Python by following these tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Descriptive Names&lt;/strong&gt;: Use meaningful variable names.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DRY Principle&lt;/strong&gt;: Don’t Repeat Yourself—reuse your code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Follow PEP 8&lt;/strong&gt;: Stick to Python’s style guide.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comment Smartly&lt;/strong&gt;: Explain &lt;em&gt;why&lt;/em&gt;, not &lt;em&gt;what&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid Globals&lt;/strong&gt;: Keep variables local to their functions when possible.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Common Pitfalls (And How to Avoid Them)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Indentation Errors&lt;/strong&gt;: Stick to spaces or tabs (not both), and use four spaces per level.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope Issues&lt;/strong&gt;: Know the difference between local and global variables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type Mismatches&lt;/strong&gt;: Python doesn’t mix types:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;   &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
   &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
   &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# TypeError
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Q: What’s the difference between variables and constants?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Variables can change; constants stay fixed. Use all caps to indicate constants (e.g., &lt;code&gt;PI = 3.14&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: How can I check a variable’s type?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;type()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# &amp;lt;class 'int'&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Q: Can I change a variable’s type?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sure can! Python allows dynamic typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Now a string&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Mastering Python syntax and variables is your gateway to writing cleaner, more effective code. With practice, these basics will become second nature.&lt;/p&gt;

&lt;p&gt;Questions? Leave them in the comments here! &lt;/p&gt;

</description>
      <category>programming</category>
      <category>python</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
