Build a Cash Register Project - Build a Cash Register

Tell us what’s happening:

I believe my solution is complete, but the cases seem to fail even with what I believe is the correct output.

I manually tested these myself by inputting the values in, and everything seems correct for all of the test cases.

For some reason the test cases seem to fail according to what I have within the cid variable.
For example, when I have the cid from the last test case, test 6 7 and 9 pass, but when I change my cid to the one in test case 9, then test cases 8 and 9 pass. All this happens without any change to the code other than the cid variable.

Also, for test 9, my output in change-due is the same exact string as what the test requires.

Your code so far

<!-- file: index.html -->
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="content" width="width=content-width, initial-scale=1.0">
  <link href="styles.css">
</head>
<body>
  <header>Cash Register</header>
  <main>
    <form>
      <label for="cash">Enter the cash amount being given:</label>
      <input type="number" step="0.01" id="cash"/>
      <button type="submit" id="purchase-btn">Purchase</button>
    </form>

    <header>Amount Due:</header>
    <div id="amount-due"></div>
    <header>Change Due:</header>
    <div id="change-due"></div>
    
    <div id="register-container"></div>
  </main>
</body>
<script src="script.js"></script>
</html>
/* file: styles.css */

/* file: script.js */
let price = 19.5;
let cid = [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]];
let values = [
  ["PENNY", 0.01],
  ["NICKEL", 0.05],
  ["DIME", 0.1],
  ["QUARTER", 0.25],
  ["ONE", 1],
  ["FIVE", 5],
  ["TEN", 10],
  ["TWENTY", 20],
  ["ONE HUNDRED", 100]
];
let sum = 0;

const registerContainer = document.getElementById("register-container");
const changeDue = document.getElementById("change-due");
const amountDue = document.getElementById("amount-due");
const cash = document.getElementById("cash");
const purchaseBtn = document.getElementById("purchase-btn");

const updateRegisterSum = () => {
  sum = 0;
  for (let i = 0; i < cid.length; i++) {
    sum += cid[i][1];
  }
  sum = Math.round(sum * 100) / 100;

  registerContainer.innerHTML = `Register Cash : ${sum}`;
}

const getChange = () => {
  changeDue.textContent = "";

  if (cash.value === "") {
    alert("Please enter a cash amount.");
    return;
  }

  if (price == cash.value) {
    changeDue.textContent = "No change due - customer paid with exact cash";
    return;
  }
  if (cash.value < price) {
    alert("Customer does not have enough money to purchase the item");
    return;
  }
  if (sum < cash.value - price) {
    changeDue.textContent += "Status: INSUFFICIENT_FUNDS";
    return;
  }

  let temp = cash.value - price;
  let currValuesIdx = values.length - 1;
  let change = [];

  while (temp > 0 && currValuesIdx >= 0) {
    let count = Math.floor(temp / values[currValuesIdx][1]); 
    let remainder = temp % values[currValuesIdx][1];

    if (count === 0) {
      currValuesIdx--;
      continue;
    }
    if (cid[currValuesIdx][1] === 0) {
      temp = remainder + count * values[currValuesIdx][1];
      currValuesIdx--;
      continue;
    }
    if (count * values[currValuesIdx][1] > cid[currValuesIdx][1]) {
      if (cid[currValuesIdx][1] !== 0) {
        remainder += count * values[currValuesIdx][1] - cid[currValuesIdx][1];
      }
      change.push([values[currValuesIdx][0], Math.floor(cid[currValuesIdx][1] / values[currValuesIdx][1])]);
      cid[currValuesIdx][1] = 0;
    }
    else {
      cid[currValuesIdx][1] -= count * values[currValuesIdx][1];
      change.push([values[currValuesIdx][0], count]);
    }

    currValuesIdx--;
    temp = remainder;
    temp = Math.round(temp * 100) / 100;
  }
  
  updateRegister();

  if (sum === 0) {
    changeDue.textContent = "Status: CLOSED";
  }
  else { // register still has money
    changeDue.textContent = "Status:  OPEN"
  }

  change.forEach((el) => {
    let value = getDollarAmount(el[0], el[1])
    changeDue.textContent += ` ${el[0]}: \$${value}`
  });
};

const getDollarAmount = (denomination, count) => {
  for (let i = 0; i < values.length; i++) {
    if (values[i][0] === denomination) {
      return count * values[i][1];
    }
  }
  return 0;
}

const updateRegister = () => {
  updateRegisterSum();
  
  for (let i = 0; i < cid.length; i++) {
    const count = cid[i][1] / values[i][1];
    const roundedCount = Math.round(count * 100) / 100;
    registerContainer.innerHTML += `<p>${cid[i][0]}: ${roundedCount}</p>`;
  }

  amountDue.textContent = price;
}

window.onload = updateRegister();

purchaseBtn.addEventListener("click", getChange);

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:122.0) Gecko/20100101 Firefox/122.0

Challenge Information:

Build a Cash Register Project - Build a Cash Register

1 Like

When cid or price are changed manually in code, the preview is reloaded and whole code is executed again. On the other hand, tests are changing only cid, price and #cash element, without reloading page.

This means if there’s some code that’s executed only when preview is reloaded, it will not be executed during the tests. The result is unexpected side-effects and different results between manually checking case and running tests automatically.

To summarize - there appears to be pieces (variables) that are not always updated between the tests, but function depends on them.

2 Likes

That was it, thanks. I found that I needed to update the register sum elsewhere and fix some other bugs.

I had the same problem with manual tests succeeding and automatic tests failing. This solution helped me realise that I had to initialise the cash register object every time the get change button was pressed, rather than just once at the start of the script.