<?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: Jackie Cisneros</title>
    <description>The latest articles on DEV Community by Jackie Cisneros (@kriegercisneros).</description>
    <link>https://dev.to/kriegercisneros</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%2F912519%2F160192ca-b304-479d-ac22-6d2deb8fbd4c.jpg</url>
      <title>DEV Community: Jackie Cisneros</title>
      <link>https://dev.to/kriegercisneros</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kriegercisneros"/>
    <language>en</language>
    <item>
      <title>Engineers Decide, Agents Execute: Why Small Teams Are the New Default</title>
      <dc:creator>Jackie Cisneros</dc:creator>
      <pubDate>Thu, 15 Oct 2026 10:10:45 +0000</pubDate>
      <link>https://dev.to/kriegercisneros/engineers-decide-agents-execute-why-small-teams-are-the-new-default-b79</link>
      <guid>https://dev.to/kriegercisneros/engineers-decide-agents-execute-why-small-teams-are-the-new-default-b79</guid>
      <description>&lt;p&gt;At WhaleHawk, I lead an engineering team of five. We build a sales intelligence platform for healthcare executive prospecting. That's a small team by any measure, and with the right AI workflow, it's the right size.&lt;/p&gt;

&lt;p&gt;Why do we keep our team this size? Building your people assets at the end of 2026 is not about putting bodies in seats. With the power of the coding bot, it's actually a liability to host that approach -- even a partial degree of misdirection will throw a coder seriously off course with the tools at hand.&lt;/p&gt;

&lt;p&gt;With our team, we stopped treating AI as autocomplete and started treating it as the workforce, with one non-negotiable rule:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The engineer is the decision point. The agent does the work.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you're a founder or eng leader planning next year's team, here's my take. A small team with an AI workflow is no longer the scrappy option. It's the new default, and how disciplined your team is will decide how far and how fast you can go together.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule is simple. Living it is not.
&lt;/h2&gt;

&lt;p&gt;"Engineers decide, agents execute" sounds obvious. Actually putting it into practice is a different story -- especially on a small team where everyone has real autonomy and nobody is waiting around for permission.&lt;/p&gt;

&lt;p&gt;Autonomy is why small teams move fast. It's also how a codebase quietly fills up with decisions nobody made on purpose. Hand an agent a vague ticket and it will make a dozen design choices for you. For me, as the one driving our technical and product direction, that is terrifying.&lt;/p&gt;

&lt;p&gt;To combat this -- and I do mean combat, because it takes an active defense -- we built a process with one job: make sure every meaningful decision is made by a human, out loud, before an agent writes a line of code.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we work: decisions first, code last
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Talk it through.&lt;/strong&gt; Every piece of work starts as a conversation, and it is based on a real need -- an engineer should never write code for a feature we cannot explain the requirements for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write the proposal.&lt;/strong&gt; It covers what we're building and why, plus mockups and other assets from the rest of the team. People have to read it and approve it, and most importantly, talk about it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write the technical spec.&lt;/strong&gt; The spec is essentially pseudocode, and is our internal pulse check -- are we alive and making the decisions for how this fits into our system? Are we following engineering best practices? Is this thoughtful?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan it in Linear.&lt;/strong&gt; We create a project and milestones. That's the map of how we'll get it done, usually broken down into thoughtful chunks of work. This keeps the scope manageable, and can help us understand timelines and expectations for QA.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope the issues.&lt;/strong&gt; Each Linear issue is a piece of work of roughly 800 lines of code or less, and directly solves the problem captured in the milestone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attach everything in the PR.&lt;/strong&gt; We want the agent empowered to go back through our history, understand the decisions made and why, and debug according to spec, not to symptom. Each PR is sized so our pipeline manager can review it against the spec in one pass.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why we cap issues at about 800 lines
&lt;/h2&gt;

&lt;p&gt;Scope is the agent's guardrail. An issue capped at roughly 800 lines is small enough to review in one sitting and specific enough that the agent can't wander.&lt;/p&gt;

&lt;p&gt;It also leaves a trail. When something goes wrong, we can regress to a specific issue and say, "Okay, this is where we go back and fix what we did." The agent can follow that same trail, because the work was scoped into issues from the start.&lt;/p&gt;

&lt;p&gt;Big, fuzzy tickets are where AI-generated code goes to rot -- the agent fills every gap with a guess, and you don't find out which guesses were wrong until something breaks. Small, scoped ones keep the code clean, keep the engineer in charge, and leave a paper trail.&lt;/p&gt;

&lt;h2&gt;
  
  
  The handoff is the leverage
&lt;/h2&gt;

&lt;p&gt;Here's the part that changes the math for small teams. Once the proposal and the spec are approved, and the pseudocode makes sense for the application, I can hand off the implementation completely.&lt;/p&gt;

&lt;p&gt;Is that blind trust in the robot? Not even close. Handing off the build is not about stepping away -- it's about doing the hard thinking up front, so that by the time the coding bot picks up the work, there is nothing left for it to decide. A senior engineer's value was never in the typing. It's in the design.&lt;/p&gt;

&lt;p&gt;The leverage depends on knowing where to hand off and how to hand off well. Hand off too early and the agent makes your decisions for you. Hand off too late and you've done the work twice.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hard truth: review becomes the bottleneck
&lt;/h2&gt;

&lt;p&gt;AI didn't remove the bottleneck. It moved it from writing code to judgment.&lt;/p&gt;

&lt;p&gt;A process like this takes full-time people and all of your attention -- especially when you're also managing a team and have engineers writing code. Designing work for agents takes real energy to get right, and so does handling that work as it comes back through the pipeline.&lt;/p&gt;

&lt;p&gt;Our review is specific. The reviewer reads the pseudocode spec, then measures the Linear issues and the PR against it. Did we deviate from the plan? Did anyone, human or agent, make a decision outside what the spec covered? If so, it's caught before it merges.&lt;/p&gt;

&lt;p&gt;That's how we stay on the same page and keep the codebase clean. It's also why I won't pretend this is free. If your senior people are already at capacity, adding more agents is not going to add output -- it's going to add unreviewed code, and that's a liability you'll be paying down for months.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means if you're building a team
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Small is the default now.&lt;/strong&gt; A handful of strong engineers with agents can cover ground that used to take a much larger team.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hire for judgment.&lt;/strong&gt; When agents do the execution, the people you hire are the decision-makers, not function writers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Invest at the front.&lt;/strong&gt; Proposals and specs aren't bureaucracy. They're how humans stay in control of what gets built.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope ruthlessly.&lt;/strong&gt; Small issues and small PRs are what make agent output reviewable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protect your reviewers.&lt;/strong&gt; Whoever owns the pipeline is your real constraint. Staff and schedule around them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The teams that win won't be the ones with the most bodies in seats. They'll be the ones where every decision has an owner -- and the agents never have to guess. Engineering in 2026 hasn't been easy; this is a new type of difficult that we all have to wrap our arms around to get right.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How is your team handling the handoff between engineers and agents? Tell me what's working, and what isn't, in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>startup</category>
      <category>leadership</category>
      <category>management</category>
      <category>ai</category>
    </item>
    <item>
      <title>Safety in AI: Hallucination Conversation for Ethicists and Software Engineers</title>
      <dc:creator>Jackie Cisneros</dc:creator>
      <pubDate>Thu, 15 Oct 2026 10:07:09 +0000</pubDate>
      <link>https://dev.to/kriegercisneros/safety-in-ai-hallucination-conversation-for-ethicists-and-software-engineers-fd1</link>
      <guid>https://dev.to/kriegercisneros/safety-in-ai-hallucination-conversation-for-ethicists-and-software-engineers-fd1</guid>
      <description>&lt;p&gt;&lt;em&gt;A quick note before you read: I wrote this in 2023, and life got so busy that I didn't open this blog again until today. I came back to publish something about AI and coding teams, and the first thing I saw was this unpublished draft.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I'm sharing it because of how extraordinarily relevant it still is. It's something my team at WhaleHawk is actively combating. Yes, we need to be responsible. No, most of us aren't -- and it's mind-blowing that this problem is still with us. We're leaving it up to our tools to be safe, yet we're still the ones operating the controls. It's an incredibly beautiful dance we find ourselves in, and I wanted to share it.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;We are in a tech turning-point in history: from one day to the next, AI has changed the game in most every software market.  OpenAI's Chat software reached &lt;a href="https://www.battery.com/blog/ai-governance-stack/#:~:text=Just%20two%20months%20after%20its,in%20history%20according%20to%20Reuters." rel="noopener noreferrer"&gt;100 million users within 2 months of deployment&lt;/a&gt;.  This same audience base took Twitter (now X) 2 years to achieve.  AI is everywhere and there is a race to integrate it into every aspect of software on the planet, and I can see why.  Its potential to help humanity and the planet is tremendous:  consider &lt;a href="https://www.linkedin.com/in/azaraskin/" rel="noopener noreferrer"&gt;Aza Raskin's&lt;/a&gt; work to use AI to understand the &lt;a href="https://www.earthspecies.org/" rel="noopener noreferrer"&gt;language of animals&lt;/a&gt;, or using it to develop a way to eliminate micro-plastics from the ocean (&lt;a href="https://theoceancleanup.com/" rel="noopener noreferrer"&gt;Ocean Cleanup&lt;/a&gt; is doing a great job with Macro-Plastics, anyone know of micro-plastic initiatives?).  While we are enthusiastic, it's crucial to remember this tech is new to public access.  We are in uncharted territory and it is wildly exciting.  However, this also means we must proceed with caution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't ask me, I just work here.
