I am working on a small app to improve my js skills. It is meant to allow the user to enter an amount of pennies, and from here the correct and minimum amount of change will be calculated to make this amount.
Currently I have the entry of pennies being worked out by the proper denominations (1p, 2p, 5p, 10p, 20p, 50p, £1, £2) however I am not sure how to get this to display the minimum change needed to make up the total number of pennies?
Below is my code so far, any help will be appreciated as I really want to learn how to do something this:
function calculate() {
var list = []
var x = document.getElementById("pennies").value;
resultTwoPounds = x / 200;
resultTwoPounds * 2;
list.push(Math.floor(resultTwoPounds));
resultPounds = x / 100;
list.push(Math.floor(resultPounds));
remaining = x % 100;
remainPennyFifty = Math.floor(remaining / 50);
list.push(remainPennyFifty);
remaining = x % 100;
remainPennyTwenty = Math.floor(remaining / 20);
list.push(remainPennyTwenty);
remaining = x % 100;
remainPennyTen = Math.floor(remaining / 10);
list.push(remainPennyTen);
remaining = x % 10;
list.push(Math.floor(remaining / 5));
remaining = x % 10;
list.push(Math.floor(remaining / 2));
remaining = x % 10;
list.push(Math.floor(remaining));
if (x > 0) {
resultLine = "You have <strong>" + x + " pennies</strong>, breakdown as follows: <br><br><strong>£2</strong> *" + list[0] + "<br><br><strong>" + "£1</strong> *" + list[1] + "<br><br><strong>50p</strong>" + " *" + list[2] + "<br><br><strong>20p</strong>" + " *" + list[3] + "<br><br><strong>10p</strong>" + " *" + list[4] + "<br><br><strong>5p</strong>" + " *" + list[5] + "<br><br><strong>2p</strong>" + " *" + list[6] + "<br><br><strong>1p</strong>" + " *" + list[7]
} else {
resultLine = "Please enter an amount"
}
document.getElementById('result').innerHTML = resultLine;
$("#submit").submit(function(e) {
e.preventDefault();
});
}
#pennies {
width: 6em;
vertical-align: middle;
}
#submit {
text-align: center;
}
.mainCalc {
text-align: center;
align-content: center;
}
.headings {
text-align: center;
color: white;
}
body {
margin-top: 200px;
background-color: lightblue;
}
#printResult {
text-align: center;
padding-top: 40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="headings">
<h1>pennyCalc
<h1>
</div>
<!-- Start of form -->
<form onsubmit="return false">
<div class="mainCalc">
<br>
<strong>p:</strong>
<input type="number" placeholder=" Amount" step="1" min="0" id="pennies">
<br>
<button type="buttom" id="submit" onclick="calculate()">Calculate!</button>
<br>
</div>
</form>
<div id="printResult"><span id="result"></span></div>
I have made a version of your calculator, let me show you how it works if you may.
The function works the same, the way I've organized it is different though. You don't need to use jQuery (as you haven't put the jQuery
tag on this question).
Let us create a function divide
that will return an array of the division integer result and the remainder of the euclidean division between x
and y
. For this, I will use, as you did, the %
modulus operator and the Math.floor()
function:
const divide = (x, y) => { return [ Math.floor(x/y), x % y ] };
I'm using the shorthand arrow function expression to declare it.
Then we will write the actual function calculate()
: declare obj
, the object that will contain are values and x
, the money count. On each step we will decrease the value of x
and append new properties to the object obj
.
With our previous divide
function this is pretty easy to do, you just have to write this line:
[ obj['twoPounds'], x ] = divide(x, 200);
By destructuring the array returned by divide(x, 200)
, we are assigning the division result to the property twoPounds
of obj
and assigning the remainder of the division to x
.
The same result would have been met with:
let result = division(x, 200);
obj['twoPounds'] = result[0];
x = result[1]
But instead of calling the function twice you only do once, and the code is cleaner.
After calling divide
for each coin type, x
will have the value of 0
and obj
will be filled with the number of coins per coin type.
Lastly, we can format our response with template literals with backticks (`
) and the ${}
syntax. This way we can embed JavaScript variables inside the string and also jump lines while writing the HTML markup in the editor.
For instance:
`You have ${obj.twoPounds} coins of £2`
Is the same as writing:
'You have' + obj.twoPounds + 'coins of £2'
const divide = (x, y) => { return [Math.floor(x / y), x % y] };
const calculate = function() {
let obj = {};
let x = document.querySelector('#pennies').value;
[ obj['twoPounds'], x ] = divide(x, 200);
[ obj['onePound'], x ] = divide(x, 100);
[ obj['fiftyPence'], x ] = divide(x, 50);
[ obj['twentyPence'], x ] = divide(x, 20);
[ obj['tenPence'], x ] = divide(x, 10);
[ obj['fivePence'], x ] = divide(x, 5);
[ obj['twoPence'], x ] = divide(x, 2);
[ obj['onePence'], x ] = divide(x, 1);
document.querySelector('#result').innerHTML = `
<div>
<span>You have: </span>
<span><strong>${obj.twoPounds}</strong> x £2, </span>
<span><strong>${obj.onePound}</strong> x £1, </span>
<span><strong>${obj.fiftyPence}</strong> x 50p, </span>
<span><strong>${obj.twentyPence}</strong> x 20p, </span>
<span><strong>${obj.tenPence}</strong> x 10p, </span>
<span><strong>${obj.fivePence}</strong> x 5p, </span>
<span><strong>${obj.twoPence}</strong> x 2p, </span>
<span><strong>${obj.onePence}</strong> x 1p, </span>
</div>
`;
return false;
}
Preview:
const divide = (x, y) => { return [ Math.floor(x / y), x % y ] };
const calculate = function() {
let obj = {};
let x = document.querySelector('#pennies').value;
[ obj['twoPounds'], x ] = divide(x, 200);
[ obj['onePound'], x ] = divide(x, 100);
[ obj['fiftyPence'], x ] = divide(x, 50);
[ obj['twentyPence'], x ] = divide(x, 20);
[ obj['tenPence'], x ] = divide(x, 10);
[ obj['fivePence'], x ] = divide(x, 5);
[ obj['twoPence'], x ] = divide(x, 2);
[ obj['onePence'], x ] = divide(x, 1);
document.querySelector('#result').innerHTML = `
<div>
<span>You have: </span>
<span><strong>${obj.twoPounds}</strong> x £2, </span>
<span><strong>${obj.onePound}</strong> x £1, </span>
<span><strong>${obj.fiftyPence}</strong> x 50p, </span>
<span><strong>${obj.twentyPence}</strong> x 20p, </span>
<span><strong>${obj.tenPence}</strong> x 10p, </span>
<span><strong>${obj.fivePence}</strong> x 5p, </span>
<span><strong>${obj.twoPence}</strong> x 2p, </span>
<span><strong>${obj.onePence}</strong> x 1p, </span>
</div>
`;
return false;
}
#pennies {
width: 6em;
vertical-align: middle;
}
#submit {
width: 10em;
text-align: center;
}
.mainCalc {
text-align: center;
align-content: center;
}
.headings {
text-align: center;
color: white;
}
body {
margin-top: 200px;
background-color: lightblue;
}
#printResult {
text-align: center;
padding-top: 40px;
}
<div class="headings">
<h1>Penny Calculator</h1>
</div>
<div class="mainCalc">
<input type="number" placeholder=" Amount" value="593" step="1" min="0" id="pennies">
<button type="buttom" id="submit" onclick="calculate()">Calculate!</button>
</div>
<div id="printResult"><span id="result"></span></div>
I went ahead and refactored my own version, the actual function itself is very short indeed, enjoy!
Instead of having to call the function divide()
multiple time, I have created an object containing the name
, label
and value
in pennies for each coin.
let coins = [
{ name: 'twoPounds', label: '£2', value: 200 },
{ name: 'onePound', label: '£1', value: 100 },
{ name: 'fiftyPence', label: '50p', value: 50 },
{ name: 'twentyPence', label: '£2', value: 20 },
{ name: 'tenPence', label: '£2', value: 10 },
{ name: 'fivePence', label: '£2', value: 5 },
{ name: 'twoPence', label: '£2', value: 2 },
{ name: 'onePence', label: '£2', value: 1 }
];
Then in the function I use the .map
method to go through each element of the coins
array. The calculation of the number of coins in the formatting of the span
s happens on the same line. The array returned by .map
is then converted into a string with .join
added in the element #result
.
document.querySelector('#result').innerHTML = `
<div>
<span>You have: </span>
${ coins.map( coin => `<span>${([x, x] = divide(x, coin.value))[0]} x ${coin.label}</span>` ).join(', ') }
</div>
`
That's the line of code that does basically everything:
${ coins.map( coin => `<span>${([x, x] = divide(x, coin.value))[0]} x ${coin.label}</span>` ).join(', ') }
Here is the final code (same result as preview version):
const divide = (x, y) => { return [ Math.floor(x / y), x % y ] };
let coins = [
{ name: 'twoPounds', label: '£2', value: 200 },
{ name: 'onePound', label: '£1', value: 100 },
{ name: 'fiftyPence', label: '50p', value: 50 },
{ name: 'twentyPence', label: '£2', value: 20 },
{ name: 'tenPence', label: '£2', value: 10 },
{ name: 'fivePence', label: '£2', value: 5 },
{ name: 'twoPence', label: '£2', value: 2 },
{ name: 'onePence', label: '£2', value: 1 }
];
const calculate = function() {
let x = document.querySelector('#pennies').value;
document.querySelector('#result').innerHTML = `
<div>
<span>You have: </span>
${ coins.map( coin => `<span>${([x, x] = divide(x, coin.value))[0]} x ${coin.label}</span>` ).join(', ') }
</div>
`
return false;
}
#pennies {
width: 6em;
vertical-align: middle;
}
#submit {
width: 10em;
text-align: center;
}
.mainCalc {
text-align: center;
align-content: center;
}
.headings {
text-align: center;
color: white;
}
body {
margin-top: 200px;
background-color: lightblue;
}
#printResult {
text-align: center;
padding-top: 40px;
}
<div class="headings">
<h1>Penny Calculator</h1>
</div>
<div class="mainCalc">
<input type="number" placeholder=" Amount" value="593" step="1" min="0" id="pennies">
<button type="buttom" id="submit" onclick="calculate()">Calculate!</button>
</div>
<div id="printResult"><span id="result"></span></div>