<?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: Elise Erickson</title>
    <description>The latest articles on DEV Community by Elise Erickson (@erickson24).</description>
    <link>https://dev.to/erickson24</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1214577%2F6f9e75b2-2a9f-42ec-b505-b6e0261ed236.PNG</url>
      <title>DEV Community: Elise Erickson</title>
      <link>https://dev.to/erickson24</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/erickson24"/>
    <language>en</language>
    <item>
      <title>How to Automatically Add Authenticated Users to your Supabase Database</title>
      <dc:creator>Elise Erickson</dc:creator>
      <pubDate>Tue, 11 Jun 2024 00:49:27 +0000</pubDate>
      <link>https://dev.to/erickson24/how-to-automatically-add-authenticated-users-to-your-supabase-database-4006</link>
      <guid>https://dev.to/erickson24/how-to-automatically-add-authenticated-users-to-your-supabase-database-4006</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;SQL databases are a powerful tool that can do a lot more than just store and serve your data.  If you're new to programming, you might not be aware that you can create functions and triggers for those functions that allow the database to handle some pretty important stuff on its own.  In this case, SQL is going to detect a newly authenticated user and create a profile for them in the database.&lt;/p&gt;

&lt;p&gt;I'm using Supabase, but Firebase, Render, and other cloud database options will offer similar capabilities. For example, Firebase utilizes Google Cloud Functions.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Goal
&lt;/h1&gt;

&lt;p&gt;We have a website that needs to authenticate users and give them a profile to display information about themselves, including a screen name.  We decide to use Supabase because it offers flexible options for different types of authentication, such as email, magic link, Google, and more.&lt;/p&gt;

&lt;h1&gt;
  
  
  Background
&lt;/h1&gt;

&lt;p&gt;The type of authentication used doesn't matter because our solution is going to occur directly in the database, not the application.&lt;/p&gt;

&lt;p&gt;We're going to assume we've already created our table for the user's profile, including a string ID, string username, and string email.  It's important for the ID to be a string because this ID is going to be the same as the ID in your user's Supabase auth, which uses string IDs.&lt;/p&gt;

&lt;p&gt;You can actually access your auth data in Supabase in your Table Editor because the data there is also saved in a SQL table.  Just go to schema &amp;gt; auth &amp;gt; users to have a look.  &lt;/p&gt;

&lt;h1&gt;
  
  
  The Solution
&lt;/h1&gt;

&lt;h3&gt;
  
  
  1. Open the SQL Editor in the side panel of your project in Supabase
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8a1yki4ffuekvbhv9am2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8a1yki4ffuekvbhv9am2.png" alt="screenshot of side panel in Supabase" width="406" height="874"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. In the terminal, write the following function and click run.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE OR REPLACE FUNCTION public.create_user_profile()
RETURNS trigger
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
BEGIN
  INSERT INTO public.profiles (id, email)
  VALUES (NEW.id, NEW.email);

  RETURN NEW;
END;
$$;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This uses PL/pgSQL, the programming language used to manage SQL databases to create a function in your database.  This code doesn't run that function, rather it creates and defines the function or redefines it if it already exists.  You could delete the session after running it, but your function would still exist until you write more code in the terminal to delete it.&lt;/p&gt;

&lt;p&gt;PL/pgSQL looks a lot different than Python or Javascript, so here's a quick rundown.  The function inserts a new row into the &lt;code&gt;profiles&lt;/code&gt; table in the &lt;code&gt;public&lt;/code&gt; schema and writes the &lt;code&gt;id&lt;/code&gt; and &lt;code&gt;email&lt;/code&gt; columns based upon the value returned to the function by the trigger, defined as &lt;code&gt;NEW&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Now its time to tell the database when to trigger this function.
&lt;/h3&gt;

&lt;p&gt;Write and run the following code in the terminal. You can write it under the function definition or in a new session.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;create trigger create_profile_from_auth after
insert
    on
    auth.users for each row execute function create_user_profile();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells the database to trigger a function whenever a new row is inserted into the &lt;code&gt;users&lt;/code&gt; table of the &lt;code&gt;auth&lt;/code&gt; schema.  The function to trigger is the one we defined before, called &lt;code&gt;create_user_profile&lt;/code&gt; and the trigger is called &lt;code&gt;create_profile_from_auth&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Access profiles using the Supabase auth user ID as your primary key.
&lt;/h3&gt;

&lt;p&gt;Now you can access your profiles like any normal SQL table.  Since our ID / primary key is the same as the user ID in the auth table, we use that to access the profiles.  &lt;/p&gt;

