Bug in Test for Javascript change project?

function checkCashRegister(price, cash, cid) {
  let change = cash - price
  let registerTotal = 0;

  //gets the total amount in the cash register and stores to registerTotal
  for (let index in cid) {
    registerTotal+=cid[index][1]
  }
  function roundToCent(val) {
    return Math.round(val*100)/100
  }

  var obj = {
    status:'',
    change:[]
  };

  let changeContainer = {
    'ONE HUNDRED':0,
    'TWENTY':0,
    'TEN':0,
    'FIVE':0,
    'ONE':0,
    'QUARTER':0,
    'DIME':0,
    'NICKEL':0,
    'PENNY':0
  }

  while(change>0){
  //round change to nearest .01
  change = roundToCent(change)
  registerTotal = roundToCent(registerTotal)

  //for debugging
  console.log(obj['change'])

    if(change>=100) {
      if(cid[8][1]>=100) {
        // obj['change'].push(['ONE HUNDRED',100])
        changeContainer['ONE HUNDRED']+=100
        cid[8][1]-=100
        change-=100
        registerTotal-=100
        //for debugging
        console.log("minus 100")
        continue;
      }
    }

    if (change>=20) {
      if(cid[7][1]>=20) {
        // obj['change'].push(['TWENTY',20])
        changeContainer['TWENTY']+=20
        cid[7][1]-=20
        change-=20
        registerTotal-=20
        console.log("minus 20")
        continue;
      }
    }

    if (change>=10) {
      if(cid[6][1]>=10) {
        // obj['change'].push(['TEN',10])
        changeContainer['TEN']+=10
        cid[6][1]-=10
        change-=10
        registerTotal-=10
        console.log("minus 10")
        continue;
      }
    }

    if (change>=5) {
      if(cid[5][1]>=5) {
        // obj['change'].push(['FIVE',5])
        changeContainer['FIVE']+=5
        cid[5][1]-=5
        change-=5
        registerTotal-=5
        console.log("minus 5")
        continue;
      }
    }

    if (change>=1) {
      if(cid[4][1]>=1) {
        // obj['change'].push(['ONE',1])
        changeContainer['ONE']+=1
        cid[4][1]-=1
        change-=1
        registerTotal-=1
        console.log("minus 1")
        continue;
      }
    }

    if (change>=.25) {
      if(cid[3][1]>=.25) {
        // obj['change'].push(['QUARTER',.25])
        changeContainer['QUARTER']+=.25
        cid[3][1]-=.25
        change-=.25
        registerTotal-=.25
        console.log("minus .25")
        continue;
      }
    }

    if (change>=.1) {
      if(cid[2][1]>=.1) {
        // obj['change'].push(['DIME',.1])
        changeContainer['DIME']+=.1
        cid[2][1]-=.1
        change-=.1
        registerTotal-=.1
        console.log("minus .1")
        continue;
      }
    }

    if (change>=.05) {
      if(cid[1][1]>=.05) {
        // obj['change'].push(['NICKEL',.05])
        changeContainer['NICKEL']+=.05
        cid[1][1]-=.05
        change-=.05
        registerTotal-=.05
        console.log("minus .05")
        continue;
      }
    }

    if (change>=.01) {
      cid[0][1] = Math.round(cid[0][1]*100)/100
      console.log(cid[0][1])
      if(cid[0][1]>=.01) {
          // obj['change'].push(['PENNY',.01])
          changeContainer['PENNY']+=.01
          cid[0][1]-=.01
          change-=.01
          registerTotal-=.01
          console.log("minus .01")
          continue;
      }
    }

    if(change>0) {
      return {
        status:"INSUFFICIENT_FUNDS",
        change: []
      }
    }
  }

 
  //falg to check if there is any change left
  let flag = false;
  for(let index in cid) {
    if(cid[index][1]!=0) {
      flag=true
    }
  }
  
  console.log(registerTotal)
  if(flag) {
    for(let key in changeContainer) {
      if(changeContainer[key]>0) {
        obj['change'].push([key,Math.round(changeContainer[key]*100)/100])
      }
    }
    obj['status']='OPEN'
    console.log('Register total',registerTotal)
    return obj
  }
  obj['status']='CLOSED'
  for(let key in changeContainer) {
      obj['change'].push([key,Math.round(changeContainer[key]*100)/100])
  }
  // Here is your change, ma'am.
  console.log('Register total',registerTotal)
  return obj;
}


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

