Can't figure out how to get a value stored/used after clicking (calculator)

please format code with </> button * homework policy * asking questions

Hello,

Below I am attaching the code for a project I am working on. The goal is to create a calculator (GUI doesn’t matter as long as it has clickable buttons) with 1-9, decimal and +,-,/,*,= and clear.

I am currently stuck. I’ve gotten arrays that will draw all the buttons and even the mouseReleased for detecting mouse clicks in the buttons. But how do I take the value of mouseReleased (the number I clicked on) if it is a void function and does not reutrn anything? I’m confused on where to go next, basically how to store the numbers and use them.

My first thought was to create another function for storing the numbers and another for doing the actual math based on the operation clicked. However, this still leaves me the problem of how to use a number form a void function.

Thank you! Please let me know if there’s anything else you need.

float buttonsx, buttonsy, 
  wd, ht, 
  c2, 
  num1, num2;

boolean numclick1, numclick2;

//declares arrays for drawing boxes locations
int[] x = {200, 150, 200, 250, 150, 200, 250, 150, 200, 250, 300, 300, 300, 300, 300, 300};
int[] y = {250, 200, 200, 200, 150, 150, 150, 100, 100, 100, 0, 50, 100, 150, 200, 250};
String op = "+-*/.=";

void setup()
{
  size(500, 500);

  buttonsx = 300;
  buttonsy = 50;

  wd = 45;
  ht = 45;
}

void draw()
{
  for (int boxes = 0; boxes < 14; boxes = boxes+1) //draws the boxes and puts numbers on them
  {
    fill(250, 250, 230);
    rect(x[boxes], y[boxes], wd, ht);
    fill(50);
    text(boxes, (x[boxes] + 20), (y[boxes] + 25));
  }

  for (int operators = 10; operators < 16; operators = operators + 1) //draws operators and labels
  {
    fill(250, 250, 230);
    rect(x[operators], y[operators], wd, ht);
    fill(50);
  }
}

void mouseReleased() //sense the clicks on the boxes
{  
  for (int i = 0; i < 10; i++)
    if ((x[i] < mouseX) && (mouseX < (x[i] + wd)) && (y[i] < mouseY) && (mouseY < (y[i]+ht)))
      println(i);

Store:
replace print(i); by appending that value to a separate variable that stores the current number. (if you press a second button, multiply the variables value by 10 before adding ;-))

