Exact Change, can't pass the two tests that test accuracy against an array - solved

Exact Change, can't pass the two tests that test accuracy against an array - solved
0.0 0

#1

I am able to pass all of the tests, except for the two that compare to the correct answer arrays.

I am not sure why this is happening. I have tried with toFixed(2), and without it on the numbers being pushed to the money array.

when I try to solve the case demonstrated in the code below with the toFixed(2) I get:
[[ ‘QUARTER’, ‘0.50’ ]]

when I try to solve the case demonstrated in the code below without the toFixed(2) I get:
[[ ‘QUARTER’, 0.5 ]]

any advice would be much appreciated!

//set global variables
var denomIndex = 0;
var money = [];
var penny;
var nickel;
var dime;
var quarter;
var one;
var five;
var ten;
var twenty;
var hundred;

//create a constructor function to convert provided array into denomination based objects
function checkCashRegister(price, cash, cid) {
  function cashObjects(index) {
    this.totalVal = cid[index][1];
    this.indiVal = indiVals[indiVals.length - index - 1][1];
    this.count = this.totalVal / this.indiVal;
  }
 
//create 2d array with denomination values
  var indiVals = [
    [
      "hundred", 100
    ],
    [
      "twenty", 20
    ],
    [
      "ten", 10
    ],
    [
      "five", 5
    ],
    [
      "one", 1
    ],
    [
      "quarter", .25
    ],
    [
      "dime", .1
    ],
    [
      "nickel", .05
    ],
    ["penny", .01]
  ];

//use constructor function to create denomination objects 
  penny = new cashObjects(0, 0.01);
  nickel = new cashObjects(1, 0.05);
  dime = new cashObjects(2, 0.1);
  quarter = new cashObjects(3, 0.25);
  one = new cashObjects(4, 1);
  five = new cashObjects(5, 5);
  ten = new cashObjects(6, 10);
  twenty = new cashObjects(7, 20);
  hundred = new cashObjects(8, 100);

//calculate change and set start variable to ""
  var change = Math.round((cash - price) * 100) / 100;
  var start = "";

//return results of a redundant function
  return run(indiVals, change);
}


function run(indiVals, change) {
//loop through denomination values, to find the highest denomination that goes into change
  for (var i = 0; i < indiVals.length; i++) {
    var temp = change - indiVals[i][1];
    start = eval(indiVals[i][0]);
//find out how much of highest denomination can go into change
    if (temp > 0 && start.totalVal > 0) {
      if (change >= start.totalVal) {
        var temp = [];
        temp.push(indiVals[i][0].toUpperCase());
        
        //I believe this is causing an issue
        temp.push(Number(start.totalVal.toFixed(2)));
        change = Math.round((change - start.totalVal) * 100) / 100;
        money.push(temp);
        start.totalVal = 0;
        denomIndex = i;
      } else {
        var temp = [];
        temp.push(indiVals[i][0].toUpperCase());
        var temp1 = Math.floor(change / start.indiVal);
        temp1 *= start.indiVal;
       
//I believe this is causing an issue
        temp.push(Number(temp1.toFixed(2)));
        console.log(temp);
        start.totalVal -= temp1;
        change = Math.round((change - temp1) * 100) / 100;
        money.push(temp);
        denomIndex = i;
      }
//break the denomination loop after calculations for highest denominator
      break;
    }
  }
//test conditions to provide correct answer
// if change is not equal to 0 and the for loop has looped through pennys, return insufficient funds
  if (change !== 0 && denomIndex === 8) {
    return "Insufficient Funds";
  } 
// if change isn't equal to 0 but for loop hasn't reached penny's yet, run through the function again
else if (change !== 0 && denomIndex !== 8) {
    return run(indiVals, change);
  }
// if cid values are 0 then register is closed, if not return money array as answer
  if(penny.totalVal === 0 && nickel.totalVal === 0 && dime.totalVal === 0 && quarter.totalVal === 0 && one.totalVal === 0 && five.totalVal === 0 && ten.totalVal === 0 && twenty.totalVal === 0 && hundred.totalVal === 0){
    return "Closed";
  } else {
    return money;
  }
}

// Example cash-in-drawer array:
// [["PENNY", 1.01],
// ["NICKEL", 2.05],
// ["DIME", 3.10],
// ["QUARTER", 4.25],
// ["ONE", 90.00],
// ["FIVE", 55.00],
// ["TEN", 20.00],
// ["TWENTY", 60.00],
// ["ONE HUNDRED", 100.00]]

checkCashRegister(19.50, 20.00, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]])


#2

The global array money is the source of your problem. The FCC tests run consecutive and because money is declared globally, it will start with the last values it had checkCashRegister was last called.

You can see what is going on by running the a few of tests consecutively with console.log statements like:

console.log(checkCashRegister(19.50, 20.00, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]]));
console.log()

console.log(checkCashRegister(19.50, 20.00, [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]))
console.log()
console.log(checkCashRegister(19.50, 20.00, [["PENNY", 0.50], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]))
console.log()
console.log(checkCashRegister(19.50, 20.00, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]]))
console.log()
console.log(checkCashRegister(3.26, 100.00, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]]))

The above yields:

[ [ ‘QUARTER’, 0.5 ] ]

Insufficient Funds

Closed

[ [ ‘QUARTER’, 0.5 ],
[ ‘PENNY’, 0.01 ],
[ ‘PENNY’, 0.5 ],
[ ‘QUARTER’, 0.5 ] ]

[ [ ‘QUARTER’, 0.5 ],
[ ‘PENNY’, 0.01 ],
[ ‘PENNY’, 0.5 ],
[ ‘QUARTER’, 0.5 ],
[ ‘TWENTY’, 60 ],
[ ‘TEN’, 20 ],
[ ‘FIVE’, 15 ],
[ ‘ONE’, 1 ],
[ ‘QUARTER’, 0.5 ],
[ ‘DIME’, 0.2 ],
[ ‘PENNY’, 0.04 ] ]


#3

very helpful! thank you! I guess that makes my solution not very effective for FCC, I will have to rethink it!


#4

In general, you should stay away from global variables, because if you were working on a large project with multiple people, there is a chance two people could choose the same variable names inside their functions. If one person declare the same name globally, it could cause side-effects across everyone’s code.


#5

actually, I just cleared the money array, and denomIndex at the start of the function and it worked!

thanks @rmdawson71


#6

good lesson! Would a better approach to use object based programming, and wrap these variables and functions in objects to prevent confusion like this?


#7

Yes, OOP is one option.