Cash Register failing test #4 #5 and #10

Tell us what’s happening:

My cash register finally works, still three of the tests fail. I can’t see why though, because my results are exactly what is asked. I have seen some other posts and noticed everyone seems to be frustrated with this one, but the posts didn’t helpt me solve the problem.

Now it may not be the best or most efficient code and I tried to explain the steps with comments as best as I could. I created a resetCid() so it’s easier for me to test the scenarios. I also created an array containing the unit’s values so it doesn’t take out too much, and I multiplied everythig by 100 to avoid the typival problems with numbers.

I’d be glad if someone could help me with this one. Thanks in advance!

Your code so far

let price = 3.26;
let cid = [
  ["PENNY", 0.5],
  ["NICKEL", 0],
  ["DIME", 0],
  ["QUARTER", 0],
  ["ONE", 0],
  ["FIVE", 0],
  ["TEN", 0],
  ["TWENTY", 0],
  ["ONE HUNDRED", 0]
];

const cashValues = [
["PENNY", 1],
  ["NICKEL", 5],
  ["DIME", 10],
  ["QUARTER", 25],
  ["ONE", 100],
  ["FIVE", 500],
  ["TEN", 1000],
  ["TWENTY", 2000],
  ["ONE HUNDRED", 10000]
]

const cashInput = document.querySelector("#cash");
const changeDue = document.getElementById("change-due");
const purchaseBtn = document.getElementById("purchase-btn");
const cashDrawer = document.getElementById("cash-drawer-display");
const priceScreen = document.getElementById("price-screen");

const priceCent = price * 100;
//let cash = parseFloat(cashInput.value) * 100;

//calculate how much change is due
const calculateChange = (a, b) => {return a - b};

// calculate money in register
const calculateCid = (num) => {
  let all = 0;
for (let i = 0; i < cid.length; i++){
  all += cid[i][1] * 100;
}
return all;
};

// show price an change on sreen, update status and start loop to take out change
const takeChange = (change) => {
        priceScreen.innerHTML =`Total: $${price} Change: $${change / 100}`;

  if (calculateCid() - change == 0)  {
          changeDue.innerHTML = `<p>Status: CLOSED</p>`;
          forLoop(change);
          return;
    }
    else {
      changeDue.innerHTML = `<p>STATUS: OPEN</p>`;
      forLoop(change);
      return;
    }
};

// check if unit's empty
const isEmpty = (i) => {
  return cid[i][1] >= 0 ? i-- : i;
};

/* check for all items in array if unit is needed, how many units ought to be taken out and if unit is available,
keep track of change, take change out of register array, check if funds sufficient and update changeDue text
*/ 
const forLoop = (change) => {
  let giveBack = 0;
  let rest = change;
  let totalChange = [];

  for (let i = cid.length - 1; i >= 0; i--) {
        if (change >= cashValues[i][1]) {
            isEmpty(i);
            rest =  change;
            giveBack = 0;
            let temp = cid[i][1] * 100;
            while (temp - cashValues[i][1] >= 0 && change >= cashValues[i][1])
            {
              temp -= cashValues[i][1];
              rest -= cashValues[i][1]; 
              giveBack += cashValues[i][1];
              change = rest;
              cid[i][1] = temp /100;  
}   
            if (giveBack) {
              totalChange.push("<p>"+cid[i][0] +": $"+giveBack/100+"</p>");
            }
        }
      }      
            if (rest != 0 && changeDue.innerHTML != `<p>Status: CLOSED</p>`) {
            changeDue.innerHTML = `<p>Status: INSUFFICIENT_FUNDS</p>`;
            return; 
            }
            
      changeDue.innerHTML += `<p>${totalChange.join("")}</p>`
};

// reset changeDue, define change, calculate register value, take change out of register and update cashDrawer
const giveChange = (cash) => {
  changeDue.innerHTML = "";
  let change = calculateChange(parseFloat((cashInput.value) * 100), priceCent);
  calculateCid();
  takeChange(change);
  showRegister();
  //resetCid();
};

// update register in cashDrawer
const showRegister = () => {
  cashDrawer.innerHTML = 
  `<p>Change in drawer:</p>
  <p>Pennies: $${cid[0][1]}</p>
  <p>Nickels: $${cid[1][1]}</p>
  <p>Dimes: $${cid[2][1]}</p>
  <p>Quarters: $${cid[3][1]}</p>
  <p>Dollars: $${cid[4][1]}</p>
  <p>Five Dollars: $${cid[5][1]}</p>
  <p>Ten Dollars: $${cid[6][1]}</p>
  <p>Twenty Dollars: $${cid[7][1]}</p>
  <p>One Hundred Dollars: $${cid[8][1]}</p>`;
};