whenever you press a different button (like +,-,/,*), append that value to a list (probably a FloatList() and append that second thing as well.

whenever you press ‘=’ " calculate the result by implementing some logic that reads the inputs from your FloatList and does something smart like:

Evaluate the List:
find the first “sign” (+ or -) and do that calculation with the value to the left and the value to the right, then replace the first value by the result, remove the next two

12 - 3 + 7 - 9 ->
9 + 7 - 9 ->
16 - 9 ->
7

having multiplication and division you should do these first. look through the list until you find a * or a / until you have eliminated them from the list

so 12 + 3 * 7 - 9 becomes 12 + 21 - 9 (only + and - are left)

then you do the same, eliminating part after part:

12 + 3 * 7 - 9 ->
12 + 21 - 9 ->
33 - 9 ->
24

voila, the list contains 1 item with the result

1 Like

Tried making the changes you suggested; ended up with the code below. Trying to figure out how to handle the second click properly, because as it is now it just adds the number that i clicked to itself and then prints that, which isn’t what I want.

Part of my confusion was when you said to add the value to a FloatList and then search for the “+” symbol? Maybe I’m misunderstanding, but how can I add a string like “+” to a FloatList?

float buttonsx, buttonsy, 
  wd, ht, 
  c2, num1, num2;

String operator;
StringList operatorChoice;
FloatList choice2;
FloatList choice1;

//declares arrays for drawing boxes locations
float[] x = {200, 150, 200, 250, 150, 200, 250, 150, 200, 250, 300, 300, 300, 300, 300, 300};
float[] y = {250, 200, 200, 200, 150, 150, 150, 100, 100, 100, 0, 50, 100, 150, 200, 250};

void setup()
{
  size(500, 500);

  buttonsx = 300;
  buttonsy = 50;

  wd = 45;
  ht = 45;
}

void draw()
{
  for (int boxes = 0; boxes < 14; boxes = boxes+1) //draws the boxes and puts numbers on them
  {
    fill(250, 250, 230);
    rect(x[boxes], y[boxes], wd, ht);
    fill(50);
    text(boxes, (x[boxes] + 20), (y[boxes] + 25));
  }

  for (int operators = 10; operators < 16; operators = operators + 1) //draws operators and labels
  {
    fill(250, 250, 230);
    rect(x[operators], y[operators], wd, ht);
    fill(50);
  }

  //adds in the overlay for operations buttons
  text("+", (x[10] + 20), (y[10] + 25));
  text("-", (x[11] + 20), (y[11] + 25));
  text("*", (x[12] + 20), (y[12] + 25));
  text("/", (x[13] + 20), (y[13] + 25));
  text(".", (x[14] + 20), (y[14] + 25));
  text("=", (x[15] + 20), (y[15] + 25));
}

void mouseClicked() //sense the clicks on the boxes
{  
  for (int i = 0; i < 10; i++) {
    if ((x[i] < mouseX) && (mouseX < (x[i] + wd)) && (y[i] < mouseY) && (mouseY < (y[i]+ht)))
      num1 = i;
    choice1 = new FloatList(); //creates float list
    choice1.append(num1); //adds choice to the float list
    if ((x[i] < mouseX) && (mouseX < (x[i] + wd)) && (y[i] < mouseY) && (mouseY < (y[i]+ht)))
      num2 = i;
    choice2 = new FloatList(); //creates float list
    choice2.append(num2); //adds choice to the float list
    if ((x[10] < mouseX) && (mouseX < (x[10] + wd)) && (y[10] < mouseY) && (mouseY < (y[10]+ht)))
      operator = "+"; //storing the plus operator if clicked
    operatorChoice = new StringList();
    operatorChoice.append(operator);
    if ((x[11] < mouseX) && (mouseX < (x[11] + wd)) && (y[11] < mouseY) && (mouseY < (y[11]+ht)))
      operator = "-"; //storing the minus operator if clicked
    operatorChoice = new StringList();
    operatorChoice.append(operator);
    if ((x[12] < mouseX) && (mouseX < (x[12] + wd)) && (y[12] < mouseY) && (mouseY < (y[12]+ht)))
      operator = "*"; //storing the multiplication operator if clicked
    operatorChoice = new StringList();
    operatorChoice.append(operator);
    if ((x[13] < mouseX) && (mouseX < (x[13] + wd)) && (y[13] < mouseY) && (mouseY < (y[13]+ht)))
      operator = "/"; //storing the division operator if clicked
    operatorChoice = new StringList();
    operatorChoice.append(operator);
  }
  
  if(operatorChoice.hasValue("+"))
    println(num1 + num2);
  
}


ah, yes, I took some shortcuts now and then to let you figure out more by yourself (better for the memory :slight_smile: )

including the operators its probably good to store all values into s StringList. all your values could go into one single List. (you can of course use more like you did, too and gather things for calculating from there…)

a) if you have more than one line after an if-statement you need to put that into curly brackets. Or else only the line following the if statement will be part of it.

if ((x[i] < mouseX) && (mouseX < (x[i] + wd)) && (y[i] < mouseY) && (mouseY < (y[i]+ht)))
      num1 = i;
    choice1 = new FloatList(); //creates float list
    choice1.append(num1); //adds choice to the float list

so her only num1 = i is depending on the if, while the next to lines are executed every time the mouse is clicked.

b) if you use new FloatList with every mouseClick, it means that your FloatList will be initialized again and again, resulting in an empty list with 1 entry, due to the append. so it always contains only 1 value.

c) because of a) your for loop executes 10 times, overwriting everything. in the last loop
choice1 and choice2 both have one entry with the value 9, operatorChoice has the value /

obviously your println does nothing, since you do it only if it is a +.
since you try to check on operatorChoice to print something, it can happen that you get an error. because you initialize it only after a mouseClick and the first thing one clicks will usually be a number, clicking a number triggers the if-statement containing hasValue(), but the list does not exist yet.