&lt;p&gt;You can retrieve the user ID in your JS front end like 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getUser&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;uid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and your Python backend like this&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;supabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_user&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;uid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I wrote this blog as a quick solution for someone new to Supabase who was having trouble moving between the Auth and Database sides of Supabase.  Special thanks to Tom Holder and &lt;a href="https://boardshape.com/engineering/how-to-pull-google-profile-through-on-account-creation-with-supabase"&gt;this blog post&lt;/a&gt; for introducing me to this concept.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Jerseys as Join Tables: Using Real-World Examples to Understand Relationships Between Data</title>
      <dc:creator>Elise Erickson</dc:creator>
      <pubDate>Mon, 20 May 2024 21:10:11 +0000</pubDate>
      <link>https://dev.to/erickson24/jerseys-as-join-tables-using-real-world-examples-to-understand-relationships-between-data-hno</link>
      <guid>https://dev.to/erickson24/jerseys-as-join-tables-using-real-world-examples-to-understand-relationships-between-data-hno</guid>
      <description>&lt;h2&gt;
  
  
  🚀 Introduction
&lt;/h2&gt;

&lt;p&gt;Understanding data relationships, like any new material is easier when you understand the WHY behind the concept instead of just memorizing it.  In this post, I want to go over the 3 main types of data relationships with real-life examples.&lt;/p&gt;

&lt;p&gt;We'll be using SQL-Alchemy for the coding portion of these examples.  We won't be going over the setup portion of using a database with SQL-Alchemy.  Instead, we'll just focus on what the models for each object look like and how to create and utilize relationships between them.&lt;/p&gt;




&lt;h2&gt;
  
  
  📱 One-to-One Relationships
&lt;/h2&gt;

&lt;p&gt;A one-to-one relationship is pretty simple to understand, so we won't spend too long on it.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Real-World Example
&lt;/h3&gt;

&lt;p&gt;Most people have one smartphone that they share with no one.  The owner owns one phone and the phone belongs to one owner. &lt;/p&gt;

&lt;p&gt;We don't tattoo the model number of our smartphones on our wrist so everyone knows which phone is ours.  Instead, we register the phone to an account in our name. This way, if someone stumbles upon a lost phone, they can find the owner.&lt;/p&gt;

&lt;h3&gt;
  
  
  In Code
&lt;/h3&gt;

&lt;p&gt;In databases, developers follow the same pattern.  The owned object keeps track of its owner using the owner's ID as a foreign key.  This is consistent with conventions we'll see later on.&lt;/p&gt;

&lt;p&gt;We'll use a reference to the owner's ID, also known as a foreign key, to store the relationship.&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;class&lt;/span&gt; &lt;span class="nc"&gt;Owner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;__tablename__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;owners&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

    &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&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="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Define one-to-one relationship with Smartphone
&lt;/span&gt;    &lt;span class="n"&gt;phone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Smartphone&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;back_populates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;owner&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Smartphone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;__tablename__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;smartphones&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

    &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;owner_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;owners.id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;#foreign key
&lt;/span&gt;
    &lt;span class="c1"&gt;# Define one-to-one relationship with Owner
&lt;/span&gt;    &lt;span class="n"&gt;owner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Owner&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;back_populates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;phone&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;SQL-Alchemy also gives us some additional tools to access the relationship, shown as &lt;code&gt;phone&lt;/code&gt; and &lt;code&gt;owner&lt;/code&gt;. While these values aren't stored in the database, you can access them and make changes.  SQL-Alchemy understands the relationship and will set the corresponding values.&lt;/p&gt;

&lt;p&gt;For example, if a guy named Jack lost his phone and bought a new one, you could write&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;new_iphone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Smartphone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;iPhone X&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;jack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;phone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new_iphone&lt;/span&gt;
&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_iphone&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;#add new phone to db session
&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and a new smartphone object would be created with &lt;code&gt;owner_id&lt;/code&gt; set to Jack's ID.  We have to add the &lt;code&gt;new_iphone&lt;/code&gt; to our db session to make sure it records our changes to the database.  We don't have to add &lt;code&gt;jack&lt;/code&gt; because the relationship is held in the smartphone!&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚽ One-to-Many Relationships
&lt;/h2&gt;

&lt;p&gt;One-to-many relationships usually related to an object that owns another object.  While there are other cases, we'll simplify by assuming all one-to-many relationships can be explained this way.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Note on Lists
&lt;/h3&gt;

&lt;p&gt;The trouble with holding a list in a database is that it's so inefficient that it should be considered impossible. &lt;/p&gt;

&lt;p&gt;When a computer creates an object, it allocates a specific amount of memory for that object.  If a list has variable length, the computer won't know how much space to allocate to the list.  If it allocates too little and we keep adding onto the end of the list, the computer will have to copy the object, find a new larger space for it, paste the object there, and delete the old version.  After all that, then the computer can actually add the new items to the list.&lt;/p&gt;

