Hi fellow beginners. You need to redo your code. It's not you, it's me.

Hi fellow beginners. You need to redo your code. It's not you, it's me.

A case study

·

8 min read

If you're going to start a coding journey, or have already begun, you're going to come across the project idea of "building a calculator." It seems easy enough. I mean, who doesn't know addition, subtraction, multiplication, and division. Easy peasy, right?

Eh, maybe.

There are loads of tutorials that can walk you through step by step on creating a calculator. I'm not here to do that. It's okay to start like that, but as many self-taught programmers have said before...

Get out of tutorial hell!

Why? It's simple, tutorials are great for giving you a feeling of accomplishment. And if that's what you're after, great! Keep at it. But they do little to really teach you.

Just because you can follow a recipe from allrecipes.com does not make you a chef. Sorry, you're not going to land a job in a bakery because you followed a TikTok video on how to make peanut butter fudge brownies.

The same thing goes for following tutorials on coding. You can't recreate that product from the tutorial unless you...

build your own!

And that's what I want to discuss.

As I became more confident in my abilities to create programs or scripts I naturally looked for bigger things. I thought a calculator was a great project to start (or revisit) once I felt comfortable with JavaScript and had already followed a tutorial. Here's my story.

I wanted to build as many things as possible during my #100DaysOfCode challenge over on @twitter. So, that's what I did. I built something every day. I had followed some tutorials and felt confident enough to make something on my own everyday. But after a few days of constant project creation, I got stuck. My idea generator was failing, and I couldn't find anything that really pushed me to expand my knowledge base. So... I followed a calculator tutorial. Terrible idea.

I felt accomplishment, true. But it wasn't mine. It wasn't something I did with my own hands. It was something I did with my ears and eyes. I'm a good listener, but I wasn't a becoming a developer. It tricked me.

So, after a few more weeks of 'back to the basics' projects (these were my own), I wanted to re-do the calculator. So I did. Turns out, I remembered NOTHING FROM THE TUTORIAL.

Here is a picture of my first day doing the calculator without a tutorial.

Screen Shot 2022-03-08 at 11.32.15 AM.png

It's quite obvious that it's not a real calculator. In fact, it's only an 'addition machine.' I don't even know what to call it.

However, it was mine. I made it.

  • I knew what went in.
  • I knew what went out.

In the following days, I began to add features like a normal calculator should include. Multiplication, division, subtraction, and a clear button. I was getting somewhere. Again, I knew what was going into the code, and I knew what was coming out of the program.

That's the main thing. I was using what I knew to solve a problem. And I think that's what programmers do. That's what software development is. We solve problems.

I used what I knew to solve a problem

It was awesome. The whole part of it was. I was pumped. I enjoyed trying it. I like solving problems. My finished product was something like this.

Screen Shot 2022-03-08 at 11.37.12 AM.png

This was looking much better. It's got functionality. It's got a light/dark mode. It's got everything that a basic calculator needs. Of course there were some problems and bugs. I still haven't figured out an elegant solution to fit the correct amount of numbers on the screen. But, I know what I know, and I know what I don't know.

Now, let's have a peak at the JavaScript bits.

let total = 0;
let arr = [];
let arr2 = [];
let arr3 = [];
let visibleArray = [];
let mathSymbol;
let answer = 0; // store answer to cut off too many numbers

const addNumbers = () => {
    arr.pop();
    arr2.push(Number(arr.join("")))
    // delete all array
    arr.splice(0)
    // store the math symbol
    mathSymbol = "+";
}

What in the world? Why do I have...

  • 4 empty arrays with terrible naming patterns
  • two variables that both equal 0
  • one variable called "answer" and one called "total" because that's really clear!
  • popping and pushing and splicing arrays
  • WTF!?!?!?

The only good thing I can say about this is that I stored the math symbol. However, that still gave me a boatload of debugging trouble down the line. I should've been storing a value instead of the actual symbol. Live and learn.

Okay, I digress. What this is, is code. It works. It runs. It does the job. It solved a problem. For sure. But it goes on and on like this for 165 lines. Here's another snippet.