// reset register for testing
const resetCid = () => {
  cid = [
  ["PENNY", 1.01],
  ["NICKEL", 2.05],
  ["DIME", 3.1],
  ["QUARTER", 4.25],
  ["ONE", 90],
  ["FIVE", 55],
  ["TEN", 20],
  ["TWENTY", 60],
  ["ONE HUNDRED", 100]
];
}

// check if enough cash
purchaseBtn.addEventListener("click", () => {
//resetCid();
  if(cashInput.value * 100 < priceCent) {
    alert("Customer does not have enough money to purchase the item");
    return;
  }
  else {
    if(cashInput.value * 100 == priceCent) {
      changeDue.innerHTML = `<p>No change due - customer paid with exact cash</p>`;
      return;
    }
    else {
      giveChange(cash);
    }
  }
});

WARNING

The challenge seed code and/or your solution exceeded the maximum length we can port over from the challenge.

You will need to take an additional step here so the code you wrote presents in an easy to read format.

Please copy/paste all the editor code showing in the challenge from where you just linked.

Your browser information:

User Agent is: Mozilla/5.0 (X11; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0

Challenge Information:

Build a Cash Register Project - Build a Cash Register

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Cash Register</title>
    <link rel="stylesheet" href="./styles.css" />
  </head>
  <body>
    <main>
      <h1>Cash Register Project</h1>
      <div id="change-due"></div>
      <div class="input-div">
        <label for="cash">Enter cash from customer:</label>
        <input type="input" id="cash" class="user-input" value="" />
        <button class="check-btn-styles" id="purchase-btn">Purchase</button>
      </div>
      <div class="container">
        <div class="top-display-screen-container">
          <p id="price-screen" class="price-screen"></p>
          <div class="connector"></div>
        </div>
        <div class="top-register">
          <div class="btns-container">
            <button class="btn"></button>
            <button class="btn"></button>
            <button class="btn"></button>
            <button class="btn"></button>
            <button class="btn"></button>
            <button class="btn"></button>
            <button class="btn"></button>
            <button class="btn"></button>
            <button class="btn"></button>
          </div>
          <div id="cash-drawer-display" class="cash-drawer-display"></div>
        </div>
        <div class="bottom-register">
          <div class="circle"></div>
        </div>
      </div>
    </main>
    <script src="./script.js"></script>
  </body>
</html>

When price and cid are changed manually in code, the preview is reloaded, resulting in all JS being executed. On the other hand when tests are run, the preview is not reloaded.

Situation when former is working fine, but later fail, suggests code depends on some additional global variables, than the expected (cid, price and #cash element). When further tests are run, part of the code is stuck with the initial values when preview was loaded.

I don’t really get it. How can I test this myself to find out which variables don’t work? I can’t find any global variables, I put everything inside the functions. Is it possible to test this somehow?

There’s couple things that might help with pin pointing to the exact variable:

  • Going through code, skipping functions, and analyze which variables contain something calculated just once.
  • Going through functions, looking for variables that are from outside of the function scope.
  • Using console.log to print to console values of suspects and checking console after running tests.

forLoop function isn’t defined yet, if you want it to work you should move the function definition up or change the arrow syntax to normal syntax .
Arrow functions cannot be accessed before initialization.

That’s not an issue here. If it would, there would be quite different errors, and manually trying test cases also wouldn’t work.

The price variable was the problem. Thanks for the help!

You can think of code as running in two stages. A setup stage and an execution stage.

Because forLoop is called inside a function by the time takeChange runs the definition of forLoop is able to be used.

This doesn’t work:

logValue('Value') // ReferenceError: logValue is not defined
const logValue = (val) => console.log(val)

This also doesn’t work:

const outerFn = (val) => logValue(val);
outerFn("Value"); // ReferenceError: logValue is not defined

const logValue = (val) => console.log(val);

This does work:

// The order of the two functions doesn't matter either
const outerFn = (val) => logValue(val);
const logValue = (val) => console.log(val); // Value

outerFn("Value");
1 Like

thank you for taking the time to clarify this concept to me

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