&lt;p&gt;This is a quite simplified version of what would occur in the database, but you can start to see why this would be such an absurd way to plot the information.  Let's use an example to understand a better solution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real-World Example
&lt;/h3&gt;

&lt;p&gt;To keep with our sports theme, let's imagine a scrimmage between soccer teams from different neighborhoods.  Each soccer team brings its own gear to use for the match, most important of which are the soccer balls.&lt;/p&gt;

&lt;p&gt;How do the teams keep track of which balls are theirs at the end of the day?  Each team could keep a list of which balls belong to them and how many of each ball they own.  That way, if there's a dispute between teams they could refer to this list.&lt;/p&gt;

&lt;p&gt;But that's silly! Instead, teams label all their gear with a marker.  That way, anyone can pick up the ball and know who it belongs to.&lt;/p&gt;

&lt;p&gt;Andy uses the same concept in Toy Story.  He writes his name on the foot of all his toys instead of tattooing a list of every toy in his toybox on his own foot.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4p3lWvEX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://pbs.twimg.com/media/EBpJygEWwAEMs3I.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4p3lWvEX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://pbs.twimg.com/media/EBpJygEWwAEMs3I.png" alt="Toys with Andy written on the bottom" width="731" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  In Code
&lt;/h3&gt;

&lt;p&gt;Developers use the same logic when arranging one-to-many relationships in a database.  Each owned object holds a reference to its owner.&lt;/p&gt;

&lt;p&gt;The relationship will look identical to a one-to-one relationship.&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;class&lt;/span&gt; &lt;span class="nc"&gt;Team&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;__tablename__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;teams&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

    &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&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="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# One-to-many relationship with SoccerBall
&lt;/span&gt;    &lt;span class="n"&gt;balls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SoccerBall&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;back_populates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;team&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SoccerBall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;__tablename__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;soccer_balls&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

    &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;team_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;teams.id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c1"&gt;# Many-to-one relationship with Team
&lt;/span&gt;    &lt;span class="n"&gt;team&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Team&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;back_populates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;balls&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;The only change we make as changing is making the &lt;code&gt;Team&lt;/code&gt;'s property to a plural &lt;code&gt;balls&lt;/code&gt; so we know to expect a list of balls.  SQL-Alchemy does the rest of the work to show us the list of balls when we ask for them.&lt;/p&gt;

&lt;p&gt;We can buy a new ball for the soccer team, the Springfield Blazers, the same way we replaced Jack's smartphone earlier.&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;new_ball&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Ball&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;green&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;springfield_blazers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;balls&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;new_ball&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;
&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_ball&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;#add new ball to db session
&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, we dont have to add the changes to &lt;code&gt;springfield_blazers&lt;/code&gt; to our db session, because the relationship is stored in the &lt;code&gt;new_ball&lt;/code&gt; object.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎽 Many-to-Many Relationships
&lt;/h2&gt;

&lt;p&gt;Many-to-many object relationships are a little trickier to figure out.  These relationships typically are not owner-owned relationships.  They are usually participating-in or part-of relationships.&lt;/p&gt;

&lt;p&gt;The tricky part of these is that no matter which side you hold the relationship on, one side will have to hold a list of the other object ...right? (And we saw how tough that would be for the computer to manage)  Nope.  Let's check back in with our soccer teams for another example.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real-World Example
&lt;/h3&gt;

&lt;p&gt;Let's imagine the goalkeeper of our soccer team.  Her name is Mia.  Mia is a goalkeeper on her neighborhood team, the Springfield Blazers in the summer.  However, in the spring she plays for her school team, the Memorial High Wildcats.  Her performance on these 2 teams has been so excellent that she joined the Youth National Team for her country.&lt;/p&gt;

&lt;p&gt;When Mia's on the field, how do spectators, coaches, and other players know which team she plays for?  It would be silly if the coach held a huge poster with the roster up on the sideline.  &lt;/p&gt;

&lt;p&gt;Instead, Mia wears a jersey.  Her jersey has the team's name and mascot on the front, and her name and number on the back.  Spectators can look at any jersey and immediately know the identity of the player and the team they represent.  This jersey represents an intermediary object that holds a relationship to Mia and to her team.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ckt4o7yg0dsh2plpnfh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ckt4o7yg0dsh2plpnfh.png" alt="Mia's #10 jersey" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  In Code
&lt;/h3&gt;

&lt;p&gt;Relationships between objects in a database work the same way.  We need an intermediary object that can hold a reference to both sides of the relationship. This way, neither side has to hold a list of references to objects from the other side.  This intermediary object is called an association table or join table.&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;# The intermediary object
&lt;/span&gt;&lt;span class="n"&gt;player_jersey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;association&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;player_id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;players.id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;team_id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;teams.id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;__tablename__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;players&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

    &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;teams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Team&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secondary&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;player_jersey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;back_populates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;players&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Team&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;__tablename__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;teams&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

    &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;players&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Player&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secondary&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;player_jersey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;back_populates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;teams&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 case, editing the &lt;code&gt;player_jersey&lt;/code&gt; table looks a little different, but accessing a team's players looks the same.&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;# adding Mia to the Youth National Team
