Build a Cash Register Project - Build a Cash Register

Tell us what’s happening: The last test fails even tho the output exactly matches the test expectations, this is my output:

Status: CLOSED PENNY: $0.5

I had heard on another thread here that this last test had a bug on fcc’s end, but that maybe it had been fixed by now?

If any more of my project info is needed let me know, thanks.

Your code so far

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.

let price = 19.50;
let cid = [
  ["PENNY", 0.50],
  ["NICKEL", 0.00],
  ["DIME", 0.00],
  ["QUARTER", 0.00],
  ["ONE", 0],
  ["FIVE", 0],
  ["TEN", 0],
  ["TWENTY", 0],
  ["ONE HUNDRED", 0]
];
let cash = 0.0;
let messages = ["Status: OPEN", "Status: CLOSED", "Status: INSUFFICIENT_FUNDS"];
let cond = 0;
let change = 0.0;
let drawer = 0.0;
let str = "";
let numberOfUnits = 0;
let multiplier = Float32Array.from([0.01, 0.05, 0.1, 0.25, 1.0, 5.0, 10.0, 20.0, 100.0]);
let purchaseBtn = document.getElementById("purchase-btn");
let unit = Int32Array.from([0, 0, 0, 0, 0, 0, 0, 0, 0]);
let changeDue = document.getElementById("change-due");
let itemPrice = document.getElementById("item-price");
let denominant = document.getElementById("change");
let clearBtn = document.getElementById("clear-btn");
let numIn = document.getElementById("cash");
changeDue.setAttribute("readonly", true);
itemPrice.setAttribute("readonly", true);
let elements = [document.getElementById("giveP"), document.getElementById("giveN"), document.getElementById("giveD"), document.getElementById("giveQ"),
    document.getElementById("giveR"), document.getElementById("giveF"), document.getElementById("giveE"), document.getElementById("giveT"), 
    document.getElementById("giveH"), document.getElementById("amountP"), document.getElementById("amountN"), document.getElementById("amountD"), 
    document.getElementById("amountQ"), document.getElementById("amountR"), document.getElementById("amountF"), document.getElementById("amountE"), 
    document.getElementById("amountT"), document.getElementById("amountH"), document.getElementById("haveP"), document.getElementById("haveN"), 
    document.getElementById("haveD"), document.getElementById("haveQ"), document.getElementById("haveR"), document.getElementById("haveF"),
    document.getElementById("haveE"), document.getElementById("haveT"), document.getElementById("haveH")];

document.addEventListener('DOMContentLoaded', () => {
  populator();
});

function populator() {
    drawer = 0;
    for(let i=0;i<3;i++) {
        for(let j=0;j<9;j++) {//i=0 is # to give of each, i=1 is cash value, i=3 # have of each
            if (i == 0) {elements[j].innerHTML = unit[j]; drawer += cid[j][1];}
            if (i == 1) {elements[18 + j].innerHTML = Math.floor(cid[j][1] / multiplier[j]);}
            if (i == 2) {elements[9 + j].innerHTML = "$ " + (cid[j][1] * 1).toFixed(2);}
            
        }
    }
    itemPrice.value = price;
}

function moneyIn(cashDistributor) {
  for (let i = 8; i >-1;i--) {
    while (cashDistributor >= multiplier[i]) {
      cid[i][1] = cid[i][1] + multiplier[i];
      cashDistributor -= multiplier[i];
    }
  }
  populator();
}

function noTrailingZeros(numb) {
  if (Math.floor(numb) !== numb) {
    if (numb.toFixed(2) % 1 !== 0) {
      let deciminus = ((numb - Math.floor(numb)) * 100).toFixed(2);
      numb = Math.floor(numb) + (deciminus / 100);
      if(deciminus < 100) {
        return numb;  
      } else {
        return numb.toFixed(2);
      }
    } else {
      return numb.toString();
    }
  } else {
    return numb.toString();
  }
}

function dividender (changeOfType, con) {
  for (let i = 8; i > -1; i--) {
    if (i != 0){
      console.log(changeOfType);
    numberOfUnits = Math.floor(Math.min(changeOfType / multiplier[i], cid[i][1] / multiplier[i]));
    } else {
      numberOfUnits = Math.min(changeOfType / multiplier[i], cid[i][1] / multiplier[i]);
    }
    unit[i] = numberOfUnits;
    if (numberOfUnits > 0) {
      changeOfType -= (numberOfUnits * multiplier[i]);
      drawer -= cid[i][1];
      cid[i][1] -= (numberOfUnits * multiplier[i]);
      let hold = noTrailingZeros(numberOfUnits * multiplier[i]);
      str += (cid[i][0] + ": $" + hold + " ");
    }
  }
  if (changeOfType > 0 || changeOfType > drawer) {
    cond = 2;
  } else cond = con;
}

