Build a Cash Register Project - Build a Cash Register

Tell us what’s happening:

please help me figure out the issue. everything works well. code is fine (i think) but the last several task don’t check. to make some of them checked i even added “cidd” variable but now there are more that don’t check. please help me what is wrong with it.

Your code so far

<!-- file: index.html -->

/* file: script.js */

let price = 1.87;
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 cidd = [
  ['PENNY', 1.01, 0.01],
  ['NICKEL', 2.05, 0.05],
  ['DIME', 3.1, 0.1],
  ['QUARTER', 4.25, 0.25],
  ['ONE', 90, 1],
  ['FIVE', 55, 5],
  ['TEN', 20, 10],
  ['TWENTY', 60, 20],
  ['ONE HUNDRED', 100, 100]
];

let change = [];
let status = 'OPEN';

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

const calculate = (inp) => {
  const inpNumber = (parseFloat(inp) - price);
  let number = inpNumber;
  let division;

  if(inpNumber > cidd.reduce((sum, item) => sum + item[1], 0)){
    status = "INSUFFICIENT_FUNDS";
    updateChangeDue(inpNumber);
    return;
  }else if(inpNumber === cidd.reduce((sum, item) => sum + item[1], 0)){
    status = "CLOSED";
  }else if(inpNumber === 0){
    updateChangeDue(inpNumber);
    return;
  }else if(inpNumber < 0){
    alert("Customer does not have enough money to purchase the item")
    return;
  }else if(!inpNumber){
    return;
  }else{
    status = "OPEN";
  }

  for(let i = 8; i >= 0; i--){
    if(Math.floor(number / cidd[i][2]) >= 1){
      division = Math.floor(number / cidd[i][2]) * cidd[i][2] > cidd[i][1] ? cidd[i][1] : Math.floor(number / cidd[i][2]) * cidd[i][2];
      change.push({ [cidd[i][0]]: division});
      number = (number - division).toFixed(2);
      cidd[i][1] -= division;
      cid[i][1] = division;
    } 
  }
  updateChangeDue(inpNumber);
}
const updateChangeDue = (num) => {

  changeDue.style.display = "block";
  if(num === 0){
    changeDue.textContent = "No change due - customer paid with exact cash";
  }else{
    const changeString = change.map(item => {
      const key = Object.keys(item)[0];
      return `${key}: $${item[key]} </br>`;
    }).join("");
    changeDue.innerHTML = `Status: ${status}</br>${changeString}`
  }
  console.log(cid, change)
}

purchaseBtn.addEventListener("click", () => {
  change = [];
  calculate(cashInput.value);
})
/* file: styles.css */


Your browser information:

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

Challenge Information:

Build a Cash Register Project - Build a Cash Register

Please post your code.

can you also post the html?

any reason why these two are declared in the global scope?
(declaring code in the global scope that can be changed by a function is usually dangerous)

please help me figure out the issue. everything works well. code is fine (i think) but the last several tasks don’t check. to make some of them checked i even added “cidd” variable but now there are more that don’t check. please help me what is wrong with it.

tasks that I cannot solve:

    1. When price is less than the value in the #cash element, total cash in drawer cid is greater than the change due, individual denomination amounts allows for returning change due, and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: OPEN" with required change due in coins and bills sorted in highest to lowest order.
    1. When price is 19.5, the value in the #cash element is 20, cid is [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]], and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: INSUFFICIENT_FUNDS"
    1. When the price is less than the value in the #cash element and the total cash in the drawer (cid) is insufficient to cover the change due, the purchase should not proceed. When the #purchase-btn is clicked under these conditions, the #change-due element should display "Status: INSUFFICIENT_FUNDS".
    1. When price is 19.5, the value in the #cash element is 20, cid is [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 1], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]], and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: INSUFFICIENT_FUNDS".
    1. When price is less than the value in the #cash element, total cash in drawer cid is greater than change due, but the individual denomination amounts make it impossible to return needed change, when the #purchase-btn element is clicked, the value in the #change-due element should be "Status: INSUFFICIENT_FUNDS"
    1. When price is 19.5, the value in the #cash element is 20, cid is [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]], and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: CLOSED PENNY: $0.5".
    1. When price is less than the value in the #cash element, total cash in drawer cid is equal to change due, and the #purchase-btn element is clicked, the value in the #change-due element should be "Status: CLOSED" with change due in coins and bills sorted in highest to lowest order.