&lt;/span&gt;&lt;span class="n"&gt;new_association&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;association_table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;team_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;youth_national_team&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_association&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="c1"&gt;# getting the roster of Youth National Team Players
&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;youth_national_team&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;players&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For simplicity's sake we're not including Mia's number on her jersey.  If we wanted to do that, we would have to create a new model with properties, like this.  The other models would remain the same.&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;class&lt;/span&gt; &lt;span class="nc"&gt;PlayerJersey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;__tablename__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;player_jersey&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

    &lt;span class="n"&gt;player_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;players.id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;team_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;teams.id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;jersey_number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Player&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;back_populates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;teams&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;team&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Team&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;back_populates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;players&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 case, we can modify the &lt;code&gt;PlayerJersey&lt;/code&gt; like any other object and the relationship will update automatically.  We can also access a team's players or a player's teams the same was as with the association table.&lt;/p&gt;

&lt;h2&gt;
  
  
  😉 Conclusion
&lt;/h2&gt;

&lt;p&gt;Hopefully that was helpful! SQL-Alchemy is a powerful tool once you understand it and it can do far more than I showcased here.  Happy coding! &lt;/p&gt;

</description>
      <category>sql</category>
      <category>sqlalchemy</category>
      <category>database</category>
    </item>
    <item>
      <title>Regex - Understanding those [^Str|ng\$] for Beginners</title>
      <dc:creator>Elise Erickson</dc:creator>
      <pubDate>Thu, 07 Mar 2024 02:05:49 +0000</pubDate>
      <link>https://dev.to/erickson24/regex-understanding-those-strng-for-beginners-1bm0</link>
      <guid>https://dev.to/erickson24/regex-understanding-those-strng-for-beginners-1bm0</guid>
      <description>&lt;h2&gt;
  
  
  👋 Introduction
&lt;/h2&gt;

&lt;p&gt;Throughout my Self-Taught-Programmer-Relying-on-Stack-Overflow Career, I encountered regular expressions many times, without having any idea what they were or how they worked.  To me, they looked like a bunch of garbled characters that would be impossible to decipher.  How could &lt;code&gt;r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'&lt;/code&gt; possibly be read to match a string?&lt;/p&gt;

&lt;p&gt;This example seems like a pretty long regular expression (or regex), but it's also probably the most common: an email address validator.  I'm going to explain exactly how this and other regular expressions work and what all the little characters mean so you can build your own.&lt;/p&gt;

&lt;p&gt;Turns out - they're pretty simple to learn and fun to play with once you've got the hang of it!  Not to mention, regex can boil down multiple lines of code logic to decipher a string into one simple expression.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤓 What Are Regular Expressions?
&lt;/h2&gt;

&lt;p&gt;At its core, a regular expression is a sequence of characters that forms a pattern that can be matched against any string of text. These patterns are used to search, match, and manipulate text based on certain rules. Regular expressions provide a concise and flexible means of expressing complex text patterns.  They assist tasks such as text validation, search, extraction, and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  📋 Basic Syntax and Characters
&lt;/h2&gt;

&lt;p&gt;Regular expressions are read left to right, like the strings they represent. Regex breaks the string being searched into pieces and evaluates each piece against a piece of the regular expression itself.  &lt;/p&gt;

&lt;p&gt;This is how &lt;code&gt;r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'&lt;/code&gt; can represent each piece in an email address.  An email address's pieces would look like &lt;strong&gt;[text]@[text].[text]&lt;/strong&gt;.  We'll look closer at this example later.&lt;/p&gt;

&lt;p&gt;Regular expressions consist of various elements, including letters, numbers, brackets, and other characters. Here's a brief (NOT comprehensive) overview of some essential inputs and their meanings:&lt;/p&gt;

&lt;h3&gt;
  
  
  / Literal Characters /
&lt;/h3&gt;

&lt;p&gt;Literal characters give an exact match of the piece being evaluated.  They are surrounded by forward slashes for readability, but don't always have to be.  For example, if we only wanted to accept emails that ended in .com domains, the last piece of our regular expression would be &lt;code&gt;/.com/&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  [ Character Classes ]
&lt;/h3&gt;

