The Cash Register Project is the most challenging in FreeCodeCamp’s Javascript Algorithms and Data Structures Certification Course.
This article aims to explain how to solve the cash register challenge. The article is written for developers who are currently learning JavaScript Algorithms and Data Structures and are looking for a guide to solve FreeCodeCamp’s Cash Register project. Developers who wish to build their JavaScript Muscle may also find this article useful.
FreeCodeCamp’s Cash Register Project
Here is the challenge as seen on FreeCodeCamp:
Cash Register
Design a cash register drawer function checkCashRegister() that accepts purchase price as the first argument (price), payment as the second argument (cash), and cash-in-drawer (cid) as the third argument.
cid is a 2D array listing available currency.
The checkCashRegister() function should always return an object with a status key and a change key.
Return {status: “INSUFFICIENT_FUNDS”, change: []} if cash-in-drawer is less than the change due, or if you cannot return the exact change.
Return {status: “CLOSED”, change: […]} with cash-in-drawer as the value for the key change if it is equal to the change due.
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.
Currency Unit | Amount |
Penny | $0.01 (PENNY) |
Nickel | $0.05 (NICKEL) |
Dime | $0.1 (DIME) |
Quarter | $0.25 (QUARTER) |
Dollar | $1 (ONE) |
Five Dollars | $5 (FIVE) |
Ten Dollars | $10 (TEN) |
Twenty Dollars | $20 (TWENTY) |
One-hundred Dollars | $100 (ONE HUNDRED) |
See below for an example of a 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]
]
How to Solve FreeCodeCamp’s Cash Register Project
Below are the steps to create a cash register with JavaSript.
1. Declare the checkCashRegister function
function checkCashRegister(price, cash, cid) { }
2. Create an object to hold the various currency units in the drawer and their values.
const availableCurrency = {
"PENNY": 0.01,
"NICKEL": 0.05,
"DIME": 0.1,
"QUARTER": 0.25,
"ONE": 1,
"FIVE": 5,
"TEN": 10,
"TWENTY": 20,
"ONE HUNDRED": 100
};
3. Initialize the relevant variables
let totalCid = 0;
let changeToGive = cash - price;
totalCid is the sum of the money in the cash drawer while changeToGive is the balance due to the customer. changeToGive is derived by subtracting the price of an item from the amount of cash that the customer gives.
4. Iterate through the cid array to calculate the total amount of money in the drawer.
for (let i = 0; i < cid.length; i++) {
totalCid += cid[i][1];
}
What this for loop does is this:
- let i = 0; – declare a variable i to represent the index of each element in the cid array and set the value to 0.
- i < cid.length; i++ – iterate through the array, and if i is less than the length of the array, increment the value of i by 1 and continue the loop.
- totalCid += cid[i][1]; – this adds the second element of each sub-array in the cid array to the totalCID.
For this challenge, this loop goes through each currency in the cid array and adds the value to the totalCid. The aim is to calculate the total amount of money in the cash drawer.
5. Convert the totalCid to two decimal places using the .toFixed() method.
totalCid = totalCid.toFixed(2);
The total Cid is converted to decimal points to avoid what is known as floating-point precision issues.
Floating-point precision issues arise due to the way that computers store numbers. Computers store numbers in binary forms, and these binary forms may not adequately represent some numbers with decimal points.
To check these issues, limit your results to 2 decimal places.
6. Check for insufficient funds
if (parseFloat(totalCid) < changeToGive) {
return { status: "INSUFFICIENT_FUNDS", change: [] };
The parseFloat in the code is used to convert the totalCid from decimal points back to floating numbers.
This conversion is necessary because the totalCid returns a string due to the toFixed method. And you are to compare it with the changeToGive which is still a floating point number.
7. Check if the change is exactly the same with the cash in drawer
else if (parseFloat(totalCid) === changeToGive) {
return { status: "CLOSED", change: cid };
}
This snippet means that if the change due to the customer is exactly the same as the total money in the drawer, issue the change and return the string “CLOSED”.
The triple “equal to” sign means strict equality. This means that the numbers being compared must be exactly the same.
8. Calculate the change due to the customer
- First of all, create an empty array to keep the change
else {
let changeArray = [];
- Iterate through the various currency units from the highest to the lowest (reverse iteration). This ensures that the function gives change in higher denominations first. You achieve this reverse iteration by using i– instead of i++.
for (let i = cid.length - 1; i >= 0; i--) {
- Extract the name of each currency from the cid array and assign it to a variable.
const nameOfCurrency = cid[i][0];
- Also, search the value of each currency from the availableCurrency object using the nameOfCurrency you extracted earlier. Assign the returned value to a variable.
const valueOfCurrency = availableCurrency[nameOfCurrency];
Remember that the availableCurrency object that we defined at the beginning of this function contains the name of the available currencies and their values. Hence, if the nameOfCurrency is “penny”, the value will be 0.01.
- Extract the available amount of money for the current currency at any particular iteration of the cid array.
const availableAmount = cid[i][1];
This line checks the available amount of each currency at any moment.
9. Calculate the amount of change due to the customer. Do this by checking the maximum amount of a particular currency unit that can be given out as change.
let balanceToGive = (availableAmount / valueOfCurrency).toFixed(0);
This code divides the available amount of a currency by the value of the currency. Remove decimal points from the result using the .toFixed method.
10. Declare a variable to keep track of the amount of change issued in each iteration. Set the initial value to 0.
let returnedAmount = 0;
11. Write a while loop to issue change from the highest denomination
while (changeToGive >= valueOfCurrency && balanceToGive > 0) {
changeToGive -= valueOfCurrency;
changeToGive = changeToGive.toFixed(2);
balanceToGive--;
returnedAmount += valueOfCurrency;
- while (changeToGive >= valueOfCurrency && balanceToGive > 0) means that the loop will continue to run while these conditions remain true:
- if changeToGive is greater than or equal to the valueOfCurrency
- if balanceToGive is greater than 0.
- changeToGive -= valueOfCurrency; – deduct the value of the current currency from the remaining change.
- changeToGive = changeToGive.toFixed(2); – Round changeToGive up to 2 decimal places to check floating-point precision issues.
- balanceToGive–; – this code subtracts the amount of the current currency to give.
- returnedAmount += valueOfCurrency; – This line adds the value of the current currency to the returnedAmount.
12. Build the change array
if (returnedAmount > 0) {
changeArray.push([nameOfCurrency, returnedAmount]);
}
}
13. Calculate the remaining change
if (changeToGive > 0) {
return { status: "INSUFFICIENT_FUNDS", change: [] };
}
This means that if the change to be given out is not complete, return an object with the string, insufficient funds.
14. Return the result and close the function
else {
return { status: "OPEN", change: changeArray };
}
}
This means that if all the due change is given successfully; return an object with the status, “open”, and the change array.
With this, all aspects of the challenge have been taken care of.
The Solution:
function checkCashRegister(price, cash, cid) {
const availableCurrency = {
"PENNY": 0.01,
"NICKEL": 0.05,
"DIME": 0.1,
"QUARTER": 0.25,
"ONE": 1,
"FIVE": 5,
"TEN": 10,
"TWENTY": 20,
"ONE HUNDRED": 100
};
let totalCid = 0;
let changeToGive = cash - price;
for (let i = 0; i < cid.length; i++) {
totalCid += cid[i][1];
}
totalCid = totalCid.toFixed(2);
if (parseFloat(totalCid) < changeToGive) {
return { status: "INSUFFICIENT_FUNDS", change: [] };
} else if (parseFloat(totalCid) === changeToGive) {
return { status: "CLOSED", change: cid };
} else {
let changeArray = [];
for (let i = cid.length - 1; i >= 0; i--) {
const nameOfCurrency = cid[i][0];
const valueOfCurrency = availableCurrency[nameOfCurrency];
const availableAmount = cid[i][1];
let balanceToGive = (availableAmount / valueOfCurrency).toFixed(0);
let returnedAmount = 0;
while (changeToGive >= valueOfCurrency && balanceToGive > 0) {
changeToGive -= valueOfCurrency;
changeToGive = changeToGive.toFixed(2);
balanceToGive--;
returnedAmount += valueOfCurrency;
}
if (returnedAmount > 0) {
changeArray.push([nameOfCurrency, returnedAmount]);
}
}
if (changeToGive > 0) {
return { status: "INSUFFICIENT_FUNDS", change: [] };
} else {
return { status: "OPEN", change: changeArray };
}
}
}
What is the Aim of the Cash Register Project
The Cash register project tasks developers to build a digital cash register that handles cash receipts for a business. The checkCashRegister() Function takes the following three arguments:
- Price: This is the selling price of the goods to be purchased.
- Cash: This is the amount of money the customers pay in exchange for the product. Like in real-life businesses, customers can pay an amount higher than the price of a product, and receive a balance from the seller.
- cid (Cash in Drawer): This argument represents the total amount of money available in the seller’s drawer. The cid comes as a 2D array and lists the available currencies and the amount of each currency.
The checkCashRegister function compares the amount paid by the customer to the total amount in the drawer and confirms if the customer will receive a change.
The checkCashRegister function outputs an object that contains two keys, status and change. “Status” shows one of the following at a time:
- if change is due and available,
- if change is equal to the total amount in drawer, or
- if the change is greater than the amount in the drawer.
The “change” key states the amount to be given to the customer.
If the cash-in-drawer is less than the change due, the status returns the string “INSUFFICIENT_FUNDS”, while the change returns an empty array.
If the cash-in-drawer is equal to the change due, the status returns “closed” and gives the customer the entire change, while the change returns the value due to the customer.
However, if the cash-in-drawer is greater than the change, the status returns open, while the change returns the amount due to the customer.
Closing Thoughts
Algorithms and Data Structures are the basics of JavaScript. You should get grounded in them if you intend to work with scripts.
With this article, I have attempted an explanation of all five Project challenges in the JavaScript Data Structures and Algorithms course.
If you haven’t seen the other four project solutions, find the links below:
- The Solution to FreeCodeCamp’s Palindrome Checker Project
- How To Create a Roman Numeral Converter – FreeCodeCamp Project
- How To Create a Caesers’ Cipher With JavaScript – FreeCodeCamp Project
- How To Create a Telephone Number Validator – FreeCodeCamp Project
Leave a Reply