&lt;/h2&gt;

&lt;p&gt;I am a software developer, and have used APIs for diffusion models and LLMs to integrate AI into my apps.  The process is relatively easy.  I do not have formal training in math or data analysis, yet just the other day I built out a computer vision model.  It took less than 10 minutes. &lt;/p&gt;

&lt;p&gt;I am telling you this to illustrate the ease of application for this mind-blowing technology.    &lt;/p&gt;

&lt;p&gt;This blog post is mostly opinionated, and addresses one big issue I have encountered with AI deployment: confidently wrong answers.  There is an ocean of safety concerns surrounding AI, but to get the conversation rolling I chose this as an entry point.  &lt;/p&gt;

&lt;p&gt;This post is for anyone in the industry to contribute to, and I want your comments.  I see industry professionals and academic researchers delving into the safety and ethics of AI.  Simultaneously, developers are being asked to integrate AI without a clear roadmap.  I believe there should be a stronger partnership between these groups to improve AI deployment in product development.  &lt;/p&gt;

&lt;h2&gt;
  
  
  AI isn't new.
&lt;/h2&gt;

&lt;p&gt;According to Tristan Harris and Aza Raskin of the Center for Humane Technology, our first contact with AI at massive scale was social media feed algorithms optimized for engagement.  LLMs have been in the works for years, and have finally reached the point of mass deployment.  Hallucinations are a known issue.  Although there have been improvements to decrease their occurrence, it is in the nature of the tech to happen.  An LLM doesn't look up answers; it predicts the most likely next word, one token at a time, based on patterns learned in training. Most likely isn't always correct, and because each word builds on the ones before it, one wrong turn can carry through the rest of the answer.  &lt;/p&gt;

&lt;h2&gt;
  
  
  The AI Race
&lt;/h2&gt;

&lt;p&gt;Hallucinations are a fact, but for much of the industry, the excitement and potential of the tech seem to outweigh this downside.  We know of the Big Dogs who have put a ton of time, money and compute power into developing LLMs: OpenAI and Google, to name two closed-source for-profit companies.  You can use their API to interact with their models.  Open-source platforms like Hugging Face host models (think &lt;a href="https://huggingface.co/blog/falcon" rel="noopener noreferrer"&gt;Falcon&lt;/a&gt;, from the Technology Innovation Institute), and their aim is to democratize the tech so everyone has access.  &lt;/p&gt;

&lt;p&gt;The point is, the race of the Tech Giants continues.  And the race of start-ups that rely on their LLMs is on, too.  &lt;/p&gt;

&lt;h2&gt;
  
  
  What does that mean for us as software developers?
&lt;/h2&gt;

&lt;p&gt;Based on how easy it is to use this tech, I can imagine developers will be asked to start using LLMs in their development process.  I just spoke with a friend who is a software engineer, who is working on a project within his fintech company using external APIs to incorporate AI into payroll.  I anticipate this becoming a standard request for developers.  Upon hearing such news, I find myself astounded.  As software engineers, we know that our job requires learning new tech quickly and often, but this is next level.  To paraphrase &lt;a href="https://www.youtube.com/watch?v=NreFQFKahxw" rel="noopener noreferrer"&gt;Giada Pistilli&lt;/a&gt;, Principal Ethicist at Hugging Face, we are in the Wild Wild West of deployment and are being asked to do something that has never been done before--ever.  &lt;/p&gt;

&lt;h3&gt;
  
  
  SOOO....what IS the problem?
&lt;/h3&gt;

&lt;p&gt;My concern is not with the technical abilities of software engineers and developers: we pride ourselves on quick and efficient technical mastery.  My concern is with the ethics: example, say we have successfully integrated AI into our fintech company to handle all things payroll and the product is deployed: how do we account for the hallucinations that will inevitably happen?  Wrong answers, wrong tax reporting, wrong employee payout.  These presumably will be anomalies, but one bad hiccup is enough to put a company under and cause an individual an unnecessary amount of stress.  &lt;/p&gt;

&lt;p&gt;That example was for a very black-and-white type of situation.  What about the startups looking to use AI in the form of a chatbot therapist (at Boulder Startup Week 2023 I observed a few startups interested in this)?  Now we are getting into the land of unclear distinctions.  As we know, people are not numbers and are very complicated.  What if a chatbot has a hallucination in the face of a human with a very real need for dependable information?  This could cause devastating effects.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Accounting for error: a three-tier step
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Level One: Big Tech Accountability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This one is giant.  We want to trust the products they make  and deploy them to stay competitive, and give the customers our company serves the best and latest tech.  But first and foremost -- always, always do your research.  For example: how does XYZ company who holds the rights to the LLM handle accountability?  Are they projecting a big change in the future which might affect your software?  Read how they are handling hallucinations and user unpredictability.     &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level Two: Startup Accountability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So your startup has decided to use AI?  Great!  What are the safeguards in place to protect your company when a hallucination goes unnoticed and is used in exactly the wrong way?  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level Three: Personal Accountability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As consumers of generative AI content, it is up to us to decide if we will trust the tech or do our own research.  This is tough, because we are buying the software to make a process easier, and we do not expect to need to babysit something that is guaranteed to work.  But for self-preservation's sake, perhaps we should.  Checking our own records is always important, and reaching out to a human for verification when we come across a fishy piece of data is important too.  Informing your customers of what to watch out for and promoting awareness is practicing good transparency.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Solutions for Developers
&lt;/h2&gt;

&lt;p&gt;While I may not have definitive answers for us, I have questions that I hope can get the ball rolling in this conversation.  In this spirit, let's share ideas for how to safely deploy AI tech, to keep consumers and companies alike in the safe zone.   &lt;/p&gt;

&lt;p&gt;First, it is important to recognize that developers are not the only players in the vast field of AI deployment.  Aside from the coding and direct tech development, there are other critical stakeholders involved: project managers, the CTOs, the business stakeholders, the quality assurance testers, devOps team, and users providing feedback as a last line of defense.  Some companies have more, and some have less.  The point is, these roles together create a holistic framework in which responsibility for the success and ethical use of AI is distributed.  As a developer, you have friends in the business who all have the same goal as you.  &lt;/p&gt;

&lt;p&gt;In the case where all these filters fail, and as software developer you are faced with some particularly fishy implementation of AI: is it above your pay grade to question?  As developers, what is our level of responsibility to human ethics in this mad dash to AI?  Creating software is a giant job, and already we juggle a lot.  Practically speaking, do we have the time and energy and knowledge to be aware of the potential pitfalls of the AI software we create? &lt;/p&gt;

&lt;p&gt;Thank you for your interest in this topic.  As a developer deploying AI software or an individual in the field of AI Ethics, I would love to hear from you.  How should a startup deploy AI Software in the context of hallucination accountability?&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd say now (2026)
&lt;/h2&gt;

&lt;p&gt;Three years later, hallucination looks different. Models still invent a line of code or a detail in a summary, but the labs have grown up, the companies building frontier models have grown up, and the harnesses around them have gotten incredibly good.&lt;/p&gt;

&lt;p&gt;The safety issue hasn't gone away -- it's moved to where this post was pointing all along: how we use the tool. That still puts the developer, and the person using the tool, in the seat.&lt;/p&gt;