function update () {  
  if(cond < 4) {
      moneyIn(cash);
      denominant.style.display = "inline";
      denominant.style.border = "1px solid #ad2";
      denominant.style.width = "346px";
      denominant.style.overflow = "hidden";
  }
    if (cond < 2) {changeDue.innerHTML = messages[cond] + " " + str;}
    if (cond === 2) {changeDue.innerHTML = messages[cond];}
    if (cond === 3) {changeDue.innerHTML = "No change due - customer paid with exact cash";}
    if (cond === 4) {changeDue.innerHTML = messages[2] + " " + str;}
    if (cond === 5) {changeDue.innerHTML = "Please enter a valid number";}
    if (cond === 6) {alert("Customer does not have enough money to purchase the item");}
}

purchaseBtn.addEventListener("click", () => {
  str = "";
  unit = Int32Array.from([0, 0, 0, 0, 0, 0, 0, 0, 0]);
  cash = parseFloat((numIn.value == undefined ? 0 : numIn.value.trim()))
  change = (cash - price);
  let set = false;
  if (!cash && !set) {
    set = true;
    cond = 5;//no value entered
  } 
  if (cash < price && !set) {
    set = true;
    cond = 6;//customer doesn't have enough money
  }
  if (change > drawer && !set) {
    set = true;
    cond = 4; //insufficient funds in drawer
  }
  if (cash === price && !set) {
    set = true;
    cond = 3;//paid with exact amount
  }
  if (change === drawer && !set) {
    set = true;
    cond = 1;//register closed with a ballance of 0
    dividender(change, 1);
  }
  if (change < drawer && !set) {//Normal transaction
    set = true;
    dividender(change, 0);   
  }
  update(cond);
  populator();
});

clearBtn.addEventListener("click", () => {
  changeDue.innerHTML = "";
  itemPrice.value = price;
  cash = 0;
  numIn.value = "";
  str = "";
  unit = Int32Array.from([0, 0, 0, 0, 0, 0, 0, 0, 0]);
  numberOfUnits = 0;
  denominant.style.border = "none";
  denominant.style.display = "none";
});

Your browser information:

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

Challenge Information:

Build a Cash Register Project - Build a Cash Register

Could you share your HTML as well? It’s necessary to fully reproduce the working code.

1 Like

How do you manually post code on here?.. Thank you @sanity I can post code here now

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="./styles.css">
    <title>ffcCashRegister</title>
  </head>
  <body>
    <h1><p title="Don't shortchange yourself or the customer" >Cash register</p></h1>
    <div class="parent">
    <div class="child">Item Price: $
      <input type="input" id="item-price" value="1.87">
      <button id="purchase-btn">Buy Item</button>
    </div>
    <br>
    <div class="child">&nbsp;&nbsp;&nbsp;Amount tendered:
    <input type="input" id="cash">
    </div>
    <br>
    <div class="child">
      &nbsp;&nbsp;&nbsp;Customer's change:
      <div id="change-due"></div>
      </div>
      <br>
      <div class="child">
    <button id="clear-btn">CLEAR ALL</button>
    </div>
      <div id="change" class="child">
       <table id="change-table">
  <tr>
    <th>Currency Unit</th>
    <th>Give customer</th>
    <th>Currency Unit</th>
    <th>Give customer</th>
  </tr>
  <tr>
    <td id="th1">Penny</td>
    <td id="giveP">0</td>
    <td id="th1">Five Dollars</td>
    <td id="giveF">0</td>
  </tr>
  <tr>
    <td id="th1">Nickle</td>
    <td id="giveN">0</td>
    <td id="th1">Ten Dollars</td>
    <td id="giveE">0</td>
  </tr>
  <tr>
    <td id="th1">Dime</td>
    <td id="giveD">0</td>
    <td id="th1">Twenty Dollars</td>
    <td id="giveT">0</td>
  </tr>
  <tr>
    <td id="th1">Quarter</td>
    <td id="giveQ">0</td>
    <td id="th1">One Hundred Dollars</td>
    <td id="giveH">0</td>
  </tr>
  <tr>
    <td id="th1">Dollar</td>
    <td id="giveR">0</td>
    <td id="th1">&nbsp;</td>
    <td id="give">&nbsp;</td>
  </tr>
        </table>
      </div>
      <br>
    <div id="status" >
      <table id="status-table">
  <tr>
    <th>Currency Unit</th>
    <th>$$$ Value</th>
    <th>Count</th>
  </tr>
  <tr>
    <td>Penny</td>
    <td id="amountP">$1.01</td>
    <td id="haveP">101</td>
  </tr>
  <tr>
    <td>Nickle</td>
    <td id="amountN">$2.05</td>
    <td id="haveN">41</td>
  </tr>
  <tr>
    <td>Dime</td>
    <td id="amountD">$3.10</td>
    <td id="haveD">31</td>
  </tr>
  <tr>
    <td>Quarter</td>
    <td id="amountQ">$4.25</td>
    <td id="haveQ">17</td>
  </tr>
  <tr>
    <td>Dollar</td>
    <td id="amountR">$90.00</td>
    <td id="haveR">90</td>
  </tr>
  <tr>
    <td>Five Dollars</td>
    <td id="amountF">$55.00</td>
    <td id="haveF">11</td>
  </tr>
  <tr>
    <td>Ten Dollars</td>
    <td id="amountE">$20</td>
    <td id="haveE">2</td>
  </tr>
  <tr>
    <td>Twenty Dollars</td>
    <td id="amountT">$60</td>
    <td id="haveT">3</td>
  </tr>
  <tr>
    <td>One Hundred Dollars</td>
    <td id="amountH">$100</td>
    <td id="haveH">1</td>
  </tr>
        </table>
    </div>
      
    <script src="./script.js"></script>
  </body>
