Build a Cash Register Project - Build a Cash Register

Tell us what’s happening:

Hi All,

I am facing a very interesting issue with this project. Depending on what my “price” and “cid” variables are set to I am passing a different set of tests. Overall I am passing each test case, but not all simultaneously. I am unsure what to do at this point, as I dont really understand how can the behaviour of my code differ based on who initialised the variables (me explicitly, or the test case implicitly).

For easier debugging please find two comment sections at the beggining of my code. With the “LAST TEST” section, the inputs of the last test case are replicated, and by using this the code passes all but the first two test cases. With the “FIRST AND SECOND TEST” the input of the second testcase is replicated, and by using this the code passes all but the last test case.

Thank you very much for looking into this, and sorry for the spaghetti code, I am sitll a begginer.

Your code so far

<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <input id="cash"></input>
    <div id="change-due">asd</div>
    <button id="purchase-btn">Purchase</button>
    <script src="script.js"></script>
  </body>
</html>

/* LAST TEST */
/*
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]];
*/
/*LAST TEST END*/ 


/*FIRST AND SECOND TEST*/ 
let price = 19.5;
let cid = [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]];
/*FIRST AND SECOND TEST END*/ 



const order = ["ONE HUNDRED", "TWENTY", "TEN", "FIVE", "ONE", "QUARTER", "DIME", "NICKEL", "PENNY"];

const value = {"PENNY": 0.01,
                "NICKEL": 0.05,
                "DIME": 0.1,
                "QUARTER": 0.25,
                "ONE": 1,
                "FIVE": 5,
                "TEN": 10,
                "TWENTY": 20,
                "ONE HUNDRED": 100}

const cash = document.getElementById("cash");
const change = document.getElementById("change-due");
const purchaseBtn = document.getElementById("purchase-btn");

let change_amount_before;
let change_amount_after;
const total_change_available = cid.reduce((to, el) => to + el[1], 0).toFixed(2);

function run(){
  console.log(`cash: ${cash.value}`)
  if (parseFloat(cash.value) < price){
    alert("Customer does not have enough money to purchase the item")
  }
  else if (parseFloat(cash.value) === price){    
    change.textContent = "No change due - customer paid with exact cash";
  }
  else {
    console.log(`different price`)
    const change_str = calc_change()
    const status = determine_status()
    let sol;
    if (status !== "Status: INSUFFICIENT_FUNDS"){
    sol = `${status} ${change_str.join(" ").replaceAll(",", ": $")}`
    }
    else {
      sol = `${status}`;
    }
    console.log("!!!!")
    console.log(sol)
    change.textContent = sol;
  }
};

function calc_change(){
  console.log("CALC_CHANGE");
  let change_amount = parseFloat(cash.value).toFixed(2) - price;
  change_amount_before = change_amount.toFixed(2);
  console.log(`change_amount: ${change_amount.toFixed(2)}`);
  let ret = []

  for (let i = cid.length-1; i>-1; i--){
    let nameOfNote = cid[i][0];
    let valueOfNote = value[nameOfNote];
    let remainingValueInNote = cid[i][1];
    let givingBack = [nameOfNote, 0]

    if (remainingValueInNote !== 0 && change_amount !== 0){
      //console.log(`remainingValueInNote: ${remainingValueInNote}`)
      while (remainingValueInNote - valueOfNote >= 0 && change_amount - valueOfNote >= 0){
        givingBack[1] += valueOfNote;
        remainingValueInNote -= valueOfNote;
        remainingValueInNote = remainingValueInNote.toFixed(2);
        cid[i][1] -= valueOfNote;
        cid[i][1] = cid[i][1].toFixed(2)
        change_amount -= valueOfNote;
        change_amount = change_amount.toFixed(2);

        console.log(`Giving back another ${nameOfNote}! Remaining change to give: ${change_amount}`);  
      }
      if (givingBack[1] !== 0){
        givingBack[1] = stripTrailingZeros(givingBack[1]);
        //givingBack[1] = givingBack[1].toFixed(1);
        //givingBack[1] = parseFloat(givingBack[1]).toString();
        //givingBack[1] = parseFloat(givingBack[1]);
        ret.push(givingBack);
        console.log("-----");
        console.log(givingBack);
        console.log("-----");
      }
    }
    
  }
  console.log(ret);
  console.log("-----");
  console.log(cid);
  console.log("-----");
  console.log(change_amount);
  change_amount_after = change_amount;
  return ret;
}

function determine_status(){
  console.log("DETERMINE_STATUS")
  console.log(`change_amount_after: ${change_amount_after}`);
  console.log(`change_amount_before: ${change_amount_before}`);
  //const total_change_available = cid.reduce((to, el) => to + el[1], 0).toFixed(2);
  //const total_change_available = cid.reduce((to, el) => to + el[1], 0);
  console.log(`total_change_available: ${total_change_available}`);


  console.log(parseFloat(change_amount_before).toFixed(2) > parseFloat(total_change_available).toFixed(2));
  console.log(parseFloat(change_amount_after) !== 0);


  if (parseFloat(change_amount_before) > parseFloat(total_change_available)  || parseFloat(change_amount_after) !== 0){
    console.log("Returning:  INSUFFICIENT_FUNDS")
    return "Status: INSUFFICIENT_FUNDS";
  }
  else if (total_change_available === change_amount_before){
    console.log("Returning:  CLOSED")
    return "Status: CLOSED";
  }
  else{
    console.log("Returning OPEN")
    return "Status: OPEN"
  }

}

function stripTrailingZeros(num) {
  let formattedString = num.toFixed(2); // Convert to string with 2 decimal places
  formattedString = formattedString.replace(/\.?0*$/, ''); // Remove trailing zeros

  return parseFloat(formattedString); // Convert back to float
}


purchaseBtn.addEventListener("click", run);

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36

Challenge Information:

Build a Cash Register Project - Build a Cash Register

That suggests function calculating result depends on some variables defined outside of the function scope - in global scope, other than the expected cid, price and #cash element. When code is changed manually, the preview is reloaded, effectively running all the code again, so whatever else function depends on, it has updated value.
On the other hand, tests don’t reload whole page, they just modify the current value of cid, price and #cash. Meanwhile there are parts that still have the initial value from when preview loaded.

Just to make sure I understand correctly what you are saying: Are you suggesting that I rewrite the functions so that they take arguments and that somehow would change the scope of variables from global to local, which would solve the issue?

Not exactly. When outdated value would be passed to function, it still would be outdated.

Consider a bit abstract example, this is the current state.

// (1) some calculations

function f() {
  // (2) some calculations depending on values calculated in (1)
}
1 Like

You are an absolute legend!
Took me a few hours but I got there.
Thank you very much for helping without solving the issue instead of me.

1 Like

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