HTML code:

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="utf-8" />
    <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</h1>
    <label for="cash">Enter costumer's cash</label>
    <input id="cash" type="number" />
    <button id="purchase-btn">Purchase</button>
    <div id="change-due"></div>
    <div id="cash-desk">
      <div id="money"></div>
      <div id="screen">Total: 3.26</div>
      <div id="buttons">
        <div class="button1"></div>
        <div class="button1"></div>
        <div class="button1"></div>
        <div class="button1"></div>
        <div class="button1"></div>
        <div class="button1"></div>
        <div class="button1"></div>
        <div class="button1"></div>
        <div class="button1"></div>
      </div>
    </div>
    <script src="./script.js"></script>
  </body>
</html>
type or paste code here
JavaScript code: 
let price = 1.87;
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 cidd = [
  ['PENNY', 1.01, 0.01],
  ['NICKEL', 2.05, 0.05],
  ['DIME', 3.1, 0.1],
  ['QUARTER', 4.25, 0.25],
  ['ONE', 90, 1],
  ['FIVE', 55, 5],
  ['TEN', 20, 10],
  ['TWENTY', 60, 20],
  ['ONE HUNDRED', 100, 100]
];

let change = [];
let status = 'OPEN';

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

const calculate = (inp) => {
  const inpNumber = (parseFloat(inp) - price);
  let number = inpNumber;
  let division;

  if(inpNumber > cidd.reduce((sum, item) => sum + item[1], 0)){
    status = "INSUFFICIENT_FUNDS";
    updateChangeDue(inpNumber);
    return;
  }else if(inpNumber === cidd.reduce((sum, item) => sum + item[1], 0)){
    status = "CLOSED";
  }else if(inpNumber === 0){
    updateChangeDue(inpNumber);
    return;
  }else if(inpNumber < 0){
    alert("Customer does not have enough money to purchase the item")
    return;
  }else if(!inpNumber){
    return;
  }else if(price < cashInput.value && price != cashInput.value){
    status = "OPEN";
  }

  for(let i = 8; i >= 0; i--){
    if(Math.floor(number / cidd[i][2]) >= 1){
      division = Math.floor(number / cidd[i][2]) * cidd[i][2] > cidd[i][1] ? cidd[i][1] : Math.floor(number / cidd[i][2]) * cidd[i][2];
      change.push({ [cidd[i][0]]: division});
      number = (number - division).toFixed(2);
      cidd[i][1] -= division;
      cid[i][1] = division;
    } 
  }
  updateChangeDue(inpNumber);
}

const updateChangeDue = (num) => {

  changeDue.style.display = "block";
  if(num === 0){
    changeDue.textContent = "No change due - customer paid with exact cash";
  }else{
    const changeString = change.map(item => {
      const key = Object.keys(item)[0];
      return `${key}: $${item[key]} </br>`;
    }).join("");
    changeDue.innerHTML = `Status: ${status}</br>${changeString}`
  }
}

purchaseBtn.addEventListener("click", () => {
  change = [];
  calculate(cashInput.value);
})
type or paste code here

get rid of this. You should not have code in the global scope other than the ones given price and cid.

also get rid of this:

Keep all the code in the functions that run when a purchase button is clicked.

The tests do not load the code except one time so anything in the global scope will be out-of-date as soon as the next test runs.

but if i remove them this code won’t work. you see in cidd there are extra values that i need to calculate. if i remove that and change and status, i will have to change the whole code. you think there is no other solution?

yes you have to change the code. Move these into the functions you are using and use parameters if you need to pass them to other functions.

i have changed this like that like that and now something interesting is going on. when pressing ctrl + enter repeatedly, 13th task sometimes becomes checked sometimes unchecked. all the rest code remains unchecked. can you help me out?

js:


let price = 1.87;
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]
];





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

const calculate = (inp) => {
  let change = [];
  let status = 'OPEN';
  let cidd = [
    ['PENNY', 1.01, 0.01],
    ['NICKEL', 2.05, 0.05],
    ['DIME', 3.1, 0.1],
    ['QUARTER', 4.25, 0.25],
    ['ONE', 90, 1],
    ['FIVE', 55, 5],
    ['TEN', 20, 10],
    ['TWENTY', 60, 20],
    ['ONE HUNDRED', 100, 100]
  ];
  const inpNumber = (parseFloat(inp) - price);
  let number = inpNumber;
  let division;

  if(inpNumber > cidd.reduce((sum, item) => sum + item[1], 0)){
    status = "INSUFFICIENT_FUNDS";
    updateChangeDue(inpNumber, change, status, cidd);
    return;
  }else if(inpNumber === cidd.reduce((sum, item) => sum + item[1], 0)){
    status = "CLOSED";
  }else if(inpNumber === 0){
    updateChangeDue(inpNumber, change, status, cidd);
    return;
  }else if(inpNumber < 0){
    alert("Customer does not have enough money to purchase the item")
    return;
  }else if(!inpNumber){
    return;
  }else if(price < cashInput.value && price != cashInput.value){
    status = "OPEN";
  }

  for(let i = 8; i >= 0; i--){
    if(Math.floor(number / cidd[i][2]) >= 1){
      division = Math.floor(number / cidd[i][2]) * cidd[i][2] > cidd[i][1] ? cidd[i][1] : Math.floor(number / cidd[i][2]) * cidd[i][2];
      change.push({ [cidd[i][0]]: division});
      number = (number - division).toFixed(2);
      cidd[i][1] -= division;
      cid[i][1] = division;
    } 
  }
  updateChangeDue(inpNumber, change, status, cidd);
}

