Cash Register not passing tests

I am getting this result when running tests on this challenge:

// tests completed
// console output
{ status: ‘OPEN’,
change:
[ [ ‘TWENTY’, 60 ],
[ ‘TEN’, 20 ],
[ ‘FIVE’, 15 ],
[ ‘ONE’, 1 ],
[ ‘QUARTER’, 0.5 ],
[ ‘DIME’, 0.2 ],
[ ‘PENNY’, 0.04 ] ] }

which matches the expected output, but doesn’t pass the test?

Any help would be greatly appreciated, as well as any other suggestions on how to improve my code.

Thanks.


var currency = [["PENNY", 0.01], ["NICKEL", 0.05], ["DIME", 0.1], ["QUARTER", 0.25], ["ONE", 1], ["FIVE", 5], ["TEN", 10], ["TWENTY", 20], ["ONE HUNDRED", 100]];

var changeArr = [["PENNY", 0], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]];

function checkCashRegister(price, cash, cid) {
var output = {status: null, change: []};
var change = cash - price;

var tillTotal = 0;
for (var i = 0; i < cid.length; i++) {
  tillTotal += cid[i][1];
}
tillTotal = Math.round(tillTotal * 100) / 100;

if (tillTotal < change) {
  output.status = "INSUFFICIENT_FUNDS";
  return output;
}

if (tillTotal === change) {
  output.status = "CLOSED";
  output.change = cid;
  return output;
}

if (tillTotal > change) {
  for (var k = (cid.length - 1); k >= 0; k--) {
    while (currency[k][1] <= change && cid[k][1] >= currency[k][1]) {
      changeArr[k][1] += currency[k][1]
      cid[k][1] -= currency[k][1]
      change -= currency[k][1]
      change = Math.round(change * 100) / 100;
    }
  }
  var newArr = [];
  for (var q = 0; q < changeArr.length; q++) {
    if (changeArr[q][1] > 0) {
      newArr.unshift(changeArr[q])
    }
  }
  output.status = "OPEN";
  output.change = newArr;
  return output;
}

}

console.log(checkCashRegister(3.26, 100, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]));
  **Your browser information:**

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36.

Challenge: Cash Register

Link to the challenge:

There are a list of testcases FCC runs against your program to test if your program behaves as expected in certain situations. The second to last testcase you have failed:

checkCashRegister(19.5, 20, [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 1], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]) should return {status: "INSUFFICIENT_FUNDS", change: []} .

The output for the second to last testcase for your program is:

{ status: ‘OPEN’, change: [ [ ‘PENNY’, 0.01 ] ] }

And the reason why your program does not output insufficient funds is the cash register expects you to give exact change or none at all. Example:

Bob buys 26 dollars worth of items, has three 10 dollar bills. Your register has a dime, and a 5 dollar bill. The program wants you to say its insufficient funds, even though numerically you have enough money for changing, you can’t rip up the 5 dollar bill and give 4 dollars worth to Bob.

Here in the failed testcase your program sees a change value of 50 cents, and that the till has 1 penny and 1 dollar, and decides to give the dollar to the customer.

Other suggestions:

  1. using objects instead of arrays for your currency and changeArr seems easier to work with.
  2. try using let and const instead of var when possible.

Good luck

1 Like

Thanks for the reply!

I’ll start working on setting a condition that only gives change if the exact amount is possible, I see now that simply putting - if (tillTotal > change) - can cause problems if the right denominations are not present.

I’m still confused as to why this test:

checkCashRegister(3.26, 100, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]) should return {status: "OPEN", change: [["TWENTY", 60], ["TEN", 20], ["FIVE", 15], ["ONE", 1], ["QUARTER", 0.5], ["DIME", 0.2], ["PENNY", 0.04]]} .

…doesn’t pass either? when I get that result with the same amounts and in the descending order of denominations.

Thanks again, i’ll brush up on objects and try to use let and const when I can.

Glad I can help.

I was a little bit confused about other testcases failing because when I copy/pasted your code, it failed only the one I mentioned.

Then I realized I did not copy the console.log at the end as I assumed it was unimportant. However in your code this was very much the opposite.

I failed to mention in my first post that whenever possible, keep your variables at minimum scope. That is to say, if only 1 function uses that variable, that variable should be initialized and contained in that function. This way we minimize unexpected behavior and ensures that for the same inputs, you get the same outputs. (There are reasons not to do this, and I am simplifying)

Your currency and changeArr are global variables. With initialization outside the scope of your checkCashRegister function. This means if you call checkCashRegister twice, the two arrays may have stuff left over from the last function call. So your console.log runs and changes your arrays, then FCC feeds the function its testcase, but at this point the two arrays are a bit messed up.

Simple fix is to just move the two arrays inside the function itself.
Hope that was clear :slight_smile:

1 Like

ahhh thank you! I can’t believe I didn’t realise I had declared them first outside the function.

I spent some time on what you said in your other reply, and after calculating the change near the end of the code I added:

var changeArrTotal = 0;

for (var j = 0; j < changeArr.length; j++) {
changeArrTotal += changeArr[j][1];
}

if (changeArrTotal !== (cash - price)) {
output.status = “INSUFFICIENT_FUNDS”;
return output;
}

I made sure to use (cash - price) as I had already changed the value of “change”, and it works!!! I am so happy to have reached the end of this section haha

Thanks for all your tips and advice, hope you have a wonderful day :grin:

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.