&lt;p&gt;Character classes give a group of optional characters for the current piece to match.  Below are some examples of character classes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[ab12]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;one instance of any character a, b, 1, or 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[^yz89]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;one instance of any character besides y, z, 8, and 9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[a-p]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;any character between lowercase a and p inclusive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[A-Z]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;any uppercase letter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[1-5]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;any number between 1 and 5 inclusive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[0-9]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;any numeric character&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[a-z0-4]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;any lowercase letter or a number between 0 and 4 inclusive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[A-z]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;any upper or lowercase letter&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In our example, &lt;code&gt;[a-zA-Z0-9._%+-]&lt;/code&gt; refers to the user name of the address and it will accept any character that is alphanumeric as well as the characters &lt;code&gt;. _ % +&lt;/code&gt; and &lt;code&gt;-&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  ? Quantifiers *
&lt;/h3&gt;

&lt;p&gt;Quantifiers specify the length of the current piece of text.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;?&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;zero or one occurence of the preceding character or class&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;zero or more occurences of the preceding character or class&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;+&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;one or more occurences of the preceding character or class&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;{5}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;exactly 5 occurences of the preceding character or class&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;{2, 5}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;between 2 and 5 occurences of the preceding character or class&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;{7, }&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7 or more occurences of the preceding character or class&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  ^ Metacharacters $
&lt;/h3&gt;

&lt;p&gt;Metacharacters are special characters with a predefined meaning, but many of them can be escaped with a backslash, as seen in the following section.  Below are a few of the most common metacharacters.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;any character&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;^&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;signifies the beginning of a line&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[^]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;negates other characters when used inside brackets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;signifies the end of a line&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;`\&lt;/td&gt;
&lt;td&gt;`&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  \ Escaped Metacharacters
&lt;/h3&gt;

&lt;p&gt;Escaped metacharacters transform the meaning of other characters to capture other types of expressions found in a string of text.  They can be used independently or within a character class.  Below are the most common examples.  Notice that a capital letter negates the value of its lowercase counterpart.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\.&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;accepts a period (.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;accepts whitespace ( )&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\S&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;accepts any character than isn't whitespace ( )&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;accepts any digit 0-9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\D&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;accepts any character other than digits 0-9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\w&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;accepts letters, numbers, and underscores&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\W&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;accepts anything other than letters, numbers, and underscores&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  📧 Breaking Down an Email Validator
&lt;/h2&gt;

&lt;p&gt;Let's break down the email address validator from before.&lt;/p&gt;

&lt;p&gt;An email address is comprised of three main pieces: the user name and two pieces of the domain name separated by a period.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[user name]@[domain].[com]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Without regex, we might solve this problem like so:&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_valid_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&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="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

    &lt;span class="n"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&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;span class="k"&gt;if&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;parts&lt;/span&gt;&lt;span class="p"&gt;)&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;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

    &lt;span class="n"&gt;local_part&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;domain_part&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parts&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="n"&gt;parts&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="k"&gt;if&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;local_part&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;or&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;domain_part&lt;/span&gt;&lt;span class="p"&gt;)&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;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

    &lt;span class="k"&gt;if&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="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;local_part&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="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="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;local_part&lt;/span&gt;&lt;span class="p"&gt;[&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="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;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;domain_part&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="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="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;domain_part&lt;/span&gt;&lt;span class="p"&gt;[&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="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;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

    &lt;span class="n"&gt;domain_parts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;domain_part&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&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;span class="k"&gt;if&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;domain_parts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;part&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;domain_parts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&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;part&lt;/span&gt;&lt;span class="p"&gt;)&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;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

    &lt;span class="n"&gt;disallowed_chars&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;?&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;!&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;#&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;$&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;%&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;^&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;&amp;amp;&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;*&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;(&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;)&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;[&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;]&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;{&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;}&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;&amp;lt;&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;&amp;gt;&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;,&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;;&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;:&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;/&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="se"&gt;\\&lt;/span&gt;&lt;span class="sh"&gt;'&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;char&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;disallowed_chars&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;char&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With regex, however, we can boild this function down to 2 lines:&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_valid_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&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;is_valid_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;example@email.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# Output: True
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's go through the regex piece by piece.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;^&lt;/code&gt; beginning of the string&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[a-zA-Z0-9._%+-]&lt;/code&gt; allow any alphanumeric character or one of those special characters&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;+&lt;/code&gt; make sure at least one of the characters in the class from Step 2 is present (in the user name)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@&lt;/code&gt; require an @ symbol before the next piece&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[a-zA-Z0-9.-]&lt;/code&gt; allow any alphanumeric character, a period, or a dash&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;+&lt;/code&gt; make sure at least one of the characters in the class from Step 5 is present (in the first half of the domain)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\.&lt;/code&gt; require a period before moving onto the next piece&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[a-zA-Z]&lt;/code&gt; accept any alphanumeric character&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;{2,}&lt;/code&gt; require at least 2 of the characters in the class from Step 8 (in the last half of the domain)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$&lt;/code&gt; end of the string&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;re.match&lt;/code&gt; simply checks the entirety of the string given to email to see if it is accepted by our given regex pattern.  More on regex functions below.&lt;/p&gt;

