Off by one error that I can't find

I keep getting a off by one error in my tests but I can’t find it. Maybe someone else can see it somewhere in there?

function checkCashRegister(price, cash, cid) {

//value of change needed to be returned
let changeValue = cash - price;
let changeRemaining = changeValue + 0;

//cidValue function returns the total amount of money in register rounded to the hundreths bc of floating point errors
function cidValue(cid) {
  let total = 0
  for(let i = 0; i < cid.length; i++){
    total += cid[i][1]
  }
  return Math.round((100*total))/100
}

//function that returns the least amount of bills/coins in change
function changeValToMoney(changeRemaining, cid){
        let currencyValue = [0.01, 0.05, 0.10, 0.25, 1, 5, 10, 20, 100]
        let currName = ["PENNY","NICKEL","DIME","QUARTER","ONE","FIVE","TEN","TWENTY","ONE HUNDRED"]
        let result = []
        let i = 8
        let j = 0
        while(i > -1){
          //if change is greater than current bill
          if(changeRemaining > currencyValue[i]){
            //if number of currency we're giving is <= the number of bills in register 
            if(j <= (cid[i][1]/currencyValue[i])){
              changeRemaining -= currencyValue[i]
              j ++ 
            } 
          }
          if(changeRemaining < currencyValue[i]){
            if(j !== 0){
              result.push([currName[i], currencyValue[i]*j])
              j = 0
              i --
            } else {
              i--
            }
          }
          if(changeRemaining === currencyValue[i]){
            result.push([currName[i], currencyValue[i]*(j+1)])
            i = -1
          }
        }
      return result
    }
  
//switch that sets Response to the correct values and returns Response
function setStatus(changeValue, cidValue){ 
  if(cidValue > changeValue){
    if(changeValToMoney(changeValue, cid) == []){
      return "INSUFFICIENT_FUNDS"
    }
    return "OPEN"
  } else if(cidValue == changeValue){
    return "CLOSED"
  } else if(cidValue < changeValue){
      return "INSUFFICIENT_FUNDS"
  } 
}

Response = {
  status: setStatus(changeValue, cidValue(cid)),
  change: changeValToMoney(changeValue, cid)
}
return Response
}

Challenge: Cash Register

Side note: I don’t think you ever declare this variable.

I don’t think this does what you think it does

Response is declared later on which is fine because the function isn’t called until Response is defined. Also for the if statement I’m trying to say “if the amount of the current bill is less than or equal to the amount of the current bill in the register”

Defined is not the same as declared. You should have let Response or const Response. Skipping the declaration makes it an accidental global.

Yeah i changed it but it made no difference in the outcome

That’s why I listed it as a side note.

Usually the freeCodeCamp editor stops you from doing that sort of thing.

I still think this line is a problem.

I’ve been messing around with that line a lot but I haven’t figured out anything that works yet

the cid[i][1]/currencyValue[i] part is supposed to result in the number of bills/coins of that type in the register

You’re ending up with using 4 twenties when there are only 3 in the drawer because your pieces of logic are fighting each other.

Which part of the logic is incorrect?

It’s so complicated and represents a couple of ways of organizing the problem that it’s hard to say which single piece is wrong.

I would back up and write out how you would explain what should happen to a young kid. If your niece wants to run a lemonade stand, how do you teach them to make change? Keep it simple for the poor kid.

Okay. Thanks for your help Jeremy

1 Like

The last time I posted my code was hard to understand so I cleaned it a bit and improved it but I’m still getting an off by one error or a floating point error that I can’t figure out. My total is one cent short on the test at the bottom and I’m not sure why. Any help would be appreciated

function checkCashRegister(price, cash, cid) {

//value of change needed to be returned
let changeValue = cash - price;
//cidValue function returns the total amount of money in register rounded to the hundreths bc of floating point errors
function cidValue(cid) {
  let total = 0
  for(let i = 0; i < cid.length; i++){
    total += cid[i][1]
  }
  return total
}
console.log(cidValue(cid))


//function that returns the least amount of bills/coins in change
function changeValToMoney(change, cid){
  let currencyValue = [0.01, 0.05, 0.10, 0.25, 1, 5, 10, 20, 100]
  let currName = ["PENNY","NICKEL","DIME","QUARTER","ONE","FIVE","TEN","TWENTY","ONE HUNDRED"]
  let result = []
  
  if(change < cidValue(cid)){
    let count = 0
    let changeRemaining = change;
    let i = 8
    while(i > -1){   
      if(changeRemaining > currencyValue[i]){
        if(count < cid[i][1]/currencyValue[i]){
          changeRemaining -= currencyValue[i]
          count ++
        } else {
          result.push([currName[i], currencyValue[i]*count])
          count = 0
          i--
        } 
      }else if(changeRemaining === currencyValue[i] && count<=cid[i][1]/currencyValue[i]){
        changeRemaining -= currencyValue[i]
        result.push([currName[i], currencyValue[i]*(count+1)])
        count = 0
        i--
      }else if(currencyValue[i] > changeRemaining){
        if(count !== 0){
          result.push([currName[i], currencyValue[i]*count])
          count = 0
          i --
        } else{
          i --
        }
      }
    } return result
  }
  if(change === cidValue(cid)){
    return cid
  }else if(change > cidValue(cid)){
    return []
  }
}
  
//switch that sets Response to the correct values and returns Response
function setStatus(changeValue, cidValue){ 
  if(cidValue > changeValue){
    if(changeValToMoney(changeValue, cid) === []){
      return "INSUFFICIENT_FUNDS"
    }
    return "OPEN"
  } else if(cidValue == changeValue){
    return "CLOSED"
  } else if(cidValue < changeValue){
      return "INSUFFICIENT_FUNDS"
  } 
}
let response = {
    status: setStatus(changeValue, cidValue(cid)),
    change: changeValToMoney(changeValue, cid)
  }
return response
}

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]]))

Link to the challenge:

I’m not sure I see what you changed. It looks largely the same but with different variable names to me? :person_shrugging:

My question remains. Pretend I’m a dumb child (computers are very dumb, very little children that are good at addition). What is the big picture of how your plan is supposed to work for how to count out change?

This will have rounding problems unless you account for floating point precision somehow. Fixing this line gets one more test passing for me.

You aren’t handling insufficient funds correctly for the other case.