d) you append your value (i) to both FloatLists at the same time. that is overwriting it.

e) you don’t need to check on the operators 10 times after a mouse click, it should be outside your for-loop

here is a fragment where you can see what happens if the if-statement are in correct brackets.

void mouseReleased() //sense the clicks on the boxes
{  
  for (int i = 0; i < 10; i++) {
    if ((x[i] < mouseX) && (mouseX < (x[i] + wd)) && (y[i] < mouseY) && (mouseY < (y[i]+ht))) {
      num1 = i;
      choice1 = new FloatList(); //creates float list
      choice1.append(num1); //adds choice to the float list
      println(choice1);
    }
    if ((x[i] < mouseX) && (mouseX < (x[i] + wd)) && (y[i] < mouseY) && (mouseY < (y[i]+ht))) {
      num2 = i;
      choice2 = new FloatList(); //creates float list
      choice2.append(num2); //adds choice to the float list
    }
    if ((x[10] < mouseX) && (mouseX < (x[10] + wd)) && (y[10] < mouseY) && (mouseY < (y[10]+ht))) {
      operator = "+"; //storing the plus operator if clicked
    operatorChoice = new StringList();
    operatorChoice.append(operator);
    }
    if ((x[11] < mouseX) && (mouseX < (x[11] + wd)) && (y[11] < mouseY) && (mouseY < (y[11]+ht))) {
      operator = "-"; //storing the minus operator if clicked
    operatorChoice = new StringList();
    operatorChoice.append(operator);
    }
    if ((x[12] < mouseX) && (mouseX < (x[12] + wd)) && (y[12] < mouseY) && (mouseY < (y[12]+ht))) {
      operator = "*"; //storing the multiplication operator if clicked
    operatorChoice = new StringList();
    operatorChoice.append(operator);
    }
    if ((x[13] < mouseX) && (mouseX < (x[13] + wd)) && (y[13] < mouseY) && (mouseY < (y[13]+ht))) {
      operator = "/"; //storing the division operator if clicked
    operatorChoice = new StringList();
    operatorChoice.append(operator);
    }
  }
    println(num1 + " " + num2);
    println(operatorChoice);
}

Still you should not use different Lists and should not initialize it (or them) every time a mouse is clicked. Using a list only makes sense when you are… well… using lists with more than one entry :slight_smile:
so, operatorChoice = new StringList(); should be done once in setup() and so on.

so here is another pseudo code:

StringList choices;
String value;
String operator;
//---------------------
void mouseReleased() //sense the clicks on the boxes
{
  for (int i = 0; i < 10; i++) {
    if (mouse is inside one of these buttons) {
      value = str(i);  // you can append your numbers to the stringlist too by converting it to a string for now    
      choices.append(value);
    }
  } 
  //---------------------
  if (your four operator checks here) {
    value = "+"; // or one of the others
    choices.append(value);
  } 
  //---------------------
  if (check for an "=") {
    work on the calculation
      (get back yoour numbers from the StringList by using int(choices.get(i)) for example)
      store the result somwhere, 
      clear all lists ;-)
  }
}

Okay so made some more progress. Cleaned up the code (sorry if it has some stuff in it that isnt useful like the println, thats mostly visual to see if things are working). But again where I’m getting stuck is handling the second click. I can get the first click. I fixed the issue where it runs through 10 times. The plus has been fixed so it is outside of the for loop. Now where would I begin handling the second mouse click?

As I have it now, it appears the code is running both clicks at the same time and appending them both to the list. I did combine into one list. How do I get the two clicks to register at different times? Also, leaving out the draw function as I don’t think I changed it.


float buttonsx, buttonsy, 
  wd, ht, 
  c2, num1, num2;

StringList storedOperator;
String value;
String operator;

//declares arrays for drawing boxes locations
float[] x = {200, 150, 200, 250, 150, 200, 250, 150, 200, 250, 300, 300, 300, 300, 300, 300};
float[] y = {250, 200, 200, 200, 150, 150, 150, 100, 100, 100, 0, 50, 100, 150, 200, 250};