&lt;p&gt;Think of a chop saw. You don't put your hand under the blade, push it down, and expect to be okay. An LLM agent is a coding tool, a developer on your team, and a thought partner in design, and even three years in, we're still figuring out how to use it well. How do we protect our codebase? How do we protect our product? I live in the applied world, and from where I sit, guardrails and knowing how to use this tool matter more than ever. (Here's how my team handles it: &lt;a href="https://dev.to/kriegercisneros/engineers-decide-agents-execute-why-small-teams-are-the-new-default-b79"&gt;Engineers Decide, Agents Execute&lt;/a&gt;.)&lt;/p&gt;

</description>
      <category>ai</category>
      <category>ethics</category>
      <category>safety</category>
      <category>startup</category>
    </item>
    <item>
      <title>Clean Python: Try/Except</title>
      <dc:creator>Jackie Cisneros</dc:creator>
      <pubDate>Mon, 12 Jun 2023 16:39:29 +0000</pubDate>
      <link>https://dev.to/kriegercisneros/clean-python-tryexcept-1gk4</link>
      <guid>https://dev.to/kriegercisneros/clean-python-tryexcept-1gk4</guid>
      <description>&lt;h2&gt;
  
  
  Exceptional Error Handling in Python
&lt;/h2&gt;

&lt;p&gt;We code in Python because the language has incredible ease of use.  Error handling in Python is no exception.  Try/except is Python's method of handling potentially hazardous input without crashing your program, and returning to the user important information needed in order for the program to proceed.  In this post, we will discuss three specific instances of when try/except is a great fit for error handling:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Cushion potentially erroneous code, such as division by 0 or file access to a file that doesn't exist or an unsupported file type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handle network or server issues that might occur when working with external systems, such as an API endpoint, giving the user workable information to allow the program to function correctly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wrap user input to handle unexpected data types which allows the program to continue to function.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This post will primarily focus on the third point, demonstrating how to handle try/except in the context of unexpected or incompatible user input.&lt;/p&gt;

&lt;p&gt;A word of caution: while try/except blocks can effectively handle problematic input and prevent crashes, they should be used judiciously as they can potentially mask issues that a developer could otherwise address to improve performance.  &lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/HdL82tAZR20?start=831"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Please begin the video at 6:04 to hear Dr. Charles Severance, Clinical Professor of Information at the University of Michigan, explain Python's try/except.  This video is part of a larger collection complied by &lt;a href="https://www.freecodecamp.org/learn/scientific-computing-with-python/python-for-everybody/introduction-why-program"&gt;freeCodeCamp&lt;/a&gt; to help devs learn more about Python.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Cushioning your Program from the Dangers of TypeError
&lt;/h2&gt;

&lt;p&gt;Instead of writing validations on the input code (which we might not have the ability to do for browser or front-end input), we can anticipate when a bad data type might come in.  &lt;/p&gt;

&lt;p&gt;In your programing, you have identified a potentially dangerous line of code.  Let's say your program looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x= userInput
calculate = x+5
print(calculate)

#userInput = 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a very simple program that calculates the value of adding 5 to the user input.  If userInput = 5 as the comment suggests, then output naturally is 10.  &lt;/p&gt;

&lt;p&gt;Now imagine the situation that you are working with a front-end team responsible for writing the user facing functionality.  For some reason, the validations for the front end don't work as anticipated/ aren't written in.  So the user is able to enter input as this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#userInput = 'five'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Python then attempts to calculate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x = 'five'
calculate = x + 5

#TypeError -- Your Python Program Crashes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As Python programers, this is a failure on our part--we did not write in error handling code to keep our program running/ provide valuable feedback to our user in order to allow Python to continue its computing.  This is where we can use try/except.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x = userInput

try:
    calculate = int(x) + 5
    return(calculate)
except:
    return("The input was not a valid number. Please try again.")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This returns some valuable information to our user.  They now know that in order for the program to work, they need to enter a number.  &lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Happening Here?
&lt;/h2&gt;

&lt;p&gt;Python is synchronous by default, meaning it only computes code line by line--it does not "know" what is happening next.  When we write our function inside of a try: statement, it stores in memory something along the lines of : "I am told to carry out the computing of the following block of code.  If it fails, I am not to halt the program and return the error; rather, I am to proceed to the block labeled 'Except:' and execute the code contained within.."  &lt;/p&gt;

&lt;p&gt;In this way, if we can anticipate potentially hazardous input (as in our current situation with user input), and we can effectively allow Python to continue running the program, even with bad input.   &lt;/p&gt;

&lt;p&gt;If you are familiar with if: else: statements, it will come to no surprise to you that Python does not even hit the return statement in the try: block upon failure; instead, it moves into the Except: block and computes ALL of the code nested there.  &lt;/p&gt;

&lt;p&gt;Now the user has been notified of Python's issue in computing data, the program has not crashed, and we have succeeded as Developers by means of effective communication across the stack.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lboW2KN9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://media0.giphy.com/media/MT5UUV1d4CXE2A37Dg/200w.gif%3Fcid%3D6c09b952akmndl5vgpr7t0k7cd9igwsibnc2ivcvefipb8ww%26ep%3Dv1_gifs_search%26rid%3D200w.gif%26ct%3Dg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lboW2KN9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://media0.giphy.com/media/MT5UUV1d4CXE2A37Dg/200w.gif%3Fcid%3D6c09b952akmndl5vgpr7t0k7cd9igwsibnc2ivcvefipb8ww%26ep%3Dv1_gifs_search%26rid%3D200w.gif%26ct%3Dg" alt="Dancing Computer Head" width="200" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up: Empowering Your Programs with Exception Handling
&lt;/h2&gt;

&lt;p&gt;As we've seen, Python's try/except mechanism is an essential tool in the programmer's toolbox. It enhances the robustness and reliability of your code, cushioning against potential pitfalls and keeping your program from crashing even when faced with unpredictable inputs or unexpected events.&lt;/p&gt;

&lt;p&gt;While this post has specifically delved into handling TypeError exceptions arising from user input, remember that the try/except construct is far more versatile. You can and should use it judiciously to handle a variety of exceptional circumstances.&lt;/p&gt;

&lt;p&gt;That being said, it's essential to not fall into the trap of using try/except blocks to mask code inefficiencies or bugs that should be fixed directly. Overusing them can lead to code that's difficult to debug and maintain.n. Always strive to write clean, efficient code and only use exception handling where it's logical and beneficial to do so.&lt;/p&gt;

&lt;p&gt;As Dr. Charles Severance rightly emphasizes, Python's error handling, particularly try/except, can make your code more resilient and user-friendly.  In the grand scheme of things, using try/except appropriately means that you're writing code that respects the user's time and experience. It's a demonstration of good coding ethics and the mark of a responsible developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Continue Your Research
&lt;/h2&gt;

&lt;p&gt;Curious of other ways can you use try/except?  Open up a &lt;a href="https://replit.com/"&gt;Replit environment&lt;/a&gt; and practice coding up some simple programs to further your understanding of the try/except environment.  &lt;/p&gt;

&lt;p&gt;Here is a code example to try with an unsuccessful api endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import requests

try:
    response = requests.get('https://nonexistent-api.com')
    data = response.json()
except:
    print("Error: Unable to connect to the API endpoint.")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is another quick example of attempting to access a file that doesn't exist:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;try:
    with open('non_existent_file.txt', 'r') as f:
        content = f.read()
except FileNotFoundError:
    print("Error: The file does not exist.")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are certain of the error that Python might throw, you can specify the exact error type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;try:
    # some code here
except TypeError:
    # handle TypeError
except ValueError:
    # handle ValueError
# and so on...

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

&lt;/div&gt;



&lt;p&gt;Open up the Replit environment and try modifying the code to see how the program's behavior changes under different circumstances.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Let's keep the conversation moving!
&lt;/h2&gt;

&lt;p&gt;Do you have any additional thoughts on Python error handling, or on maintaining clean Python code in general? Any challenges you've faced, or innovative solutions you've discovered?&lt;/p&gt;

&lt;p&gt;Whether it's a question, a concern, or simply an interesting observation, I'm all ears. So don't hesitate—join the conversation. After all, the best way to learn is together. Let's enhance our coding journey by sharing and discussing our experiences.&lt;/p&gt;

&lt;p&gt;Looking forward to hearing from you!&lt;/p&gt;

</description>
      <category>python</category>
      <category>errors</category>
    </item>
    <item>
      <title>Stable Diffusion XL API: using the API for the beginner dev</title>
      <dc:creator>Jackie Cisneros</dc:creator>
      <pubDate>Mon, 24 Apr 2023 22:49:17 +0000</pubDate>
      <link>https://dev.to/kriegercisneros/stable-diffusion-xl-api-513g</link>
      <guid>https://dev.to/kriegercisneros/stable-diffusion-xl-api-513g</guid>
      <description>&lt;p&gt;If you're interested in the world of AI image generation, you may have heard of Stable Diffusion, a product from &lt;a href="https://stability.ai/" rel="noopener noreferrer"&gt;Stability.AI&lt;/a&gt; and powerful tool for generating unique images based on text or image prompts.  Recently, they released their latest XL version, which is very powerful in terms of prompt engineering to generate beautiful, high quality images.  Along with their newest version, they also have released a rest API for students and developers to use, allowing ease of integration into an app you might be building.  The number one question on my mind looking into this was: do I need a dedicated CPU and a ton of storage on my local machine to use this API?  The answer is nope!  The API allows you access to Stable Diffusion's Models without having to host them on your local machine!  In this blog post, I will share my journey on stumbling across the API, and how I plan to use it in my full-stack project I am building at Flatiron School. &lt;/p&gt;

&lt;p&gt;I use a MacBook Air with an M1 chip.  When I first started looking into Stable Diffusion I downloaded automatic1111 in order to run a simple drawing app to ai image generation program a friend had recommended.  After getting Stable Diffusion's models onto my machine, and the source code for automatic1111 (which I had to integrate SD models into) and running in the background of my machine, I literally had NO STORAGE LEFT to download the paint program!  Determined to find a better way, I came across Google Colab, a sweet service for running python code with Googles amazing CPU's.  StableDiffusion had a Juypter Notebook for their source code, so I could easily open it up in Colab.  It ran great, and fast (maybe took 3-5 seconds to generate an image).  However, I am looking for a way to build an app that has Stable Diffusion integrated in, and using Google Colab seemed like maybe it was possible, but not necessarily practical (if I am wrong on that, please let me know!)&lt;/p&gt;

&lt;p&gt;Feeling relatively defeated yet still optimistic, I kept digging for a solution.  I found an excellent &lt;a href="https://www.youtube.com/watch?v=GA5P9ljQI_g&amp;amp;t=209s" rel="noopener noreferrer"&gt;tutorial&lt;/a&gt; from Skolo Online and she walks you through how to fetch the models from the API using Python.  She says right at the beginning that her computer is slow, so apologies if it takes a minute for the code to process.  I followed her step by step guidance and generated an image from my command line using a prefabricated prompt.  The generation time was a matter of seconds and the image quality is astounding.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F5azk0uha1wcr7sgfew3d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F5azk0uha1wcr7sgfew3d.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Prompt: create a high resolution picture image of a luxary car in a studio setting showcasing its sleek lines and high-end features.  perfect lighting with highlights.&lt;/p&gt;

&lt;p&gt;Note: Yes, I spelled luxury wrong in the prompt I entered for this image.  I wanted to show you exactly what I told it in order to generate the above image.  It can function with typos, what a plus for a not-so-great-speller as myself.   &lt;/p&gt;

&lt;p&gt;If you know python, the simplicity of incorporating these models into your code is astonishingly simple.  If you feel confident running the python script flying solo, I will give you a few steps to get you started.  However, if you want a hand-hold like I did, go ahead to the tutorial above.  It takes about an hour to get through but it is worth it.  &lt;/p&gt;

&lt;p&gt;Step 1:  Go to &lt;a href="https://beta.dreamstudio.ai/generate" rel="noopener noreferrer"&gt;DreamStudio&lt;/a&gt; and make an account.  They start you off with some credits, which equal about 150 images to generate.  Play with the software a little, this is the FUN PART!  Get familiar with the left tool-bar on the page: there is a prompt section where you engineer a text prompt the ai uses to generate it's images. (Tip, if you want an easy way to make a prompt, head to chatGPT and ask it to engineer a creative prompt for text to image ai generation.)&lt;/p&gt;

&lt;p&gt;Take a look at the advanced settings: there is something called steps; the higher the steps, the better the image quality, the higher the cost to run the program.  This is the downside to this api: you need to pay for it.  But in reality, it is much cheaper than others, like DALL-E, coming in at about $10 for around 1000 images.  If you had the CPU and memory to download stable diffusion and use the models directly on your machine, that would be the way to go to get SD "for free".  However, if you are like me with a limited machine, this is the price we pay to play around with the tech.  Not bad.  (Note, I am unsure if SDXL, the latest model we are talking about here, is available for download.  I ended up playing with v1.5 (which produces significantly less quality images) on Google Colab.  Please let me know if XL is available and you have tried it either locally or with Colab.)&lt;/p&gt;

&lt;p&gt;There is also a dropdown called Model in the advanced setting.  These are the different versions of SD that are available.  You can play around and test the same prompt in different models; do the results differ? &lt;/p&gt;

&lt;p&gt;Step 2: In your personal account info in DreamStudio, there is an API key autogenerated for you.  Click on the documentation tab below that and it will take you where you need to find the code to get you started.  &lt;/p&gt;

&lt;p&gt;Step 3: Here is a link to the &lt;a href="https://platform.stability.ai/docs/getting-started" rel="noopener noreferrer"&gt;getting started&lt;/a&gt; page for Stability.Ai's REST API.  It is very comprehensive.  They basically provide the python code necessary for gaining access to the API.  Here is my source code that I ended up with, plus I have a config.py file that contains my API key, which I will then store in a dotenv file and then to a .gitignore as I build out my project.  I know I need this often, so remember guys to not share your API code with the world.  Ok, source code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import os
import requests
import config
import base64
import json


api_host = 'https://api.stability.ai'
api_key = config.api_key
engine_id='stable-diffusion-xl-beta-v2-2-2'

if api_key is None:
    raise Exception("Missing Stability API key.")

def getModelList():
    url = f"{api_host}/v1/engines/list"
    response = requests.get(url, headers={
        "Authorization": f"Bearer {api_key}"
    })
    if response.status_code != 200:
        raise Exception("Non-200 response: " + str(response.text))
    # Do something with the payload...
    payload = response.json()
    print(payload)

def generateStableDiffusionImage(prompt, height, width, steps):

    url= f"{api_host}/v1/generation/{engine_id}/text-to-image"
    headers = {
            "Content-Type": "application/json",
            "Accept": "application/json",
            "Authorization": f"Bearer {api_key}"
    }
    payload={}
    payload['text_prompts'] = [{"text": f"{prompt}"}]
    payload['cfg_scale'] = 7
    payload['clip_guidance_preset'] = 'FAST_BLUE'
    payload['height'] = height
    payload['width'] = width
    payload['samples'] = 1
    payload['steps'] = steps

    response = requests.post(url,headers=headers,json=payload)

    #processing the response
    if response.status_code != 200:
        raise Exception("Non-200 response: " + str(response.text))

    data = response.json()
    # print(data)

    for i, image in enumerate(data["artifacts"]):
        with open(f"v1_txt2img_{i}.png", "wb") as f:
            f.write(base64.b64decode(image["base64"]))

for i, image in enumerate(data["artifacts"]):
    with open(f"v1_txt2img_{i}.png", "wb") as f:
        f.write(base64.b64decode(image["base64"]))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I ran my code in the python shell from my base directory, feeding the shell my code line by line, then establishing the variables of prompt, width (512, or whatever dimensions you desire), height (512) and steps (50, remember, more steps, better images and more expensive).   Note that the engine_id is the current model you would like to use (I want to use the beta model with XL) and the very few last lines of code are responsible for taking the image as a string (it is a really, really, really long string) and converting it into a PNG image.  My image saved directly in the base code in my directory, and I was able to see it that way.  &lt;/p&gt;

&lt;p&gt;In conclusion, I am so excited to explore this API more and integrate it into my app.  Not exactly sure what I will make with it, but the possibilities are extensive!  Just know that you can implement this api and use the models from Stable Diffusion in order to have a wonderful image generator inside you app.  I hope this post was a spark to a fire that I have found and you feel inspired by the accessibility of this API.  Think of different ways you might be able to use this tech: a simple text to image generator would be sweet, but what if you could use python to make a simple drawing, and as you sketch the API recognizes your sketch (plus a prompt) and generates an AI image?  What if you use their image to image software and create a totally new image with a fed prompt?  There is also an in-painting option; what type of image could you describe with those algorithms?  &lt;/p&gt;

&lt;p&gt;So happy you were here, if there is anything you think I should know let me know and most of all, Happy Coding!      &lt;/p&gt;

</description>
    </item>
    <item>
      <title>SQL fundamentals: understanding Join Tables</title>
      <dc:creator>Jackie Cisneros</dc:creator>
      <pubDate>Sat, 01 Apr 2023 18:57:25 +0000</pubDate>
      <link>https://dev.to/kriegercisneros/sql-fundamentals-understanding-join-tables-1jf6</link>
      <guid>https://dev.to/kriegercisneros/sql-fundamentals-understanding-join-tables-1jf6</guid>
      <description>&lt;p&gt;SQL (structured query language) is the language of databases.  On its own, it is a very powerful tool, and as a full stack dev, it is super important we understand how this language works.  In this blog post, I am going to discuss SQL join tables in depth: what they are, why they are necessary, the different types of joins you can perform, and how to use them.  This article is for you if you are beginning your journey with SQL and have a working knowledge of the language, including some basic syntax.  Difficulty level: intermediate beginner.  &lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Join Table? Why wouldn't I just make a new table?
&lt;/h2&gt;

&lt;p&gt;SQL join tables are used to associate records from different tables; think of them as linking tables.  Making a new table to represent a relationship would work, however, you would need to make a new table for each instance that is created. &lt;br&gt;
 If you intend to grow your db, this would become unmanageable very quickly.  So a join table allows you to create a many-to-many relationship between two or more tables in an efficient way.&lt;/p&gt;
&lt;h3&gt;
  
  
  Wait...what is a many-to-many relationship again?
&lt;/h3&gt;

&lt;p&gt;A many-to-many relationship is where multiple records in one table can be associated with multiple records in another table.&lt;/p&gt;

&lt;p&gt;For example, imagine you have a chatbot with two db tables: a "statements" table that collects all the training data for your bot, and "tag" table, which has a collection of helper tags with an associated id. A statement can have multiple tags, and a tag can have multiple statements; this helps the bot classify statements and make searching for an appropriate response easier, creating a many-to-many relationship between the two tables.&lt;/p&gt;

&lt;p&gt;In order to represent this relationship in SQL, you would need to use a third table, a join table, that sits between the two.  Let's call it "tag_association". This table would have two columns of foreign keys that reference the primary keys of both the "statements" and "tag" tables.  The join table creates our necessary many-to-many relationship and maintains the referential integrity of "statement" and "tag", simultaneously avoiding data duplication.  Also, it is self-scaling, which means as your data updates, so does your relationship model.  &lt;/p&gt;
&lt;h2&gt;
  
  
  The Importance of Relationships
&lt;/h2&gt;

&lt;p&gt;SQL is a relational database language, which means data is organized into tables with rows and columns.  Each row represents a specific type of data, and each column is an instance of that data.  Naturally, the process of querying the databases heavily relies on relationships: different types of joins in SQL can represent different types of relationships between tables in a database. There are several types of joins in SQL, including (but not entirely limited to):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inner Join&lt;/strong&gt;: This type of join returns only the rows that have matching values in both tables being joined. An inner join can be used to represent a &lt;strong&gt;one-to-many&lt;/strong&gt; or &lt;strong&gt;many-to-many&lt;/strong&gt; relationship between two tables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Left Outer Join&lt;/strong&gt;: This type of join returns all the rows from the left table and matching rows from the right table. If there is no matching row in the right table, then the result will contain NULL values for the right table columns. A left outer join can be used to represent a &lt;strong&gt;one-to-many relationship&lt;/strong&gt;, where the left table contains the primary key and the right table contains the foreign key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Right Outer Join&lt;/strong&gt;: This type of join returns all the rows from the right table and matching rows from the left table. If there is no matching row in the left table, then the result will contain NULL values for the left table columns. A right outer join can be used to represent a &lt;strong&gt;one-to-many relationship&lt;/strong&gt;, where the right table contains the primary key and the left table contains the foreign key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full Outer Join&lt;/strong&gt;: This type of join returns all the rows from both tables being joined, with NULL values for any unmatched columns. A full outer join can be used to represent a &lt;strong&gt;many-to-many&lt;/strong&gt; relationship between two tables.&lt;/p&gt;
&lt;h2&gt;
  
  
  WHEW!  That is a lot of information. Want to practice?
&lt;/h2&gt;

&lt;p&gt;Let's go ahead a practice creating some join tables using &lt;a href="https://www.mycompiler.io/new/sql"&gt;MyComplier:&lt;/a&gt;.  We are going to use some examples from W3School's &lt;a href="https://www.w3schools.com/sql/sql_join.asp"&gt;SQL program&lt;/a&gt; (which is extensive and contains a lot of helpful information in learning the language).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- create a table
CREATE TABLE orders (
  OrderID INTEGER PRIMARY KEY,
  CustomerID INTEGER,
  OrderDate TEXT NOT NULL
);
-- insert some values
INSERT INTO orders VALUES (10308, 2, '1996-09-18');
INSERT INTO orders VALUES (10309, 39, '1996-09-19');
INSERT INTO orders VALUES (10310, 77, '1996-09-20');
-- fetch some values
SELECT * FROM orders WHERE CustomerID = 2;

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

&lt;/div&gt;



&lt;p&gt;Go ahead copy and paste this code into the complier link above (the link will take you to the main page, just click on the "Run Your SQL Code" button, it is giant and yellow, can't miss it).  You can see we are creating a table called orders which has columns of OrderID, CustomerId and OrderDate.  We are then inserting values into the table as particular instance orders.   Then we are retrieving, or fetching an entire instance (annotated by the *) from our table where customerID matches 2.  Hit the green run play button at the top and see what happens.  &lt;/p&gt;

&lt;p&gt;Now we are going to create another table, customers and populate with some data.  You can copy and paste the code below, or type it yourself to improve muscle memory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- create another table
CREATE TABLE customers (
  CustomerID INTEGER PRIMARY KEY,
  CustomerName TEXT NOT NULL, 
  ContactName TEXT NOT NULL, 
  Country TEXT NOT NULL
);
-- insert some values
INSERT INTO customers VALUES (1, 'Alfreds Futterkiste', 'Maria Anders', 'Germany');
INSERT INTO customers VALUES (2, 'Ana Trujillo Emparedados y helados', 'Ana Trujillo', 'Mexico');
INSERT INTO customers VALUES (3, 'Antonio Moreno Taquería', 'Antonio Moreno', 'Mexico');
-- fetch some values
SELECT * FROM customers WHERE CustomerID = 2;

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

&lt;/div&gt;



&lt;p&gt;Hitting run, you will see that we are retuning the instance from customers where the id is 2.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's write for an Inner Join Table.
&lt;/h2&gt;

&lt;p&gt;Great!  Now it time to test how we can join these tables together.  Comment out the two SELECT commands, and write the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate
FROM Orders
INNER JOIN Customers ON Orders.CustomerID=Customers.CustomerID;

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

&lt;/div&gt;



&lt;p&gt;Before you press run, can you guess what the new table will look like?  Take a minute to study the above code and take an educated guess at what type of relationship we are creating.  We see we are selecting from our both of our tables: orderID from orders, customerName from customers, and orderDate from orders.  So there will be three columns of organized data.&lt;/p&gt;

&lt;p&gt;The next line of code specifies the first table we are joining, orders.  The next line, INNER JOIN Customers specifies that an inner join should be performed with the Customers table.  ON Orders.CustomerID=Customers.CustomerID specifies the join condition, which is that the CustomerID column in the Orders table must match the CustomerID column in the Customers table.&lt;/p&gt;

&lt;p&gt;Can you assume which is the instance that will be created?  Run the code to see if you're right!&lt;/p&gt;

&lt;p&gt;You can see that the only instance that is created is the one where the customer ID is in both tables, the id of 2.  This is a very small example, so can you imagine ways to scale the table to see more instances in our join table?&lt;/p&gt;

&lt;h2&gt;
  
  
  Left Join Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT Customers.CustomerName, Orders.OrderID
FROM Customers
LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID
ORDER BY Customers.CustomerName;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we may recall, a left join returns all the rows of the left table (in this instance customers) and only the matching rows of the right table (the orderId where customer.customerId=orders.customerID).  There is only one occurrence of this in our tables, the order 10308, so the join table contains only one orderID.  The other spaces for this may return Null or empty.  So we see all three customer names printed, but only Anna Trujillo's id printed.  &lt;/p&gt;

&lt;h2&gt;
  
  
  How to use the join tables within my application?
&lt;/h2&gt;

&lt;p&gt;Join tables are used when we have many-to-many or a many-through relationship.  For instance, say we have db that has coffee drinks and coffee shops as tables.  We also have a customer tables that allows you to make an account, say for placing an online order.  A join table (orders) allows us to make a relationship of orders, connecting one order with a customer_id, a drink_id and a shop_id.  This way, the system has knowledge base of who ordered what and from where.  &lt;/p&gt;

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

&lt;p&gt;SQL is a beast of a language, and if you would like to dive into it, you could very well become a SQL master.  However, with the benefits of abstraction and using tools like SQLAlchemy, our databases become easier to write.  Understanding depth of the SQL language to write DB's can help us in our abstraction have a better understanding of what is happening in our program under the hood.  It can be dense, but once you emerge from the darkest forest, the sun shines brighter!  &lt;/p&gt;

&lt;p&gt;If there is anything that I missed or that you think I ought to have included in this blog post, please let me know.  And as always, Happy Coding!&lt;/p&gt;

</description>
      <category>fullstack</category>
      <category>sql</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Building Graphics with Code: Zdog and JS, a quick overview</title>
      <dc:creator>Jackie Cisneros</dc:creator>
      <pubDate>Sat, 11 Mar 2023 02:34:41 +0000</pubDate>
      <link>https://dev.to/kriegercisneros/building-graphics-with-code-zdog-and-js-a-quick-overview-37gb</link>
      <guid>https://dev.to/kriegercisneros/building-graphics-with-code-zdog-and-js-a-quick-overview-37gb</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AKIh8yeP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mg99ibkd1zasmhklw07b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AKIh8yeP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mg99ibkd1zasmhklw07b.png" alt="Image description" width="400" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are some amazing JS engines out there designed to make building graphics more accessible.  As an amateur visual artist/ growing developer, I would love to learn how to build my own static and animated graphics.  After a quick google search, I found Zdog, an easy to use lightweight JS engine that renders 'pseudo' 3D images.  My post here is to share with you my initial thoughts on the user-friendliness of engine, a quick guide to get going with it's syntax and features where we code together a sphere and a cube rotating through space, and an overall 'general implementation' idea for when this engine would be appropriate for use.     &lt;/p&gt;

&lt;h2&gt;
  
  
  Wait, backup.  What does 'pseudo 3D image' mean?
&lt;/h2&gt;

&lt;p&gt;It means 3D in motion, and 2D when static.  The power behind zdog is this: you transmute circles and squares on an x,y,z axis.  Meaning, you target what direction you want your shape to grow or shrink.  When a screenshot is taken, like in the photo above, the image looks 2D.  However, when the animation is spun, you can see the dimensionality behind the object.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So why use zdog?&lt;/strong&gt;     &lt;/p&gt;

&lt;p&gt;I am going to go a little out of order and get this out of the way right off the bat: If you want to make a game, this isn't the JS engine for you.  It doesn't come with the right elements for a game (such as collision detection).  Apparently you can modify it manually, but there are probably better engines out there to do your dirty work.  (Actually, you might want to bark up the Python tree for that one...more on that later.)  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;USE ZDOG IF YOU WANT AN ISOLATED 3D IMAGE WITH SIMPLE ANIMATION CAPACITY&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;Imagine you want to spin your company's logo on the Home Page and make it have depth.  Or you want your 404 Not Found Page to have a bit of artistic fancy so users aren't AS disappointed if their app fails to load.  Zdog can help you do these things, and of course, much more depending on where your imagination can take you.     &lt;/p&gt;

&lt;p&gt;Here is a sweet animation TienCoffee made.  It is a &lt;a href="https://codepen.io/tiencoffee/pen/OePgEg"&gt;model of a solar system&lt;/a&gt;.  Just imagine how helpful this would be for 1st graders trying to wrap their heads around how the earth moves around the sun.  Or if a coder made a model of a molecule and instead of the flat image in a text book, students can &lt;em&gt;see&lt;/em&gt; how it connects by simply spinning the image.  &lt;/p&gt;

&lt;p&gt;Curious to get started?  So am I.  Let's do a little Zdog challenge together.  Dave DeSandro (the creator of Zdog), made this codepen &lt;a href="https://codepen.io/desandro/pen/RmLyyq"&gt;template&lt;/a&gt; for new users to play with.  Click on it and let's make some shapes!&lt;/p&gt;

&lt;h2&gt;
  
  
  We are going to make a cube and sphere rotating around an invisible point space.
&lt;/h2&gt;

&lt;p&gt;Don't worry, you can do this.  If you know basic JS, Zdog's API is easy enough to grasp.  And the results are so fun.  I have been coding in JS for less than a year, and the learning curve here is realistically around a few hours to get a hang of the syntax.  (That is not speaking to how long it would take in real life to create a product to deploy, but that is beyond our scope today.) Ok, without further delay, let's get started.  &lt;/p&gt;

&lt;p&gt;Do you see a purple circle inside of a cream box?  Great!  Off to a good start.  Let's make this circle completely solid, take out the diameter and change the stroke to 12.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new Zdog.Ellipse({
  addTo: illo,
  stroke: 12,
  fill: true,
  color: '#636',
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whoops!  It is super tiny!  No worries, just go up to where we are setting illo and change make a new key/value pair of &lt;code&gt;zoom: 8&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;Now, let's take a quick minute to look at what's going on here.  Ellipse is a shape class in Zdog.  We are adding this ellipse shape (with the defined key value pairs that create it's image) to our page with &lt;code&gt;addTo: illo&lt;/code&gt;.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Wait, what is illo?
&lt;/h2&gt;

&lt;p&gt;Back in our codpen file, if we scroll up to the top of the JS file, we will see this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let illo = new Zdog.Illustration({
  // set canvas with selector
  element: '.zdog-canvas',
zoom: 8
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's say this out loud together to practice technical communication:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We are declaring a variable illo and setting it equal to a new object (using JS's &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new"&gt;new operator&lt;/a&gt;) calling Zdog's Illustration class and setting canvas with our css selector, '.zdog-canvas'.  Zoom will be set to 8.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Great!  But &lt;strong&gt;what is Illustration?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Illustration is a "high level" class in Zdog api that basically attaches your creation to your  HTML element.  All of your subsequent shape creations in Zdog will have reference to this Illustration class.  This is like our fixed point for all the rotations to circle around.   &lt;/p&gt;

&lt;h2&gt;
  
  
  Moving on to Animation!
&lt;/h2&gt;

&lt;p&gt;Go ahead and copy this code to the bottom of your JS file, right before &lt;code&gt;illo.updateRenderGraph();&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function animate() {
  illo.rotate.x += 0.05;
  illo.updateRenderGraph();
  requestAnimationFrame( animate );
}
animate();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Does your codepen look like this?  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AsdSCQHz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cdy3ebyvcuts7v8swvd1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AsdSCQHz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cdy3ebyvcuts7v8swvd1.png" alt="Image description" width="528" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sweet!  You should see it spinning too.  Well, actually, because we changed its' properties, it will look more like a squishing ball.  Study the code for a minute; do you see that we declare it to rotate on the x-axis?  What if you changed that to y?  Have some fun playing with this.   &lt;/p&gt;

&lt;p&gt;Let's add another class of Rect (short for rectangle) right below our Ellipse.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new Zdog.Rect({
  addTo: illo,
  width: 8,
  height: 8
  stroke: 12,
  color: '#E62',
  fill: true
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Right now it should look like a breathing rectangle.  Why is that?  Where did the ball go?  It is still there, it is simply hidden behind the rectangle.  We can add &lt;code&gt;translate: { z: -10 },&lt;/code&gt; to the key/values of this Rect object.  This will push the shape back on the page (along the z axis) by 10 (whatever 10 is distinguished by in Zdog; I would need to look at their API to really know).  Go ahead and add x and y values to translate on the rectangle, and do the same with the ellipse.  What happens?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new Zdog.Ellipse({
  addTo: illo,
  stroke: 12,
  color: '#636',
  translate: { x: 5, z:10, y:-5 },
  fill:true
});

new Zdog.Rect({
  addTo: illo,
  width: 8,
  height: 8,
  translate: { x: -5, z:-10, y:5 },
  stroke: 12,
  color: '#E62',
  fill: true
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See if you can get the circle to land on the rectangle.  Manipulating what part of these objects will get that job done?  Is there another key we need to add in order to accomplish our task?   &lt;/p&gt;

&lt;h2&gt;
  
  
  Drag and Rotate
&lt;/h2&gt;

&lt;p&gt;Ok, now the fun part.  Add this code to your illo variable declaration: &lt;br&gt;
&lt;code&gt;dragRotate: true,&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, add this above it :&lt;br&gt;
&lt;code&gt;let isSpinning = true;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, add a function definition to your illo object: &lt;code&gt;onDragStart: function() {&lt;br&gt;
    isSpinning = false;&lt;br&gt;
  },&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Finally, update your animate function to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function animate() {
  if ( isSpinning ) {
    illo.rotate.y += 0.03;
  }
  illo.updateRenderGraph();
  requestAnimationFrame( animate );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great!  Did you break it?  I sure did.  Let's go through what the entire js file should look like at this point:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
let isSpinning = true;

const illo = new Zdog.Illustration({
  element: '.zdog-canvas',
  zoom: 6,  
  dragRotate:true, 
  onDragStart: function() {
    isSpinning = false;
  },
});

new Zdog.Ellipse({
  addTo: illo,
  stroke: 12,
  color: '#636',
  translate: { x: 5, z:10, y:-5 },
  fill:true
});
new Zdog.Rect({
  addTo: illo,
  width: 8,
  height: 8,
  translate: { x: -5, z:-10, y:5 },
  stroke: 12,
  color: '#E62',
  fill: true
});

function animate() {
  if ( isSpinning ) {
    illo.rotate.y += 0.03;
  }
  illo.updateRenderGraph();
  requestAnimationFrame( animate );
}
animate();

illo.updateRenderGraph();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Awesome!  Now you can stop the image, and spin it around using your mouse. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mwOl53CK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ar0c106yzs41k1onvf3b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mwOl53CK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ar0c106yzs41k1onvf3b.png" alt="Image description" width="528" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Accomplishment: you know the basics of creating shapes and starting animations, congrats!  The next step is going to the website and using the tools we explored here to &lt;a href="https://zzz.dog/modeling"&gt;model images&lt;/a&gt;.  Doesn't that look fun?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S-TlnY1U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vm4hjb5s49v98a43qcm6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S-TlnY1U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vm4hjb5s49v98a43qcm6.png" alt="Image description" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TakeAways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Zdog's API uses classes (Illustration, Ellipse, and Rect) to make shapes and fix them to your HTML using .&lt;/li&gt;
&lt;li&gt;Each class renders an object based on coder's choice of color, size and other mutations.&lt;/li&gt;
&lt;li&gt;Creating animations is a matter of making functions that call illo.rotate (our fixed point) on a particular axis at a particular speed.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you are excited about the potentials for Zdog, you can jump right into some projects DeSandro lists on &lt;a href="https://zzz.dog/"&gt;Zdog's website &lt;/a&gt; and reverse engineer them to learn the basics.  Or, you can go back to the codepen we worked on and try adding another shape, or even making a line (what the heck would that look like?). Have fun and happy coding!    &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>zdog</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Recursion in JS for Beginners, avoiding an infinite loop</title>
      <dc:creator>Jackie Cisneros</dc:creator>
      <pubDate>Sun, 19 Feb 2023 23:06:09 +0000</pubDate>
      <link>https://dev.to/kriegercisneros/recursion-in-js-for-beginners-avoiding-and-infinite-loop-17bh</link>
      <guid>https://dev.to/kriegercisneros/recursion-in-js-for-beginners-avoiding-and-infinite-loop-17bh</guid>
      <description>&lt;p&gt;Recursion is tricky.  First of all, as a beginner, we are just learning about functions and what they do.  We feel happy with our progress until a teacher, youTuber or blog post helpfully drops recursion on us and we are floored: a function that calls itself? For lack of a better word, whaaaaa...???&lt;/p&gt;

&lt;p&gt;In this blog post, I will address a few questions that I encountered when I first learned about recursion, mainly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What &lt;em&gt;is&lt;/em&gt; Recursion?&lt;/li&gt;
&lt;li&gt;How does it work?&lt;/li&gt;
&lt;li&gt;Why should I use it?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;**Spoiler; the last question I am still answering for myself.  &lt;/p&gt;

&lt;h2&gt;
  
  
  What &lt;em&gt;is&lt;/em&gt; Recursion?
&lt;/h2&gt;

&lt;p&gt;A recursive function is one that calls itself.  It may look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function recursionFunction(num){
  if(num &amp;gt; 0){
    console.log(num)
    recursionFunction(num-1);
  };
};
recursionFunction(10)

//Prints 10 9 8 7 6 5 4 3 2 1 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Study the code above.  Really look at what each element is doing; look at the curly braces, the parenthesis, the name of the function.  Try to understand what the function is doing and describe it out loud to yourself.  You can even open it up it this &lt;a href="https://replit.com/languages/javascript"&gt;JavaScript REPL&lt;/a&gt; (make sure you are in node.js) and plug in the code to the left side and hit run.    &lt;/p&gt;

&lt;p&gt;Let's go through line-by-line, performing how JS performs, to better understand this process. &lt;/p&gt;

&lt;h3&gt;
  
  
  Line one: the function declaration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function recursionFunction(num)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's say out loud what this is saying: &lt;/p&gt;

&lt;p&gt;"We are declaring a function called recursiveFunction that has one parameter, num.  &lt;/p&gt;

&lt;p&gt;Wonderful!  Great technical communication.  Now, JS stores this function (which is everything inside of the curly braces) in global memory, to be accessed when we call the function later in our program.  The program moves on to the next line of code:&lt;/p&gt;

&lt;h3&gt;
  
  
  The Call to recursionFunction
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;recursionFunction(10)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the call for recursionFunction to execute with the passed in argument of 10.  Since JS has this info stored in global memory, it can pull recursionFunction up again (remember, JS is synchronous, so it will not move up lines of code to access the function again; it will look for the stored function declaration in global memory.).&lt;/p&gt;

&lt;h3&gt;
  
  
  The Body of the Function
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  if(num &amp;gt; 0)

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

&lt;/div&gt;



&lt;p&gt;Now, JS has entered a local execution context for the call to recursionFunction, and in the local memory, we are storing the argument at 10 (so currently, num = 10).  In the next line of code, JS is reading "if 10 is greater than 0".  This is called our "base case" and is so very important in recursion (more on this later).  What that means is that, if this is true, go ahead and do the body of the "if" statement.  &lt;/p&gt;

&lt;p&gt;Is the if statement true or false right now?&lt;/p&gt;

&lt;p&gt;That's right!  It is totally true.  Let's move on to the next line of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    console.log(num)
    recursionFunction(num-1);
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JS will then print num, which it has stored in this local memory as 10.  Then, it will call recursionFunction again, but this time, the argument is (num -1).  What is num?  We have it stored in the local memory for the first call of recursionFunction; it is 10.  So now, JS will open another execution context, on top of the first one, storing num-1, or 10-1, as the definition of num.  &lt;/p&gt;

&lt;p&gt;What do you think will happen next?  We have a second execution context open, and num = 9.  I think we will go back up to the stored function declaration of recursionFunction (which is stored where?  In the Global Memory, meaning we can call it over and over again no matter where in our call stack we are) and use our second argument in place of our parameter num.  &lt;/p&gt;

&lt;p&gt;First we hit our base case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(num&amp;gt;0)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is that true?  Is 9 &amp;gt; 0?  Absolutely, so we can move into the body of our base case and execute the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    console.log(num)
    recursionFunction(num-1);
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we print 9, and call recursionFunction passing in num (which is 9) minus 1.  Now we open up yet another execution context, with our new argument at 8, and do everything all over again.  &lt;/p&gt;

&lt;p&gt;Now let's pretend we did all that, and now num = 0.  We currently have 10 execution contexts stacked on top of each other (this is called the call stack).  JS hits our base case, if num &amp;gt; 0... is it?  Not anymore!  We have finally hit the base case for this recursion.  Our if statement evaluates to false, so JS exits the current execution context (which is recursionFunction(0)), enters the next one, sees there is nothing more to do there, and keeps going down the line until we are back in the Global Execution Context.  Whew!!!&lt;/p&gt;

&lt;h3&gt;
  
  
  Base Case
&lt;/h3&gt;

&lt;p&gt;As promised, let's talk a little more about our base case and code composition.  What would happen to our recursive function if we moved the call to recursionFunction &lt;em&gt;outside&lt;/em&gt; of the if statement body?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function recursionFunction(num){
  if(num &amp;gt; 0){
    console.log(num)
  };
  recursionFunction(num-1);
};
recursionFunction(10)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is a simple change, we moved the code one line down.  But go ahead and open up the REPL, see what happens when you plug this variation in. &lt;/p&gt;

&lt;p&gt;Something like this will appear:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10
9
8
7
6
5
4
3
2
1
RangeError: Maximum call stack size exceeded
    at recursionFunction (/home/runner/tf3w0jc6kne/index.js:1:27)
    at recursionFunction (/home/runner/tf3w0jc6kne/index.js:5:3)
    at recursionFunction (/home/runner/tf3w0jc6kne/index.js:5:3)
    at recursionFunction (/home/runner/tf3w0jc6kne/index.js:5:3)
    at recursionFunction (/home/runner/tf3w0jc6kne/index.js:5:3)
    at recursionFunction (/home/runner/tf3w0jc6kne/index.js:5:3)
    at recursionFunction (/home/runner/tf3w0jc6kne/index.js:5:3)
    at recursionFunction (/home/runner/tf3w0jc6kne/index.js:5:3)
    at recursionFunction (/home/runner/tf3w0jc6kne/index.js:5:3)  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ouch, that is painful!  See where it says &lt;/p&gt;

&lt;p&gt;"Maximum call stack size exceeded&lt;br&gt;
    at recursionFunction"?  &lt;/p&gt;

&lt;p&gt;JavaScript is throwing us this error because we are recursively calling recursionFunction outside of our base case declaration (the "if" statement right at the beginning).  &lt;/p&gt;
&lt;h2&gt;
  
  
  WAIT, WAIT...WHAT???
&lt;/h2&gt;

&lt;p&gt;Think about it like this: we are calling a function from the body of itself.  Which means we are inherently setting up the stage for an infinite loop.  If we don't tell JS, "Hey wait!  Stop running this loop when you hit zero.  You don't need to go past zero and into the forever underworld of negative numbers.  We good at 0.", then it doesn't know to stop.  JS is performative and does not make judgement calls; it will simply go on doing what we ask of it until our memory doesn't allow it to happen any more.  And then our program crashes.      &lt;/p&gt;

&lt;p&gt;To avoid that, when we write our recursions, let's make sure that our recursive call is within the code block where our base case has power.  &lt;/p&gt;
&lt;h3&gt;
  
  
  Space and Time Complexity
&lt;/h3&gt;

&lt;p&gt;That was a simple demo for what recursion can do for you as a programmer.  It can make life easier for you, but it does take up more memory.  Remember the call stack we talked about?  Because recursive functions need to maintain this stack when they are being called, they use more space than an iteration would.  They also have a slower processing rate.&lt;/p&gt;
&lt;h2&gt;
  
  
  HOLD ON: if recursion is slower and takes more space to process than an iteration...
&lt;/h2&gt;

&lt;p&gt;...why wouldn't we just use an iteration, like a for loop or a forEach()?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const nums = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1];

function printNums(number){
  for(let i = 0; i&amp;lt;number.length; i++){
    console.log(number[i])
  }
}
printNums(nums)
//prints 10 9 8 7 6 5 4 3 2 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In many &lt;a href="https://www.freecodecamp.org/news/imperative-vs-declarative-programming-difference/"&gt;imperative&lt;/a&gt; situations, iteration is favored way above recursion.  However, there are some specific situations where the code to write an iteration is too complex, and recursion is necessary.  One of these situations includes &lt;a href="https://www.educative.io/blog/tree-traversal-algorithms"&gt;Tree Traversal&lt;/a&gt;.  Click on the link if you are feel confident with recursion and are looking for some meaty methods for solving algorithms.  If algorithms are a new idea and you feel like a firehose just blasted you with info, take a breath, and lets go back to the recursive code we started with and practice our technical communication:&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Communication
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function recursionFunction(num){
  if(num &amp;gt; 0){
    console.log(num)
    recursionFunction(num-1);
  };
};
recursionFunction(10)

//Prints 10 9 8 7 6 5 4 3 2 1 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;We are declaring a function called recursionFunction that accepts a parameter, num.  The body of the function first establishes a base case:  if num is greater than zero, print num.  Then call recursionFunction again, passing in the argument of num minus one.  We then exit the body of our base case, and exit the body of our function, and call recursionFunction passing in the integer ten as our argument.  This begins the recursion process.   &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Great job!  You just tackled one very tricky topic in your path to understand JavaScript.  Give yourself a pat on the back, and go celebrate your win.  &lt;/p&gt;

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

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>recursion</category>
    </item>
    <item>
      <title>.reduce() for the beginner</title>
      <dc:creator>Jackie Cisneros</dc:creator>
      <pubDate>Thu, 16 Feb 2023 23:09:13 +0000</pubDate>
      <link>https://dev.to/kriegercisneros/reduce-for-the-beginner-222k</link>
      <guid>https://dev.to/kriegercisneros/reduce-for-the-beginner-222k</guid>
      <description>&lt;p&gt;If you are reading this post, you are at the point in your coding journey where you want to start exploring iterator techniques outside of a for loop.  You are in a great spot, because .reduce() will take a callBack function (supplied by you, the Software Engineer) and return a single value without necessarily "looping" through your entire array.  Here is the code we will be working with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let arrayOne = [7, 8, 3];

let arraySum = arrayOne.reduce(function(a, b){
return (a + b)
}, 2);

console.log(arraySum) // displays 20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Getting to Know the Code
&lt;/h3&gt;

&lt;p&gt;Take a minute right now to study the code above.  Look at the parenthesis, the curly braces, the commas.  Try to understand what the language is actually saying, and say it out loud.  At the end of this post, we will say out loud together, in human words, what the code is doing. This will greatly improve your skill in technical communication.      &lt;/p&gt;

&lt;p&gt;In the above example, reduce accepts two parameters: a callBack function (which has two parameters in this example, a and b; it can actually have up to 4, but that is beyond our scope today), and an optional "initial value".&lt;/p&gt;

&lt;p&gt;We know that in JavaScript, we have to pass in arguments when we call our functions.  So why don't we see arguments here?  That is a great question!  And that is why reduce is so awesome and helpful. Reduce is a built-in method, which means JavaScript knows what to do when we call it on a particular array, in this case, arrayOne.  It uses the array to establish the arguments to pass into the callBack function.  &lt;/p&gt;

&lt;p&gt;Let's walk line by line through our code and try to think like the program.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Synchronous JavaScript
&lt;/h2&gt;

&lt;p&gt;In the first line, JavaScript sees arrayOne:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let arrayOne = [7, 8, 3]; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because JavaScript is synchronous (meaning it processes our code much like we read books in English: top to bottom, and left to right), we must initialize our array variable before we call our reducer. &lt;/p&gt;

&lt;p&gt;Take a quick pause for a minute and try to answer this question: what would happen to the program if we initialized arrayOne &lt;em&gt;after&lt;/em&gt; we called our reducer function?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let arraySum = arrayOne.reduce(function(a, b){
return (a + b)
}, 2);

let arrayOne = [7, 8, 3];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The program would throw an error.  It would say something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;index.js:14 Uncaught ReferenceError: Cannot access 'arrayOne' before initialization
    at index.js:14:20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JavaScript is good to us in this way.  It can recognize that we want to access an array, but because the program is &lt;strong&gt;inherently synchronous&lt;/strong&gt;, it cannot jump lines of code to go searching for our variable.  So, it throws an error saying we aren't communicating with it correctly.  How helpful!  If you come across an error like this, go ahead and check the composition of your code.  Ask yourself, "Did I try to access a variable before I created it?  How can I fix that?"  In this case, we can simply move the line of code in which we initialize arrayOne above the reduce function.       &lt;/p&gt;

&lt;h2&gt;
  
  
  Storing Our Single Returned Value: Practicing with REPL
&lt;/h2&gt;

&lt;p&gt;In our next line of code, we initialize a variable arraySum:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let arraySum = 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is important because reduce returns a single value from an array.  The way to access that returned value is through this variable.  Go ahead and open up this &lt;a href="https://replit.com/languages/javascript"&gt;REPL&lt;/a&gt; for JavaScript.  Copy and paste the entire code snippet from the beginning of this post into the left window (make sure you are in node.js in the little drop-down window).  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qn5x7fUl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/idqtg7n1vrtqy566xe01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qn5x7fUl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/idqtg7n1vrtqy566xe01.png" alt="Image description" width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you hit run, you will see your console.log displayed in the right window as 20.  Now in the right window, type arraySum and hit enter.  You should see 20.  This is because our variable arraySum is set equal to the evaluated reducer function.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Parameters of Reduce: the Anonymous Function and "Initial Value"
&lt;/h2&gt;

&lt;p&gt;Let's return to our code and move to the right of the variable, after the equal sign:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arrayOne.reduce(function(a, b){/*...*/}, 2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are calling reduce on arrayOne and setting our first parameter, our callBack function.  This is an anonymous function (we can tell it is anonymous because it has no name, and it &lt;em&gt;can&lt;/em&gt; be anonymous because we do not call it outside of the arraySum variable) with two parameters, a and b.  Parameter a is  our "accumulator" and parameter b is our "current value".  Finally, we have the lonely 2.  This is an optional parameter in the reduce method.&lt;/p&gt;

&lt;p&gt;HEY WAIT!  WHAT HAPPENED TO ALL THE CODE BETWEEN THE CURLY BRACES?  &lt;/p&gt;

&lt;p&gt;This is a great question.  Right now, we are looking at the code the way JavaScript reads it.  It doesn't look at the code block between the curly braces; it continues looking down the line at the other parameters of our anonymous function, which is the "initial value".  It needs this information before it can execute the function.  &lt;/p&gt;

&lt;p&gt;What does the "initial value" do?  Hold on to your hat, because this is where the ride starts.  Let's integrate this question into our discussion about the parameters of our callback function.    &lt;/p&gt;

&lt;h3&gt;
  
  
  Accumulator and Current Value: Parameters of the Anonymous Function
&lt;/h3&gt;

&lt;p&gt;Let's talk about the "accumulator" first, in this case a.  This is the value resulting from the previous call to our callBack  function.  On the first call, it is set to the value of arrayOne[0].  Check out our array below.  On the first call of our callBack, where is accumulator set?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let arrayOne = [7, 8, 3];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is set at arrayOne[0], which is the integer 7.&lt;/p&gt;

&lt;p&gt;Now, if we have an "initial value" declared, which we do, our "accumulator" is then set to be the initial value.  Check out the code snippet below one more time.  What would our accumulator value be set to?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arrayOne.reduce(function(a, b){/*...*/}, 2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you guessed 2, you've got it!&lt;/p&gt;

&lt;p&gt;Now let's talk about "current value".  This is the value of the current element in our array.  We start at arrayOne[1].  Look at our array above.  Imagine we are still in the first call.  What is our "current value"? &lt;/p&gt;

&lt;p&gt;arrayOne[1] is the integer 8.  Great!  Now let's throw in the "initial value" wrench.  If this is declared, as in our example, "current value" becomes arrayOne[0], which is 7.  &lt;/p&gt;

&lt;p&gt;Whew!  So to recap, when "initial value" is a player, on the first call of our callBack function, "initial value" takes the place of "accumulator", and the default for "current value" (which is arrayOne[1]) is replaced by the arrayOne[0].  Basically, everything bumps down by one.  It is almost like we are adding an element to the beginning of our array and starting there. &lt;/p&gt;

&lt;p&gt;Finally, we hit our last line of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(arraySum)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JavaScript scans global memory, looking for a variable named arraySum.  Aha, it is there, and it evaluates to the call of our reducer function.  So now, JavaScript can enter the body of our function.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Body of the callBack Function and Making Calculations
&lt;/h2&gt;

&lt;p&gt;Before we evaluate the body of our function, let's make a quick cheat sheet for the work JavaScript has done so far and stored in local memory for the first execution context of this function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arraySum = the evaluated result of calling reduce on arrayOne;
a = 2 (this is our accumulator and first parameter/argument, in this case our "initial value");
b = 7 (this is our current value and second parameter/argument, because we have "initial value" declared, it it arrayOne[0]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this information that JS has stored in memory, we can enter the body of our function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
return (a + b)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JavaScript hits this line of code and knows what a and b represent in this call, as they are stored in the local memory of this function.  JavaScript adds them together and returns the math, in this case 9, back to the callBack function.  Now we have the value of our "accumulator" for our next call.  Remember, we are only in the first call; JavaScripts' job is to do this on ALL of the element specified in the array! &lt;/p&gt;

&lt;p&gt;For the final piece of this blog (and the most fun part of .reduce()), we finish up the calculations.  In local memory, our parameters are updated, so now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a = 9 (the evaluated result of the first call, the "accumulator");
b = 8 (the next index in our array, or arrayOne[1]);

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

&lt;/div&gt;



&lt;p&gt;JavaScript then enters the body of the function and performs for us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
return (a + b)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which is 17.  Can you guess what we do with the evaluated result of our callBack function?  &lt;/p&gt;

&lt;p&gt;Yes!  We use it as our new accumulator value in the next call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a = 17;
b = 3;

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

&lt;/div&gt;



&lt;p&gt;which is 20.  JavaScript sees there are no more elements in the array to iterate over, and exits out of the function entirely, leaving our variable arraySum equal to the returned value of 20, which is stored in global memory.  &lt;/p&gt;

&lt;p&gt;Here is our entire snippet of code one more time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let arrayOne = [7, 8, 3];

let arraySum = arrayOne.reduce(function(a, b){
return (a + b)
}, 2);

console.log(arraySum) // displays 20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Technical Communication
&lt;/h2&gt;

&lt;p&gt;Now, as promised, let's look at the code again and talk technically about the code.  Try it yourself first.  Then read the below paragraph out loud and follow along with the code above:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We are declaring a variable arrayOne and setting it equal to an array of integers including 7, 8, and 3.  We are declaring another variable, arraySum, and setting it equal to the evaluated result of calling reduce on arrayOne.  Reduce accepts two parameters: the first is an anonymous function that also accepts two parameters, a and b; the second is the initial value of 2.  The body of the anonymous function returns adding b to a. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Whew, you did it!  Now it it time to play.  Go ahead and use the &lt;a href="https://replit.com/languages/javascript"&gt;REPL&lt;/a&gt; link to try out different parameters.  What would happen if you passed in a different initial value, or none at all?  What would happen if you had a much larger array and called slice on it before calling reduce on it?  What if you had a collection of functions that you called reduce on?  Here is a little code snippet to toy with if you're up for the challenge:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const minusThree = x =&amp;gt; x - 3

const result = [minusThree].reduce((value, currVal) =&amp;gt; currVal(value), 0 )  

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

&lt;/div&gt;



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

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>synchronous</category>
      <category>technicalcommunication</category>
    </item>
  </channel>
</rss>
