JS Beta Project 4: Cash Register - correct output not passing FCC test

Hello! My code passes the test cases in the sense that it provides the corrects status and change due when the purchase button is clicked, however many of the FCC tests (6, 8, and 9) do not pass.

Any tips very appreciated!

const cash = document.getElementById("cash");
const priceField = document.getElementById("price-field");
const purchaseBtn = document.getElementById("purchase-btn");
const changeDueDiv = document.getElementById("change-due");
const clearBtn = document.getElementById("clear-btn");

let price = 3.26;
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]
];
// let cid = [
//   ["PENNY", 0.5],
//   ["NICKEL", 0],
//   ["DIME", 0 ],
//   ["QUARTER", 0],
//   ["ONE", 0],
//   ["FIVE", 0],
//   ["TEN", 0],
//   ["TWENTY", 0],
//   ["ONE HUNDRED", 0]
// ];

const currencyArr = [10000, 2000, 1000, 500, 100, 25, 10, 5, 1];
//let reversedCid = [...cid].reverse(); // shallow copies :(
let reversedCid = JSON.parse(JSON.stringify(cid)).reverse(); // Deep copy (a bit weird, probably more standard way to do this)
// console.log("----")
// console.log(cid)
// console.log(reversedCid)

// cid[0][1] = 100
// console.log("Set to 100")

// console.log(cid)
// console.log(reversedCid)
// console.log("----")


let resultArr = [];
let changeBackArr = [];

priceField.innerText = `Price: ${price}`

// changeDue function
const changeDue = (cash, price) => {
  let change = 0;
  price = (price * 100);
  cash = (cash.value * 100);
  change = ((cash - price)/100);  
  return change; }; 

// My initial approach to cidSum
const cidSum = (cid) => { 

  //console.log(cid[0][1]); // reads 0
  let sum = 0;
  for(let i=0; i<cid.length; i++){
     sum += cid[i][1];
  } 
return sum; };

// // Update cid function
const updateCid = (cash, price) => { 
  let count = 0;
  let change = (changeDue(cash, price))*(100); 
  reversedCid.forEach((element)=>{
    element[1] *= 100; // multiplies $ values by 100
    element[1] = Math.ceil(element[1]); // rounds up
  })
  
  for (let i = 0; i < reversedCid.length; i++) {
    while(change >= currencyArr[i] && change > 0 && reversedCid[i][1] >= currencyArr[i]){
      reversedCid[i][1] -= currencyArr[i];
      change -= currencyArr[i];
      count++;
      if(count > 0){
      resultArr.push([reversedCid[i][0], currencyArr[i]]);
    }  
  }
 } changeBackArr  = resultArr.reduce((acc, [label, value]) => {
    const existingItem = acc.find(item => item[0] === label);
    if (existingItem) { 
        existingItem[1] += value;
    } else {
        acc.push([label, value]);
    }
    return acc;
}, []);

};

// // Register Status Function 
const regStatus = (cash,price,cid) =>{
  // console.log(cid);
  updateCid(cash,price); 
  // console.log(cid);
  let change = changeDue(cash, price); 
  let sum = (cidSum(cid));
  // console.log(sum);
  // console.log(changeBackArr);
  cash = (cash.value * 100);
  price = (price * 100);
  
  if(cash < price){ 
    alert("Customer does not have enough money to purchase the item");
  } else if(cash === price){
  changeDueDiv.textContent = `No change due - customer paid with exact cash`
  } else if(sum < change && change > 0 ){   
  changeDueDiv.textContent = `Status: INSUFFICIENT_FUNDS`;
  } else if(sum === change || (sum-change <= 0)){
  changeDueDiv.textContent = `Status: CLOSED`;
  for(let i=0; i<changeBackArr.length; i++){
      changeDueDiv.textContent += ` ${changeBackArr[i][0]}: $${((changeBackArr[i][1])/100)}`;
    }
  } else if(cidSum > changeDue){
    changeDueDiv.textContent = `Status: OPEN`;
    for(let i=0; i<changeBackArr.length; i++){
      changeDueDiv.textContent += ` ${changeBackArr[i][0]}: $${((changeBackArr[i][1])/100)}`;
    }} 
}


// Purchase Button + changeDue Function
purchaseBtn.addEventListener("click", () => {
  // add every function here so it is called with "click" 
  // cidSum(cid);
  changeDue(cash, price);
  regStatus(cash, price, cid);
});


this is my HTML is that is relevant as well. I did not use CSS in this challenge