void setup()
{
  storedOperator = new StringList(); //creates float list for storing the numbers and operators

  size(500, 500);

  buttonsx = 300;
  buttonsy = 50;

  wd = 45;
  ht = 45;
}

void draw()
{
  for (int boxes = 0; boxes < 14; boxes = boxes+1) //draws the boxes and puts numbers on them
  {
    fill(250, 250, 230);
    rect(x[boxes], y[boxes], wd, ht);
    fill(50);
    text(boxes, (x[boxes] + 20), (y[boxes] + 25));
  }

  for (int operators = 10; operators < 16; operators = operators + 1) //draws operators and labels
  {
    fill(250, 250, 230);
    rect(x[operators], y[operators], wd, ht);
    fill(50);
  }

  //adds in the overlay for operations buttons
  text("+", (x[10] + 20), (y[10] + 25));
  text("-", (x[11] + 20), (y[11] + 25));
  text("*", (x[12] + 20), (y[12] + 25));
  text("/", (x[13] + 20), (y[13] + 25));
  text(".", (x[14] + 20), (y[14] + 25));
  text("=", (x[15] + 20), (y[15] + 25));
}

void mouseReleased() //sense the clicks on the boxes
{  
  for (int i = 0; i < 10; i++) {
    if ((x[i] < mouseX) && (mouseX < (x[i] + wd)) && (y[i] < mouseY) && (mouseY < (y[i]+ht))) {
      String value = str(i);
      storedOperator.append(value); //adds choice to the float list
    }
    if ((x[i] < mouseX) && (mouseX < (x[i] + wd)) && (y[i] < mouseY) && (mouseY < (y[i]+ht))) {
      String value = str(i);
      storedOperator.append(value);
      println(storedOperator);//adds choice to the float list
    }
  }
  if ((x[10] < mouseX) && (mouseX < (x[10] + wd)) && (y[10] < mouseY) && (mouseY < (y[10]+ht))) {
    operator = "+"; //storing the plus operator if clicked
    storedOperator.append(operator);
  }
  if ((x[11] < mouseX) && (mouseX < (x[11] + wd)) && (y[11] < mouseY) && (mouseY < (y[11]+ht))) {
    operator = "-"; //storing the minus operator if clicked
    storedOperator.append(operator);
  }
  if ((x[12] < mouseX) && (mouseX < (x[12] + wd)) && (y[12] < mouseY) && (mouseY < (y[12]+ht))) {
    operator = "*"; //storing the multiplication operator if clicked
    storedOperator.append(operator);
  }
  if ((x[13] < mouseX) && (mouseX < (x[13] + wd)) && (y[13] < mouseY) && (mouseY < (y[13]+ht))) {
    operator = "/"; //storing the division operator if clicked
    storedOperator.append(operator);
  }
  if ((x[15] < mouseX) && (mouseX < (x[15] + wd)) && (y[15] < mouseY) && (mouseY < (y[15]+ht))) {
    int num1 = int((storedOperator.get(0)));
    int num2 = int((storedOperator.get(3)));
  if (storedOperator.equals("+")); 
  {//checks and does addition
    println(num1 + num2);
  }
  if (storedOperator.equals("-"));; 
  {//checks and does subtraction
    println(num1 - num2);
  }
  if (storedOperator.equals("*")); 
  {//checks and does multiply
    println(num1 * num2);
  }
  if (storedOperator.equals("/")); 
  {//checks and does divide
    println(num1 / num2);
  }
  storedOperator.clear();
  }
}

EDIT: added in complete code because I think I’m really close. Got it to do the operations, but now it does all four operations and prints them all. Why does it do that when only 1 of the 4 if statements should be used?

EDIT 2: just added in (.equals instead of “==”)

Actually == doesn’t work well with String

Use … .equals("*") instead

Thank you. I have done that, but it still prints out the results of all 4 operators as opposed to just the one I selected. Any suggestions for that? I suspect it’s a program flow misunderstanding like when I misplaced some “if” statements into a for loop earlier.