const updateChangeDue = (num, change, status, cidd) => {

  changeDue.style.display = "block";
  if(num === 0){
    changeDue.textContent = "No change due - customer paid with exact cash";
  }else{
    const changeString = change.map(item => {
      const key = Object.keys(item)[0];
      return `${key}: $${item[key]} </br>`;
    }).join("");
    changeDue.innerHTML = `Status: ${status}</br>${changeString}`
  }
}

purchaseBtn.addEventListener("click", () => {
  
  calculate(cashInput.value);
})
type or paste code here

have you fixed the issues we discussed? if yes, please post the new code in full.

that is the whole js code, and yes i have put change, status and cidd variables into the function and use parameters to pass them to other functions.

okay I’ll try it now. I edited your post slightly so the code was the only thing in the backticks area.

okay, let’s work through this one problem at a time.
for me the first issue I see is test #14.
When you have these values:

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

And you type 20 in the input, instead of getting Status: INSUFFICIENT_FUNDS we get instead:
Status: OPEN QUARTER: $0.5

So start there. Work on fixing this. Then we can move on to the next issue.

(for eg. why does quarter say 0.5 when there are no quarters in cid at all?)

okay let me take my time to make some changes i think i got it.

This is suspicious…

okay that worked. what i have done is that in if statements i changed cidd with cid and 14th and 15th and 19th got checked. i have left 16th 17th and 18th. thanks for that

let price = 1.87;
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]
];





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

const calculate = (inp) => {
  let change = [];
  let status = 'OPEN';
  let cidd = [
    ['PENNY', 1.01, 0.01],
    ['NICKEL', 2.05, 0.05],
    ['DIME', 3.1, 0.1],
    ['QUARTER', 4.25, 0.25],
    ['ONE', 90, 1],
    ['FIVE', 55, 5],
    ['TEN', 20, 10],
    ['TWENTY', 60, 20],
    ['ONE HUNDRED', 100, 100]
  ];
  const inpNumber = (parseFloat(inp) - price);
  let number = inpNumber;
  let division;

  if(inpNumber > cid.reduce((sum, item) => sum + item[1], 0)){
    status = "INSUFFICIENT_FUNDS";
    updateChangeDue(inpNumber, change, status, cid);
    return;
  }else if(inpNumber === cid.reduce((sum, item) => sum + item[1], 0)){
    status = "CLOSED";
  }else if(inpNumber === 0){
    updateChangeDue(inpNumber, change, status, cid);
    return;
  }else if(inpNumber < 0){
    alert("Customer does not have enough money to purchase the item")
    return;
  }else if(!inpNumber){
    return;
  }else if(price < cashInput.value && price != cashInput.value){
    status = "OPEN";
  }

  for(let i = 8; i >= 0; i--){
    if(Math.floor(number / cidd[i][2]) >= 1){
      division = Math.floor(number / cidd[i][2]) * cidd[i][2] > cidd[i][1] ? cidd[i][1] : Math.floor(number / cidd[i][2]) * cidd[i][2];
      change.push({ [cidd[i][0]]: division});
      number = (number - division).toFixed(2);
      cidd[i][1] -= division;
      cid[i][1] = division;
    } 
  }
  updateChangeDue(inpNumber, change, status, cidd);
}

const updateChangeDue = (num, change, status, cidd) => {

  changeDue.style.display = "block";
  if(num === 0){
    changeDue.textContent = "No change due - customer paid with exact cash";
  }else{
    const changeString = change.map(item => {
      const key = Object.keys(item)[0];
      return `${key}: $${item[key]} </br>`;
    }).join("");
    changeDue.innerHTML = `Status: ${status}</br>${changeString}`
  }
}

purchaseBtn.addEventListener("click", () => {
  
  calculate(cashInput.value);
})
type or paste code here

no problem. Keep debugging. Remember that the tests run in sequence, so sometimes it helps to find the right way of testing to break the code (by making specific inputs to force the cid to get to a specific point to trigger a condition for eg)