<!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>
    <h1>Cash Register Project</h1>
    <h3 id="price-field"></h3>
    <div class="input-container">

      <label>Enter cash from customer:</label>
      <input id="cash" type="number" />
      <button id="purchase-btn">Purchase</button>
      <button id="clear-btn">Clear</button>
 
    </div>
    <div id="change-due">
    <output id="result" for="number-input"></output>
    </div>
    
    
    <script src="script.js"></script>
  </body>
</html>

You are barring the tests from ever changing the cid with this line. This is the root of your problem.

1 Like

Thanks for pointing that out - is it correct that I need to make a deep copy in this situation? Prior to making a deep copy I believe my test were failing because the reversedCid variable was impacting cid (from my understanding).

The tests will change the cid variable. Making a deep copy of anything won’t change that. You need to make sure you account for the fact that the tests can change the cid variable before any test runs.

Hello! I’ve reworked my solution to account for a changing cid variable, however test 7 and 9 still fail when my output looks correct. Any ideas to troubleshoot this?

const cash = document.getElementById("cash");
const priceField = document.getElementById("price-field");
const purchaseBtn = document.getElementById("purchase-btn");
const changeDueDiv = document.getElementById("change-due");
const clearBtn = document.getElementById("clear-btn");

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]
// ];
let cid = [
  ["PENNY", 0.01],
  ["NICKEL", 0],
  ["DIME", 0 ],
  ["QUARTER", 0],
  ["ONE", 0],
  ["FIVE", 0],
  ["TEN", 0],
  ["TWENTY", 0],
  ["ONE HUNDRED", 0]
];

const currencyArr = [1,5,10,25,100,500,1000,2000,10000];

let resultArr = [];
let changeBackArr = [];

priceField.innerText = `Price: ${price}`

// changeDue function
const changeDue = (cash, price) => {
  let change = 0;
  price = (price * 100);
  cash = (cash.value * 100);
  change = ((cash - price)/100);  
  return change; }; 

// My initial approach to cidSum
const cidSum = (cid) => { 

  //console.log(cid[0][1]); // reads 0
  let sum = 0;
  for(let i=0; i<cid.length; i++){
     sum += cid[i][1];
  } 
return sum; };

// // Update cid function
const updateCid = (cash, price) => { 
  let count = 0;
  let change = (changeDue(cash, price))*(100);
  cid.forEach((element)=>{
    element[1] *= 100; // multiplies $ values by 100
    element[1] = Math.ceil(element[1]); // rounds up
  })

for(let i=8; i>=0; i--){  
while(i>=0 && change >= currencyArr[i] && change > 0 && cid[i][1] >= currencyArr[i]){
      cid[i][1] -= currencyArr[i];
      change -= currencyArr[i];
      count++;  
    if(count > 0){
      resultArr.push([cid[i][0], currencyArr[i]]);
    }  
  }
} 
 changeBackArr  = resultArr.reduce((acc, [label, value]) => {
    const existingItem = acc.find(item => item[0] === label);
    if (existingItem) { 
        existingItem[1] += value;
    } else {
        acc.push([label, value]);
    }
    return acc;
}, []);
};

// // Register Status Function 
const regStatus = (cash,price,cid) =>{
  // console.log(cid);
  let sum = (cidSum(cid));
  updateCid(cash,price); 
  let change = changeDue(cash, price); 

  cash = (cash.value * 100);
  price = (price * 100);
  if(cash < price){ 
    alert("Customer does not have enough money to purchase the item");
  } else if(cash === price){
  changeDueDiv.textContent = `No change due - customer paid with exact cash`
  } else if(sum < change && change > 0 ){   
  changeDueDiv.textContent = `Status: INSUFFICIENT_FUNDS`;
  } else if(sum === change || (sum-change <= 0)){
  changeDueDiv.textContent = `Status: CLOSED`;
  for(let i=0; i<changeBackArr.length; i++){
      changeDueDiv.textContent += ` ${changeBackArr[i][0]}: $${((changeBackArr[i][1])/100)}`;
    }
  } else if(cidSum > changeDue){
    changeDueDiv.textContent = `Status: OPEN`;
    for(let i=0; i<changeBackArr.length; i++){
      changeDueDiv.textContent += ` ${changeBackArr[i][0]}: $${((changeBackArr[i][1])/100)}`;
    }} 
}

// Purchase Button + changeDue Function
purchaseBtn.addEventListener("click", () => {
  // add every function here so it is called with "click" 
  changeDue(cash, price);
  regStatus(cash, price, cid);
});