Sure

No ;; allowed after a line with if (very important)

It would separate the line from its {…} part

Therefore, all {…} parts were executed (because the if doesn’t prevent them from being excuted because of the “;” ).

Thank you so much, that got it working for me. Now one last thing, how would you recommend adding a decimal aspect into this? It would require a longer list/more checks, right?

Yeah like append/insert a dot . into the number?

1 Like

Additional read Why Can't Processing Do Basic Math lol

Thank you so much, that got it working for me. Now one last thing, how would you recommend adding a decimal aspect into this? It would require a longer list/more checks, right?

just forget the language requirement of processing for a second. Think of it in a very general way and look at it as a series of really simple, stupid things happening…

you have a surface with buttons. each click is a value. if your code was a buddy of yours watching you what you do, he would note each event on a piece of paper.

so the first thing you will probably see on that paper is a row of characters:

1 2 4 + 7 . 2 - 2 + 4 4 + 7 7 7 7 = result

neither your buddy nor the code needs to know what it actually means to achieve the task of writing stuff down.

that is your list. (obviously you are smarter than him, so you know about floats)

while “writing”, the only thing you need to watch for if an = is coming. that is the moment when you go to the trigger the next step. you assemble the items of the list to a shorter list (since it still can be anything, so we still use a StringList)

A cycle through your list with a loop:

step 1: 
look at the nth item 
-> if it is a number or a '.' add it to a variable (which is a string !)
myTemporaryVariable = myTemporaryVariable += myStringList.get(index);
if the **next** item is **not** an operator -> remove the entry from the list
go to step 1 (thats the loop)

-> if its an operator, write the variable into the last position (that you did not remove) and clear your variable
go to step 1

now you should have the same list, but it contains less entries:
124 + 7.2 - 2 + 44 + 7777

B cycle through the list again

step 1:
look at the nth item
-> if it is a number, ignore it
go to step 1
-> if it is an operator, check which one it is
   -> if it is a +, take the entry before, convert it to a float, and **add** 
   it to the entry after the + (that you convert as well)
   -> if it is a -, take the entry before, convert it to a float, and **subtract** 
   it to the entry after the + (that you convert as well)