&lt;p&gt;Boom! You've validated an email using regex! Much nicer than writing a whole validation function, right?&lt;/p&gt;

&lt;p&gt;Now think about this: How would you build the validator to only accept addresses with a &lt;em&gt;.com&lt;/em&gt; domain name?&lt;/p&gt;

&lt;p&gt;Hint: test out your answer with &lt;a href="https://regex101.com/"&gt;regex101.com&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🖥️ Regex Functions
&lt;/h2&gt;

&lt;p&gt;Regex can be used to match, search, substitute, and extract pieces of a text string.  I won't be going over those here, but there is great documentation for utilizing these functions. See Resources below.&lt;/p&gt;

&lt;h2&gt;
  
  
  📈 Conclusion
&lt;/h2&gt;

&lt;p&gt;Regex supports advanced techniques such as capturing groups, lookahead and lookbehind assertions, and backreferences. This was by no means a comprehensive guide to regex.  &lt;/p&gt;

&lt;p&gt;In fact, most languages have packages that utilize slightly different versions of regex.  Make sure to read the official documentation for the package version you're using and experiment with some examples yourself.&lt;/p&gt;

&lt;p&gt;Regular expressions are a versatile tool for text processing tasks. While the syntax may seem daunting to new programmers at first glance, once you understand them they become fun tools with which to solve complex problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://regex101.com/"&gt;Regex Sandbox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://regexone.com/"&gt;Regex Practice Problems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.python.org/3/library/re.html"&gt;Python Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3schools.com/python/python_regex.asp"&gt;W3 Schools Python Lessons&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions/Cheatsheet"&gt;Mozilla Docs Regex Cheat Sheet for JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>regex</category>
      <category>beginners</category>
      <category>cheatsheet</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>React Hooks Cheat Sheet</title>
      <dc:creator>Elise Erickson</dc:creator>
      <pubDate>Fri, 05 Jan 2024 14:41:19 +0000</pubDate>
      <link>https://dev.to/erickson24/react-hooks-cheat-sheet-52k4</link>
      <guid>https://dev.to/erickson24/react-hooks-cheat-sheet-52k4</guid>
      <description>&lt;h1&gt;
  
  
  Hooks Rundown
&lt;/h1&gt;

&lt;p&gt;React Hooks allow users to pass and access data within functional components in React.  They allow users to access built-in React features such as state, context, and more.  If you haven't yet encountered Hooks, read more about them &lt;a href="https://react.dev/reference/react/hooks"&gt;here.&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The Cheat Sheet
&lt;/h1&gt;

