Cash Register problems

Tell us what’s happening:

Why is it not logging my second console.log statement to the fcc console?
I am stuck here so how can I make this happen:

  //   you need to loop through the tendervalues from highest denomination to lowest denomination
// if the i'th denomination can be used to make change, use it to make change
// continue to use that denomination until either you run out of that denomination or you exceed the amount of change you need to give
//  for (let i=0; i<tenderArray.length; i++){
//    if (change<tenderArray[i]){
//     cidArray[i]=cidArray[i]-tenderArray[i];
//    }
//  }

Your code so far
The work I did is unorganized, Not sure what pieces I should keep and what I should throw.


const tenderValues=
[["PENNY", 0.01 ],
["NICKEL", 0.05 ],
["DIME", 0.1],
["QUARTER", 0.25 ],
["ONE", 1],
["FIVE", 5],
["TEN", 10],
["TWENTY", 20],
["ONE HUNDRED", 100]]


function checkCashRegister(price, cash, cid) {
  
   let change=price-cash;
   let totalIndrawer=0;
  for (let i=0; i<cid.length; i++){
    totalIndrawer+=cid[i][1]
  }
  totalIndrawer= totalIndrawer.toFixed(2) 
  //console.log(totalIndrawer)
  // let TenderName=[];
  // let changeValue=[TenderName, sum];
   let sum; 
  // const objReturn= { status:"" , change: changeValue };
     let tenderArray=[];
  for (let i=0; i<tenderValues.length; i++){
    tenderArray.push(tenderValues[i][1]);
  }
  tenderArray=tenderArray.reverse()
  console.log('this is tenderArray: '+tenderArray);
  
  //   you need to loop through the tendervalues from highest denomination to lowest denomination
// if the i'th denomination can be used to make change, use it to make change
// continue to use that denomination until either you run out of that denomination or you exceed the amount of change you need to give
//  for (let i=0; i<tenderArray.length; i++){
//    if (change<tenderArray[i]){
//     cidArray[i]=cidArray[i]-tenderArray[i];
//    }
//  }
    
  cidArray=[];
for (let i=0; i<cid.length; i++){
  cidArray.push(cid[i][1])
}
  cidArray=cidArray.reverse();
console.log('this is cidArray: '+cidArray);
  
}

checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]);

Your browser information:

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

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/javascript-algorithms-and-data-structures-projects/cash-register

Make sure you are always explicitly declaring your variables. I see one that is not explicitly declared but assigned an initial value.

EDIT: Also, if you create your cidArray in reverse, you would not need to use the reverse method on it.

  const cidArray = [];
  for (let i = cid.length - 1; i >= 0; i--) {
    cidArray.push(cid[i][1])
  }
1 Like

I understood your prior point about arranging the object from greatest to lowest value vs vice versa… to follow up,

I looked at this cash register every free hour I had yesterday and I still could not solve it. I have a relative that is a mathematician, alot smarter than me, and knows a little javascript wrote me that the following snippet is missing in my code:

let change = [];
let status = "OPEN";
let changePossible = 0;
for (let i = cid.length - 1; i >= 0; i--) {
if (getValue(cid[i][0]) <= changeOwed && cid[i][1] > 0) {
let x = 0;
while ((x + getValue(cid[i][0])) <= changeOwed && cid[i][1] > 0) {
x += getValue(cid[i][0]);
cid[i][1] -= getValue(cid[i][0]);
}
changePossible += x;
changeOwed -= x;
changeOwed = changeOwed.toFixed(2);
change.push([cid[i][0], x])
}
}

I used this piece and was able to pass the tests, but im not counting it because I didnt write it, nor do I fully understand why the double if and while statements that seem to be both checking the same thing??