</html>

And this is my styles.css code:

  font-size: 20px;
}
html, body {
  height: 130%; 
  width: 100%;
  border: 1px solid rgb(221, 218, 34);
  background-color: rgb(129, 64, 3);
}
body {
  color:rgb(55, 248, 184);
  flex-direction: column;
  justify-content: center;
  align-items: baseline;
}
td {
  border: 1px solid #ad2;
}

tr {
  border: 1px solid #ad2;
}

th {
  border: 1px solid #ad2;
}
#th1 {
    background-color: rgb(38, 92, 0);
    color:rgb(55, 248, 184);
    width: 80px;
    height: 80px;
    border-radius: 50%;
    outline-style: dotted;
    outline-width: 2px;
    outline-color: rgb(255, 215, 0);
}

p {
    color:rgb(55, 248, 184);
    width: 175;
    margin: auto; 
}
.child {
    display: flex;
    align-items: center;
    margin-left: 9;
  }
  
  .child p {
    margin: 10;
  }

  #change{
    border: 1px solid #ad2;
    width: 346px;
    padding-right: 250px;
    display: none;
    overflow: hidden;
  }

  #change-table{
    border: 1px solid #ad2;
    text-align: center;
  }

  #status{
    border: 1px solid #ad2;
    width: 246px;
    float: left;
    overflow: hidden;
  }
  #status-table{
    border: 1px solid #ad2;
    text-align: center;
  }


#purchase-btn {
    border: 1px solid #ad2;
    background-color: orange;
    color:rgb(23, 95, 71);
    width: 112px;
    margin: 10px; 
}

#clear-btn {
    border: 1px solid #ad2;
    background-color: orange;
    color:rgb(23, 95, 71);
    width: 112px;
    margin: 10px; 
}

#change-due {
  background-color: rgb(160,111,54);
  color:rgb(55, 248, 184);
  margin-left: 10px;
}

#change-due:focus {
  background-color: rgb(165,134,99);
  color:rgb(55, 248, 184);
}

#cash {
    border: 1px solid #ad2;
    background-color: rgb(160,111,54);
    color:rgb(55, 248, 184);
    width: 260px;
    margin-left: 10px;
}

#cash:focus {
  border: 1px solid #ad2; 
  background-color: rgb(165,134,99);
  color:rgb(55, 248, 184);
}

#item-price{
  border: 1px solid #ad2;
  background-color: rgb(160,111,54);
  color:rgb(55, 248, 184);
  width: 100px;
  margin-left: 10px;
}

#item-price:focus {
  border: 1px solid #ad2;
  background-color: rgb(165,134,99);
  color:rgb(55, 248, 184);
} ```

Put it within triple backticks:

```
HTML here
```
1 Like

I added console.log(changeDue.innerHTML); at the end of purchaseBtn’s click event callback. When tests are run, the result for last test is: Status: OPEN PENNY: $0.5

This suggests there are some parts of code that depends on global variables other than the expected - cid, price and #cash element. This works when checking test cases manually - each update to the cid or price will reload preview window, executing all the code again. On the other hand during tests preview is not reloaded, effectively resulting in part of the code being stuck with the initial values or having some values affected by previous tests.

1 Like

Ok thank you, I do have a habit of overusing global variables, I think I got from using GML for so many years. Thank you for your help, I’ll mark this solved because I know what direction I need to go in now, thanks again!

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