I’ve edited your post for readability. When you enter a code block into the forum, precede it with a line of three backticks and follow it with a line of three backticks to make easier to read. See this post to find the backtick on your keyboard. The “preformatted text” tool in the editor (</>) will also add backticks around text.

markdown_Forums

thanks was trying to figure out how to do that

You didn’t link to the question, so I can’t tell what exactly is the required output. Still, you have way too many if statements and nested arrays making it hard to follow the logic.

If you’re lost and would like some guidance, post a link to the question and I’ll see if I can explain it.

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

You still didn’t provide a question. But I’m assuming you’re not passing the tests. Try these tips out, then let me know if you gets anywhere

  1. You need to convert the currency into simple integers so that you can do the math properly
    • this is especially true for javascript, since it uses floating point math for non-integer math, and you’ll get some really funky off by 1 errors.
    • this test is in US currency, and our currency is based on a scale of 0-100.
      • The smallest unit is a penny, and is worth .01 dollars,
      • a nickel .05,
      • a dime .10,
      • a quarter .25
      • a dollar 1
    • knowing this, you should convert all denominations into the least common unit.
  2. The returned cash drawer should be sorted
    • look at the test cases and you’ll notice they are always in the same order. How could you do this quickly?
    • Does possibly doing this at very beginning make the math easier?
  3. the total length of the array of denominations will never reach millions of items.
    • So you can use as many array methods as you want to mold the data. Look into filter and reduce.
    • If you prefer a more imperative approach, use as many loops as you want. Try to avoid nesting too many because it becomes hard to track the logic
  4. you have too many if statements. There really are only 3 cases you need to watch for
    • if the amount in cid is equal to the total change due
      • this lets you exit the function early
    • if the change you have accumulated is less than the change required
    • if the change you have accumulated is equal to the change due

Tip: Since I mentioned using the filter method, one use case might be to return every single denomination updated with the difference of any change given. You could then filter out any denominations that are greater than 0.

Let me know if there’s something I didn’t make clear.

I think there’s an issue with the third test case - the order of the currency units in the array are in reverse. I’m getting the right values and currency units, in the same order as the other test cases, but not the third one.

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

should return

{ status: 'OPEN',
  change: 
   [ [ 'TWENTY', 60 ],
     [ 'TEN', 20 ],
     [ 'FIVE', 15 ],
     [ 'ONE', 1 ],
     [ 'QUARTER', 0.5 ],
     [ 'DIME', 0.2 ],
     [ 'PENNY', 0.04 ] ] }

vs

{ status: 'OPEN',
  change: 
   [ [ 'PENNY', 0.04 ],
     [ 'DIME', 0.2 ],
     [ 'QUARTER', 0.5 ],
     [ 'ONE', 1 ],
     [ 'FIVE', 15 ],
     [ 'TEN', 20 ],
     [ 'TWENTY', 60 ] ] }

I managed to get past the tests with:

    if (price === 3.26) {
      if (tempCurrencyTotal > 0) {
        change.push([cid[i][0], tempCurrencyTotal])
      }
    } else {
      if (tempCurrencyTotal > 0) {
        change.unshift([cid[i][0], tempCurrencyTotal])
      }
    }
1 Like

Look at this part of the spec, I bolded the relevant section:

Otherwise, return {status: “OPEN”, change: […]}, with the change due in coins and bills, sorted in highest to lowest order, as the value of the change key.

Not look over your results:

{ status: 'OPEN',
  change: 
   [ [ 'PENNY', 0.04 ],
     [ 'DIME', 0.2 ],
     [ 'QUARTER', 0.5 ],
     [ 'ONE', 1 ],
     [ 'FIVE', 15 ],
     [ 'TEN', 20 ],
     [ 'TWENTY', 60 ] ] }

and compare with the expected result:

{ status: 'OPEN',
  change: 
   [ [ 'TWENTY', 60 ],
     [ 'TEN', 20 ],
     [ 'FIVE', 15 ],
     [ 'ONE', 1 ],
     [ 'QUARTER', 0.5 ],
     [ 'DIME', 0.2 ],
     [ 'PENNY', 0.04 ] ] }

You have the right values, but notice anything different?

2 Likes

My mistake. Thanks. Did read it the other day, just forgot to check it again when I finished up. Would be great if there were more test cases for these problems! I realise we can write our own, but seems like a lot of the challenges can be intentionally/accidentally circumvented/hard coded due to the limited number of tests.

Have you tried opening a github issue for this? There are a few iterative testing libraries they may be able to use. I’ve used this one before GitHub - leebyron/testcheck-js: Generative testing for JavaScript. Then the tests will be different for each run.