if (getValue(cid[i][0]) <= changeOwed && cid[i][1] > 0) {
let x = 0;
while ((x + getValue(cid[i][0])) <= changeOwed && cid[i][1] > 0) {

So why is it necessary to have a while statement inside of an if that seems to be checking the same thing?

Where is getValue defined? You seem to be missing a bit a code.

checkCashRegister(price, cash, cid) {
let cashInDrawer = 0;
for (let i = 0; i < cid.length; i++) {
cashInDrawer += cid[i][1];
}
let changeDue = cash - price;
let changeOwed = changeDue;
if (cashInDrawer == changeDue) {
return {status: “CLOSED”, change: cid};
}
let change = [];
let status = “OPEN”;
let changePossible = 0;
for (let i = cid.length - 1; i >= 0; i–) {
if (getValue(cid[i][0]) <= changeOwed && cid[i][1] > 0) {
let x = 0;
while ((x + getValue(cid[i][0])) <= changeOwed && cid[i][1] > 0) {
x += getValue(cid[i][0]);
cid[i][1] -= getValue(cid[i][0]);
}
changePossible += x;
changeOwed -= x;
changeOwed = changeOwed.toFixed(2);
change.push([cid[i][0], x])
}
}
changePossible = changePossible.toFixed(2);
if (changePossible != changeDue) {
status = “INSUFFICIENT_FUNDS”;
change = [];
}
let obj = {
status: status,
change: change,
}
return obj
}
function getValue(denomination) {
switch(denomination) {
case “PENNY”:
return 0.01
break;
case “NICKEL”:
return 0.05;
break;
case “DIME”:
return 0.1;
break;
case “QUARTER”:
return 0.25;
break;
case “ONE”:
return 1;
break;
case “FIVE”:
return 5;
break;
case “TEN”:
return 10;
break;
case “TWENTY”:
return 20;
break;
case “ONE HUNDRED”:
return 100;
break;
default:
return null;
}
}
// Example cash-in-drawer array:
// [[“PENNY”, 1.01],
// [“NICKEL”, 2.05],
// [“DIME”, 3.1],
// [“QUARTER”, 4.25],
// [“ONE”, 90],
// [“FIVE”, 55],
// [“TEN”, 20],
// [“TWENTY”, 60],
// [“ONE HUNDRED”, 100]]

console.log(checkCashRegister(3.26, 100, [[“PENNY”, 1.01], [“NICKEL”, 2.05], [“DIME”, 3.1], [“QUARTER”, 4.25], [“ONE”, 90], [“FIVE”, 55], [“TEN”, 20], [“TWENTY”, 60], [“ONE HUNDRED”, 100]]));

these are the two lines that are irking me most about it…

if (getValue(cid[i][0]) <= changeOwed && cid[i][1] > 0) {
let x = 0;
while ((x + getValue(cid[i][0])) <= changeOwed && cid[i][1] > 0) {

Your pasted code has html entities instead of code. Try posting the code again inside 3 backticks on the line above and below the code.

Also, I strongly suggest using a lookup object instead of that getValue function. That way overcomplicates things.

I did post inside of three backticks, but the three backticks were themselves nested inside of spoiler brackets, is this not the way to do it?
And on my side of freecodecamp its showing up fine without the html entities.
I will switch out the getVal for a lookup object, but its the while loop inside of the for if statement that repeats the same line of code that I did not understand. Can you explain to me why its necessary in this case?
I realize it may not be necessary if the code is structured differently, but I want to understand why in this case it is. it seems to be checking the same thing twice

if (getValue(cid[i][0]) <= changeOwed && cid[i][1] > 0) {
let x = 0;
while ((x + getValue(cid[i][0])) <= changeOwed && cid[i][1] > 0)

below is my initial solution to be put in spoiler brackets for your reference but my question is regarding the above three lines of code and why its repeated.

function checkCashRegister(price, cash, cid) {
let cashInDrawer = 0;
for (let i = 0; i < cid.length; i++) {
cashInDrawer += cid[i][1];
}
let changeDue = cash - price;
let changeOwed = changeDue;
if (cashInDrawer == changeDue) {
return {status: "CLOSED", change: cid};
}
let change = [];
let status = "OPEN";
let changePossible = 0;
for (let i = cid.length - 1; i >= 0; i--) {
if (getValue(cid[i][0]) <= changeOwed && cid[i][1] > 0) {
let x = 0;
while ((x + getValue(cid[i][0])) <= changeOwed && cid[i][1] > 0) {
x += getValue(cid[i][0]);
cid[i][1] -= getValue(cid[i][0]);
}
changePossible += x;
changeOwed -= x;
changeOwed = changeOwed.toFixed(2);
change.push([cid[i][0], x])
}
}
changePossible = changePossible.toFixed(2);
if (changePossible != changeDue) {
status = "INSUFFICIENT_FUNDS";
change = [];
}
let obj = {
status: status,
change: change,
}
return obj
}
function getValue(denomination) {
switch(denomination) {
case "PENNY":
return 0.01
break;
case "NICKEL":
return 0.05;
break;
case "DIME":
return 0.1;
break;
case "QUARTER":
return 0.25;
break;
case "ONE":
return 1;
break;
case "FIVE":
return 5;
break;
case "TEN":
return 10;
break;
case "TWENTY":
return 20;
break;
case "ONE HUNDRED":
return 100;
break;
default:
return null;
}
}
// Example cash-in-drawer array:
// [["PENNY", 1.01],
// ["NICKEL", 2.05],
// ["DIME", 3.1],
// ["QUARTER", 4.25],
// ["ONE", 90],
// ["FIVE", 55],
// ["TEN", 20],
// ["TWENTY", 60],
// ["ONE HUNDRED", 100]]

console.log(checkCashRegister(3.26, 100, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]));

additionally if you can explain why you insist on using the lookup obj instead of a getVal function, will this speed up runtime? or just because its cleaner? why is it a better design option?

Yes, Yes, and because calling a function takes more time than a simple O(1) object lookup.

Also, rename x to make it clear what it represents in your code.

I will rename x to “tenderValue” or “coinValue” unless you have a better suggestion?

I tried to implement a reference obj “tenderValues” however I am recieving the following console errors:
TypeError: Cannot read property ‘8’ of undefined

Why is it undefined? Observe I am successfully logging the reference obj to the console right before its used. Also, It mentions property 8. is this the last key in the reference obj, the string
“ONE HUNDRED”, I also tried changing all instances of
tenderValues.cid[i][0] to
tenderValues[cid[i][0]]
but I was getting a syntax error.
javascript obj notation with spaces

what should I do to fix these remaining bugs?
Updated code:
codepen fcc cash reg

When I replace all instances of tenderValues.cid[i][0] with tenderValues[cid[i][0]] it works fine. My guess is you have a typo or did not change one of them.

Its passing on fcc and returning as expected on codepen but I still have 3 problems:

  1. VS Code node ./ displaying the same error as before in the terminal even though I updated the file
    image

  2. I cannot think of a better name than ‘x’, you requested a reference obj which is now called ‘tenderValues’. If I chage x to tenderValue, in singular form, that is too confusing I might not be able to differentiate between the two. The word coinValue also is incorrect in my mind that only applies to denominations less than 1.00

  3. Can you explain to me why its necessary to repeat the same condition of the If inside a while loop only one line below it :

if (tenderValues[cid[i][0]] <= changeOwed && cid[i][1] > 0) {
let x = 0;
while ((x + tenderValues[cid[i][0]]) <= changeOwed && cid[i][1] > 0) {

The image shows you trying to use dot notation and you should be using bracket notation like the codepen uses.

This is incorrect. I sent you message with the full contents of VS code. I did not use dot notation in that file. that Is a reference to an older file that does not exist, as i mentioned before, I had since updated the file to the correct version but its still displaying that message.

I don’t know what to tell you then. I tested your code on Node locally and it works fine.

I need to look into this and get back to you. Thank you for helping me.