// check the math symbol to see which function to perform
        if (button === "=") {
            arr.pop();
            result.innerHTML = Number(arr.join(" "));
            arr3.push(Number(arr.join("")));

            if (arr3 === "") {
                arr3 = Number(newNumber);
            }

            // show the second number to be added
            if (mathSymbol === "+") {
                answer = (Number(arr2) + Number(arr3));
                result.innerHTML = (Number(arr2) + Number(arr3));  
                mathSymbol = "";
                // store the answer
            } else if (mathSymbol === "-") {
                result.innerHTML = (Number(arr2) - Number(arr3));
                mathSymbol = "";     
                // store the answer
                answer = (Number(arr2) - Number(arr3));

More gobbledygook in my opinion. You might be able to ascertain that the program is displaying the numbers on the calculator screen, and then it's checking what math operator was clicked, and then it's doing the math operation. Whew... that was a long breath.

I think I could've made it shorter.

Let's be clear, the above code works fine. It gets the job done, but I was not happy with how it turned out.

So, I did it again. Delete, delete, delete... and opened a new file.

<div class="grid-container">
            <div class="grid-item numbers clear">C</div>
            <div class="grid-item blend"></div>
            <div class="grid-item blend"></div>
            <div class="grid-item blend"></div>
</div>

That's better. Let's start with a grid. It's much easier to modify later. Now, let's start with simple and clear variables in JS.

const display = document.querySelector("#answer");
let numbers = document.querySelectorAll(".grid-item");

let visibleDisplay = "";
let firstNum = "";
let secondNum = "";
let operator = "";

Oh my, these are well named. I have no questions about what a visibleDisplay is or the difference between the firstNum and secondNum. That's important. I like this much better. I feel like I'm growing. You?

!important

I still know what's going in, and what's going out. It's much cleaner now though.

for(let i =0; i< numbers.length; i++) { 
    numbers[i].addEventListener('click', function() {
        visibleDisplay += numbers[i].innerText
        display.innerHTML = visibleDisplay;

        if (numbers[i].classList.contains("plus")) {
            operator = "plus";
            firstNum = visibleDisplay.slice(0,-1);

Looks like I"m looping through the numbers here, and then showing those numbers in the visibleDisplay. No, wait, there is a little confusion here, but it might be cleared up later. The visibleDisplay is different than the display because of the length of the answer. Again, I haven't found an elegant solution for this. I am still learning.

Nonetheless, this is much easier to read.

if (numbers[i].classList.contains("equals")) {
            secondNum = Number(display.innerText.slice((firstNum.length+1), -1));
            firstNum = Number(firstNum);

            if (operator === "plus") {
                visibleDisplay = firstNum + secondNum;   
            } else if (operator === "minus") {
                visibleDisplay = firstNum - secondNum;

And look at this! If the equals button (NOT THE = sign) is sliced then we're getting a first number AND a second number. Still slicing, but we're only cutting off the operator sign. That's relatively clear. Then we add them together if the operator is plus, subtract if it's minus, and so on and so forth.

Wow. This IS easier to read. And I don't know about you, but it looks cleaner too. No copying, no fidgeting. It's a smooth working calculator.

Screen Shot 2022-03-08 at 12.07.56 PM.png

So, why did I go on about this? I wanted to share this.

Things I've learned from building 2 calculators

1. Your first code is not your best code.

Granted, after finishing a project it's fine to be proud, show others and bask in its glory. However, 9 times out of 10, it's not great code. It's viable, but there are mistakes. Go back and check it over. Do you understand what you were trying to do? If you don't, how can anybody else?

2. Make your variable and function names clear and easily readable

I hated going back to my first code to try to understand what I was talking about. I got into a bad habit of assigning new variables arr1, arr2, arr3... This works on Leet Code or Code Wars problems, but is awful when it's sitting in a lot of code. Make it readable for everyone. Other people will read your code.

3. You have to practice making your code shorter

Most Senior Developers that I've spoken to are always searching for faster and smoother running code. One said "we write in C++ because it's faster than Python. We sacrifice engineering time for better user experience." If you can shorten your lines of code, you're becoming a master. Be a master. I went from 165 lines to 60 lines of JS. I'm not a master, but I know which one is better.

4. Rinse and Repeat

The second time was much faster, and I solidified the skills I practiced on the first build. It took me 3 days to complete a working calculator by myself. The next time I tried, it took me the morning to finish. You gotta edit and redo to get better.

Now get out there and create!

You can follow me here or I'm always posting over here

Did you find this article valuable?

Support Jacob Good by becoming a sponsor. Any amount is appreciated!