something like:  myTemporaryVariable = myStringList.get(index-1) + myStringList.get(index+1)
(because your index is pointing at the operator, so you want the one before and the one after

delete 2 of the 3 entries and write the result into the 3rd one

the results should be:

124 + 7.2 - 2 + 44 + 7777
131.2 - 2 + 44 + 7777
129.2 + 44 + 7777
173.2 + 7777
7950.2

Put loop B into another loop (maybe a while loop)

so you repeat it infinitely.
before you let loop B start check on its length
if the number of items in your list is > 1, do the loop
if it is not -> that is the result. break out from the loop

in fact it doesn’t matter which characters you store in the loop.
its about how you deal with them, about the logic you create about them
or, how you explain to your buddy, who is less smart then you, what he should do with that list of numbers, step by step

tbh, that is probably the biggest amount of time I spent with code… staring at the screen and trying to find out which simple instruction I forgot to give the computer :slight_smile:

1 Like

I got to step 1 on the first step. I’m having trouble constructing the loop (use a counter? that’s the only way I know how to create loops so far), and the if statements. I understand what I need to do, check if it is a number or a “.” but how do I do that? When I try to used storedOperator.hasValue() it won’t let me unless I write out a check for every single number (unless theres a way to combine the multiple checks into one line that I haven’t learned yet?).

I’m struggling at grasping the if statements. “If its an operator, write the variable into the last position,” what does this accomplish? I’m going to just throw my current code into the bottom of this post because at this point I’m lost and showing what I have is the most helpful I think.

I’m sorry for so much trouble, but the teacher assigned this with no information about lists, only gave an intro on arrays and strings and told us to do this project. Seeing as it’s due tomorrow, I’m not even sure if I’ll be able to complete anyways.

/*--------------------------------------------------------------------------------------------------------------------------------------
 Calculator Project
 --------------------------------------------------------------------------
 ----- changelog ----------------------------------------------------------
 
 Date Time ---------------Notes------------------------------------------
 ---- -------------------------------------------------------------------
 10/1/20 Initial Coding - setup button locations
 10/2/20 Cleaned code and combined arrays into one
 10/3/20 Added in Numbers on the buttons, added for loops
 10/4/20 Added in stringlist, changed variables, cleaned code
 ------------------------------------------------------------------------*/

float buttonsx, buttonsy, 
  wd, ht, 
  c2, num1, num2;
int whilecounter;

StringList storedOperator;
StringList test;
String value;
String operator;
String number;
String temp;

//declares arrays for drawing boxes locations
float[] x = {200, 150, 200, 250, 150, 200, 250, 150, 200, 250, 300, 300, 300, 300, 300, 300};
float[] y = {250, 200, 200, 200, 150, 150, 150, 100, 100, 100, 0, 50, 100, 150, 200, 250};

void setup()
{
  //sets up number and operator stringlist
  storedOperator = new StringList(); //creates float list for storing the numbers and operators

  size(500, 500);
  whilecounter = 0;
  buttonsx = 300;
  buttonsy = 50;

  wd = 45;
  ht = 45;
}

void draw()
{
  for (int boxes = 0; boxes < 14; boxes = boxes+1) //draws the boxes and puts numbers on them
  {
    fill(250, 250, 230);
    rect(x[boxes], y[boxes], wd, ht);
    fill(50);
    text(boxes, (x[boxes] + 20), (y[boxes] + 25));
  }

  for (int operators = 10; operators < 16; operators = operators + 1) //draws operators and labels
  {
    fill(250, 250, 230);
    rect(x[operators], y[operators], wd, ht);
    fill(50);
  }

  //adds in the overlay for operations buttons
  text("+", (x[10] + 20), (y[10] + 25));
  text("-", (x[11] + 20), (y[11] + 25));
  text("*", (x[12] + 20), (y[12] + 25));
  text("/", (x[13] + 20), (y[13] + 25));
  text(".", (x[14] + 20), (y[14] + 25));
  text("=", (x[15] + 20), (y[15] + 25));
}

void mouseReleased() //sense the clicks on the boxes
{  
  for (int i = 0; i < 10; i++) { //stores the value of the first click in storedOperator
    if ((x[i] < mouseX) && (mouseX < (x[i] + wd)) && (y[i] < mouseY) && (mouseY < (y[i]+ht))) {
      String value = str(i);
      storedOperator.append(value);
      println(storedOperator);
    }
  }

  if ((x[10] < mouseX) && (mouseX < (x[10] + wd)) && (y[10] < mouseY) && (mouseY < (y[10]+ht))) {
    operator = "+"; //storing the plus operator if clicked
    storedOperator.append(operator);
  }
  if ((x[11] < mouseX) && (mouseX < (x[11] + wd)) && (y[11] < mouseY) && (mouseY < (y[11]+ht))) {
    operator = "-"; //storing the minus operator if clicked
    storedOperator.append(operator);
  }
  if ((x[12] < mouseX) && (mouseX < (x[12] + wd)) && (y[12] < mouseY) && (mouseY < (y[12]+ht))) {
    operator = "*"; //storing the multiplication operator if clicked
    storedOperator.append(operator);
  }
  if ((x[13] < mouseX) && (mouseX < (x[13] + wd)) && (y[13] < mouseY) && (mouseY < (y[13]+ht))) {
    operator = "/"; //storing the division operator if clicked
    storedOperator.append(operator);
  }
  if ((x[14] < mouseX) && (mouseX < (x[14] + wd)) && (y[14] < mouseY) && (mouseY < (y[14]+ht))) {
    operator = "."; //storing the division operator if clicked
    storedOperator.append(operator);
  }
  if ((x[15] < mouseX) && (mouseX < (x[15] + wd)) && (y[15] < mouseY) && (mouseY < (y[15]+ht))) {
    while (whilecounter < storedOperator.size()) {
      whilecounter++;
      if (storedOperator.hasValue() {
        temp = temp += storedOperator.get(0);
        println(temp);
      }  
}