&lt;p&gt;The point of this post isn't to teach you hooks; It's to give you an easy guide to refer to without digging through the docs because you forgot some simple syntax.  I'll provide a more in-depth explanation of each hook below if you ever need a refresher.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4dy2b543ig2i48ru8oue.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4dy2b543ig2i48ru8oue.jpg" alt="Cheat Sheet of React Hooks" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;import { useState, useEffect, useContext, useRef } from 'react'&lt;/code&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  useState : Access and modify internal state objects
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;const [name, setName] = useState("default_user")&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Takes one optional parameter that sets the default value of the state object&lt;/li&gt;
&lt;li&gt;Returns a reference to internal state object and a setter function for that state object&lt;/li&gt;
&lt;li&gt;Triggers a rerender of the whole component which is default behavior when state is changed&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  useEffect : Call a function whenever a component is rendered or a state dependency is changed
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;useEffect(callbackFunction, [dependencies])&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Takes 1 required parameter: &lt;em&gt;a function&lt;/em&gt; and 1 optional parameter: &lt;em&gt;an array of dependencies&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;[ ]&lt;/code&gt; - no dependencies, only runs on initial component render&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[name]&lt;/code&gt; - runs when variable &lt;em&gt;name&lt;/em&gt; is changed, including initial render&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;null&lt;/code&gt; - all states are dependencies, runs on initial render and every state change / rerender&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Calls given function whenever dependencies are changed&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  useContext : Access internal context props provided by parent
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;const user = React.useContext(MyContext)&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Takes one argument: the context object created with &lt;code&gt;React.createContext()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Returns whatever data was passed to the context provider value&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create context object&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const UserContext = React.createContext()
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create context provider&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function UserProvider({children}){

    const user = {
        name: "puppy_lover_2024",
        avatar: "pexels.com/photo/puppy/"
    }

    return(
        &amp;lt;UserContext.Provider value={user}&amp;gt;
            {children}
        &amp;lt;/UserContext.Provider&amp;gt;
    )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Wrap children components in context provider&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {
    return (
        &amp;lt;UserProvider&amp;gt;
            [screenComponents]
        &amp;lt;/UserProvider&amp;gt;
    )
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Access the context using the useContext in a child component&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const user = React.useContext(UserContext)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  useRef - references in internal variable that persists across rerenders but does not trigger them
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;const numRenders = useRef(1)&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Takes one argument: a default value for the variable&lt;/li&gt;
&lt;li&gt;Returns a reference to that variable which has a property &lt;code&gt;.current&lt;/code&gt; that can be treated like any prop/variable&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Useful for keeping track of previous state values and referencing DOM elements&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function ReferencedDiv({children}){
    const currentDiv = useRef()
    return(
        &amp;lt;div ref={currentDiv}&amp;gt;
            {children}
        &amp;lt;/div&amp;gt;
    )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;import { useParams, useRouteError, useOutletContext, useNavigate } from 'react-router-DOM&lt;/code&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  useParams - access data stored in current URL
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;const params = useParams()&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Takes no arguments&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Returns object with a key of whate the router was told to expect and a value of the parameter that exists in the link itself&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In Router:
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    path: "/profile/:name", element &amp;lt;ProfilePage/&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;



&lt;ul&gt;
&lt;li&gt;In Link:
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Link to={ `/profile/puppy_lover_2024` }&amp;gt;
    View Profile
&amp;lt;/Link&amp;gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;ul&gt;
&lt;li&gt;Returned:
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return( useParams() )
-&amp;gt; { name: "/profile/puppy_lover_2024" }
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  useNavigate - Returns function to programmatically navigate to given route
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;const navigate = useNavigate()&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Takes no arguments&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Returns a function that will navigate to given route param&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const navigate = useNavigate()

...

navigate("/login")
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  useRouteError - catch any error in the UI and reroute to this component
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;const error = useRouteError()&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Takes no arguments&lt;/li&gt;
&lt;li&gt;Returns the error that caused the reroute to this page / component&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  useOutletContext - accesses data stored in the direct parent Outlet's context
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;const myData = useOutletContext()&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Takes no arguments&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Returns the object passed to &lt;code&gt;context&lt;/code&gt; parameter in parent &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In Outlet (parent component):
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Outlet context={ name: "puppy_lover_2024" }&amp;gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;ul&gt;
&lt;li&gt;Returned :
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return( useOutletContext() )

-&amp;gt; { name: "/profile/puppy_lover_2024" }
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Only works if the Outlet is this components direct parent&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Writing Scalable Code for Self-Taught Developers</title>
      <dc:creator>Elise Erickson</dc:creator>
      <pubDate>Thu, 14 Dec 2023 02:00:36 +0000</pubDate>
      <link>https://dev.to/erickson24/writing-scalable-code-in-javascript-inn</link>
      <guid>https://dev.to/erickson24/writing-scalable-code-in-javascript-inn</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I began my coding career by teaching myself JavaScript and ReactNative to build appointment arrival management systems for medical clinics.  I felt I had built the skills to pursue a job in tech, but upon meeting with a recruiter I discovered I had a lot to learn, particularly in the realm of building readable, scalable, future-proof code.&lt;/p&gt;

&lt;p&gt;We decided to pursue a coding bootcamp where I could learn these principles, amongst other things.  I keep a separate tab in my study binder for tips, principles, and conventions of building scalable code.  I figured I would share them here for other self-taught programmers looking to elevate their craft and I’ll try to update it as I learn more.&lt;/p&gt;

&lt;p&gt;Code examples are given in JavaScript, but the principles are applicable to most development languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Easier Debugging
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Test-Driven Development: Decide how you want a function to act and what you want it to return given certain parameters.  Then write the test use-case using Mocha BEFORE writing the function solution.&lt;/li&gt;
&lt;li&gt;Always use &lt;em&gt;const&lt;/em&gt; when creating new variables, then change to &lt;em&gt;let&lt;/em&gt; later on if you decide that variable should be mutable.  In a concise program, variables will be &lt;em&gt;const&lt;/em&gt; more often than you expect.&lt;/li&gt;
&lt;li&gt;Only reflect changes in your frontend once they have been accepted by the backend.  For example, don’t increment a “thumbs-up counter” until the server confirms that it received your user’s “thumbs-up”.&lt;/li&gt;
&lt;li&gt;Functions should only perform one task.  These means breaking up long functions into smaller helper functions and then calling them within a parent function.  This will help you trace bugs to their responsible function, makes code more reusable and more readable!&lt;/li&gt;
&lt;li&gt;Take the time to get to know the &lt;a href="https://developer.chrome.com/docs/devtools" rel="noopener noreferrer"&gt;developer tools&lt;/a&gt; in your web browser for debugging.  They do more than your &lt;em&gt;console.log()&lt;/em&gt; ever could!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Nondestructive Modification
&lt;/h2&gt;

&lt;p&gt;It actually takes less computer-brain-power to create and play with a new object than modify preexisting objects in most cases.  This is because the computer has to check to see if the memory space allocated for the original object is large enough to handle modification before it can actually modify it, whereas it can allocate as much memory as necessary for a new object.  Because of this, it’s important to understand methods of nondestructive modification.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use the spread operator or &lt;em&gt;Object.assign()&lt;/em&gt; to create a copy of the original object, not just a copy of the reference to the memory location of the old object.  Side note: these only create shallow copies.  For more information on that, see &lt;a href="https://medium.com/@ruchivora16/understanding-shallow-vs-deep-copy-in-javascript-a21d986f0864" rel="noopener noreferrer"&gt;here&lt;/a&gt;.
&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;newObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="nx"&gt;oldObject&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt; 
&lt;span class="c1"&gt;// makes a copy of the data in oldObject&lt;/span&gt;
&lt;span class="c1"&gt;// modifying newObject leaves oldObject alone&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;newObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oldObject&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// makes a copy of the data in oldObject&lt;/span&gt;
&lt;span class="c1"&gt;// modifying newObject leaves oldObject alone&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;newObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;oldObject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Avoid This!!&lt;/span&gt;
&lt;span class="c1"&gt;// copies the memory location of oldObject&lt;/span&gt;
&lt;span class="c1"&gt;// modifying newObject will still modify oldObject&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Use functions such as &lt;em&gt;.map&lt;/em&gt; and &lt;em&gt;.filter&lt;/em&gt; to iterate over an array and return a new one without changing the original&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Documentation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When using Github, commit frequent updates with compartmentalized update messages and content&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;1: Initialize Repo&lt;/p&gt;

&lt;p&gt;2: Add basic HTML and CSS&lt;/p&gt;

&lt;p&gt;3: Write initial HTML Content&lt;/p&gt;

&lt;p&gt;4: Add CSS classes and rules&lt;/p&gt;

&lt;p&gt;5: Add new color scheme to CSS&lt;/p&gt;

&lt;p&gt;6: Finish writing About Me section&lt;/p&gt;

&lt;p&gt;7: Add Download Resume button and link&lt;/p&gt;

&lt;p&gt;8: Add JS Event Listeners&lt;/p&gt;

&lt;p&gt;…&lt;/p&gt;

&lt;p&gt;53: Finish and publish website&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Only use comments to describe what is happening in your code if the variable names and functions are unconventional, which shouldn’t be very often!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Readability
&lt;/h2&gt;

&lt;p&gt;Readability ≥ Efficiency&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Variable and function names should be self explanatory.  If you have to write out a long comment to explain what your function is doing it can probably be broken down into smaller, more understandable functions.&lt;/li&gt;
&lt;li&gt;Your code should read like English.  The more stable item being compared is named AFTER the less stable one, just like in English.
&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You would never say "15 is younger than the age of my brother."  You would just say "My brother is older than 15."&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;newUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;oldUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example is a little more ambiguous than the age example, because age is constant whereas the two ages being compared here are not.  However, if we're changing something about the &lt;code&gt;newUser&lt;/code&gt; and using the &lt;code&gt;oldUser&lt;/code&gt; as a benchmark for comparison, the &lt;code&gt;oldUser&lt;/code&gt; should be considered the more stable open.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;if…else&lt;/em&gt; statements are much easier to read than nested &lt;em&gt;if&lt;/em&gt; statements.&lt;/li&gt;
&lt;li&gt;Use functions that are self-explanatory to communicate to other developers and your future self what to expect from the function.  This also makes debugging simpler.
&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;squaredArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&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;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&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="c1"&gt;// iterates through array and squares each number&lt;/span&gt;
&lt;span class="c1"&gt;// nondestructively returns new array as squaredArray&lt;/span&gt;
&lt;span class="c1"&gt;// .map tells other developers to expect a new array to be returned&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;squaredArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&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;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;squaredArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// iterates through array and squares each item then adds it to squaredArray&lt;/span&gt;
&lt;span class="c1"&gt;// not wrong, but forEach doesn't tell a developer what to expect as a result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;When using HTML, CSS, and JS together, keep content and presentation separate by using HTML and CSS properly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Other Tips for Self-Taught Programmers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The 5 iterator functions are &lt;em&gt;forEach&lt;/em&gt;, &lt;em&gt;filter&lt;/em&gt;, &lt;em&gt;find&lt;/em&gt;, &lt;em&gt;map&lt;/em&gt;, and &lt;em&gt;reduce&lt;/em&gt;.  Understand them thoroughly and never use a &lt;em&gt;for&lt;/em&gt; loop again!&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;array.reduce()&lt;/em&gt; is very commonly used by JS developers.  Get extra comfortable with it.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>learning</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
