Project Feedback for Cash Register

Hey guys. I’m doing the last project for the JS certificate. Can’t see to pass two tests. Damn floating points. I need perspective. What am I missing?

function checkCashRegister(price, cash, cid) {
  let statusArray = ["INSUFFICIENT_FUNDS", "CLOSED", "OPEN"];
  let currency = [0.01, 0.05, 0.1, 0.25, 1, 5, 10, 20, 100];

  let change = cash - price;

  let totalCash = 0;
  for(let i = 0; i < cid.length; i++) {
      totalCash += (cid[i][1]) * 100;
  }

  totalCash = totalCash / 100;
  
  let cashInRegister = [...cid];
  let receipt = {
    status: "",
    change : []
  };

  if(change > totalCash) {
    receipt.status = statusArray[0];
    receipt.change = [];
  } else if(change == totalCash) {
    receipt.status = statusArray[1];
    receipt.change = [...cashInRegister];
  } else {
    
    let matchesGreaterThanChange = [];
    for(let i = cashInRegister.length - 1; i >= 0; i--) {
      if(change > cashInRegister[i][1] && cashInRegister[i][1] != 0) {
        console.log(cashInRegister[i][1]);
        console.log(change);
        receipt.change.push(cashInRegister[i][0]);
        change -= currency[i];
        cashInRegister[i][1] -= currency[i];
        matchesGreaterThanChange.push(cashInRegister[i][1]);
      }
    }

    if(change > matchesGreaterThanChange[matchesGreaterThanChange.length - 1]) {
      receipt.status = statusArray[0];
      receipt.change = [];
    } else {
      receipt.status = statusArray[2];
    }
  }

  console.log(totalCash);
  console.log("Change: " + change);
  console.log(receipt.status + " and " + receipt.change);
  // Here is your change, ma'am.
  return receipt;
}

// Example cash-in-drawer array:
// [["PENNY", 1.01],
// ["NICKEL", 2.05],
// ["DIME", 3.1],
// ["QUARTER", 4.25],
// ["ONE", 90],
// ["FIVE", 55],
// ["TEN", 20],
// ["TWENTY", 60],
// ["ONE HUNDRED", 100]]

checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]);

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]]);

I had the same difficulties you’re having with that challenge in regards to the way floats will throw you off. Have you tried doing a google search for rounding floats to two decimal places in javascript?

You need to use this to round to the nearest two decimal point.

.toFixed(2)

However, this will return a string. So make sure you convert it back to float again after rounding it.

parseFloat()

Yeah I wasn’t quite prepared. I did round it off by multiplying by hundered, summing it up and then dividing it by a hundred. That seems to work.

I’m getting the hang of rounding the numbers. But now I am stuck at the loop. i want it to loop for as long as the change is greater than the cash in the category. I tried doing a while loop inside the if statement but I can’t break it and it goes into the negatives.

function checkCashRegister(price, cash, cid) {
  let statusArray = ["INSUFFICIENT_FUNDS", "CLOSED", "OPEN"];
  let currency = [0.01, 0.05, 0.1, 0.25, 1, 5, 10, 20, 100];

  let change = cash - price;

  let totalCash = 0;
  for(let i = 0; i < cid.length; i++) {
      totalCash += (cid[i][1]) * 100;
  }

  totalCash = totalCash / 100;
  
  let cashInRegister = [...cid];
  let receipt = {
    status: "",
    change : []
  };

  if(change > totalCash) {
    receipt.status = statusArray[0];
    receipt.change = [];
  } else if(change == totalCash) {
    receipt.status = statusArray[1];
    receipt.change = [...cashInRegister];
  } else {
    
    let matchesGreaterThanChange = [];
    for(let i = cashInRegister.length - 1; i >= 0; i--) {
      if(change >= cashInRegister[i][1] && cashInRegister[i][1] != 0) {
        console.log("Cash: " + cashInRegister[i][1]);
        console.log("Currency: " + currency[i])
        console.log("Change: " + change);
        console.log();
        receipt.change.push(cashInRegister[i][0]);
        change -= currency[i];
        cashInRegister[i][1] -= currency[i];
        matchesGreaterThanChange.push(cashInRegister[i][1]);
      }
    }

    if(change > matchesGreaterThanChange[matchesGreaterThanChange.length - 1]) {
      receipt.status = statusArray[0];
      receipt.change = [];
    } else {
      receipt.status = statusArray[2];
    }
  }

  console.log(totalCash);
  console.log("Change: " + change);
  console.log(receipt.status + " and " + receipt.change);
  // Here is your change, ma'am.
  return receipt;
}

// Example cash-in-drawer array:
// [["PENNY", 1.01],
// ["NICKEL", 2.05],
// ["DIME", 3.1],
// ["QUARTER", 4.25],
// ["ONE", 90],
// ["FIVE", 55],
// ["TEN", 20],
// ["TWENTY", 60],
// ["ONE HUNDRED", 100]]

checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]);

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]]);

This is a good start, but you also need to do this as you update the change value inside the loop (e.g. you have 0.3 in due change and subtract 0.2 for two dimes, → 0.3 - 0.2 will give you 0.09999999999999998). Imho it’s best to work in pennies and only convert back to dollars for the output.

You don’t really need an inner loop here. You can directly calculate how much cash from that category should be used for the change based on the currency and the remaining change.

Hey check out my most recent post about this project. It has updated code.