Skip to main content

Project Two - Calculator

Introduction‚Äč

Project time!

We are going to build the iOS calculator! If you've never seen that before, here it is:

Project2

Project Example‚Äč

Calculator

Skeleton Code‚Äč

  1. Go to this link: https://classroom.github.com/a/E8O8GyfS
  2. Click on Accept this assignment
  3. Classroom will begin configuring your assignment. Wait 30 seconds, and then refresh.
  4. Click on the link to go to the repository. 
  5. In the terminal on your local computer, navigate to the directory (folder) where you want to keep all of your assignments. cd into this directory. To be clear, this should not be a git repository. Instead, it will store all of your git repositories. A new repository is created for each assignment, and they will all be organized under this directory (folder).
  6. Click on the green Code button and clone the code to your local machine (this can be done via SSH or HTTPS, but beware that HTTPS is being deprecated). To clone, type git clone [link] while in the directory where you want assignments to be stored.
  7. That's it! No extra steps unlike last time. You should now see a folder called \project2-[username] . cd into this folder to begin and make all of your git commits from inside this folder. To push back to the Classroom repo, just use git push origin main

Goal‚Äč

  • The calculator should look like the above image
  • The calculator should function like a normal calculator
  • Do not¬†implement¬†%¬†or¬†.. You can assume everything will be an integer.
  • C¬†means clear. When a user clicks it, it should clear everything and go back to the first state it was in when the page loaded.
  • Doing the back arrow is required. It's like pressing backspace; it'll delete the last character typed. If it's clicked when there's only one digit, it sets the current number to be¬†0.
  • Don't worry about if the number is too long for the screen.
  • Calculators tend to have some special behavior when you hit equals: if you type another number it erases the results and starts over. Feel free to do that but also free free (like me) to just treat it normally and make the user hit¬†C¬†if they want to clear it. Let's keep it simple.

Okay, now that you have requirements, let's go over some tips and hints.

Helpful Resources, Tips and Hints‚Äč

HTML and CSS Tips and Hints‚Äč

  • Programming is all about taking large problems and breaking them into smaller problems. If you're trying to tackle too much at once, break it into two smaller problems and try to solve one of those.
  • Personally, I wrote the HTML and CSS first. Once that's all taken care of, then I do the JavaScript.
  • For the font of the "result screen" I'd just use¬†monospace.
  • There are so many ways to write this. There is no one right way. My solution is not the only nor is it the best solution. Experiment. Try. Fail. Succeed. It's all about learning here.
  • Good idea to use¬†<button></button>¬†for the buttons. You have to deal with some extra styling stuff but it will make your code work pretty much automatically for disabled people. In general when writing HTML, if something serves the function of a button, make it a¬†<button></button>.
  • I used multiple rows of flex layed out divs for the button. You could do it all in one div using the¬†flex-wrap¬†property.
  • The secret to getting equal gutters (which is what you call the black space between buttons): you can set width to be¬†24.5%¬†(so four of them fit on a line) and then use¬†justify-cotent: space-between¬†to evenly space them. That'll give them a gutter of roughly¬†.5%¬†of the whole width. The problem with using percentages in conjuections with heights: your heights and widths are different. 5% of height is not the same of 5% of width, and that'll make the gutters look weird. You want the bottom gutters to be the same size as the side gutters.¬†margin-bottom¬†to the resuce! If you give the row a¬†margin-bottom¬†of¬†.5%¬†(if you're using my same numbers) then that'll work since margin is always measured as a function of width (just one of those things you have to know!) Hopefully that helps.
  • Sometimes I do the math to get things right. Sometimes I just guess-and-check to see if it looks okay.
  • You can add a class to get the orange buttons. Or you could try¬†:last-child¬†(assuming you have row div.)

JavaScript Tips and Hints‚Äč

JavaScript DOM EventListener

EventTarget.addEventListener()

  • Again, no wrong way to do this. I wrote about 80 lines of JavaScript to finish the project (not including empty lines.) I say that so you have an idea of how much code you should be writing. If you're writing 200+ lines of code, you may want to rethink some of your solutions. Don't feel like you're going for the smallest possible answer. You're just going for correct.
  • I use¬†console.log¬†everywhere while I'm writing code. Just remember to take them out at the end.
  • Many small functions is¬†very¬†preferable to one large function. Have each function do one thing well as opposed to having giant functions that do everything. If you find a function doing too, break it into smaller pieces. I solved it with eight different functions.
  • You'll need to keep track of several variables. Make sure these variables are stored in a place where they stay in scope.
  • You can add an event listener to each button individually, or you can use one listener at the root of the button. I did the latter but it's up to you.

Types‚Äč

A brief note on what is called types in JavaScript. We've danced the idea already and I want to make it a little more concrete for you. Strings, booleans, objects, arrays, numbers, these are different types of types. JavaScript is a language where you don't have to concern yourself a lot with types since it doesn't strictly enforce them (other languages do) but in this problem you are definitely going to have to deal with it.

Whatever you put into the DOM and whatever you get out it are going to strings, every time. If I do:

10

const num = 10;
const div = document.querySelector(".number-target"); // the div right above this block
console.log(num, typeof num); // this is a number here
div.innerText = num;
console.log(div.innerText, typeof div.innerText); // it's a string here

result:

10 "number"
"10" "string"
undefineda

Since you're doing math here, you'll need the numbers to actually be of the number type. Otherwise you'll get "5" + "5" = "55". There's a function called parseInt(string) that will turn a string of a number ("5") to a number (5).

You'll also see that we used the typeof operator. typeof tells whatever the type of the thing that comes right after it is. This is useful to quickly see what's happening in your code. Be careful because typeof is not always useful, but it is useful for telling numbers and strings apart.

Submission‚Äč

Push code onto classroom repo. Submit repo link on gradescope.


Contributors