I'm trying to create a calculator that when you input your points, and the total amount of points in the class you receive a lot of information about it, I currently have working the letter grade, percentage, and the amount of points that you need to get to the next grade up.
Ex. 95/100
A 95%
Points Needed = 5
I want to do the same thing with Points needed but opposite. So with the same example it would be
Points Lost = 5
I currently have the script for my current Points Needed if it helps, but I really can't figure out the equation for this, luckily not necessary for a school project, just for a solo project so I can learn how to code.
Here is the code for the Points Needed
var pointsNeeded = totalGrade.value - grade.value;
if (gradePercentage > 100) {
pointsNeeded = pointsNeeded * -1;
document.getElementById("pointsNeeded").innerHTML = "You can lose " + pointsNeeded + " point(s) and still have 100%";
}
else {
document.getElementById("pointsNeeded").innerHTML = pointsNeeded;
}
}
else if (gradePercentage < 89, gradePercentage > 79) {
var pointsNeeded = Math.round(10 * ((totalGrade.value * 0.9) -
grade.value)) / 10;
document.getElementById("pointsNeeded").innerHTML = pointsNeeded;
}
else if (gradePercentage < 79, gradePercentage > 69) {
var pointsNeeded = Math.round(10 * ((totalGrade.value * 0.8) -
grade.value)) / 10;
document.getElementById("pointsNeeded").innerHTML = pointsNeeded;
}
else if (gradePercentage < 69, gradePercentage > 59) {
var pointsNeeded = Math.round(10 * ((totalGrade.value * 0.7) -
grade.value)) / 10;
document.getElementById("pointsNeeded").innerHTML = pointsNeeded;
}
else if (gradePercentage < 59) {
var pointsNeeded = Math.round(10 * ((totalGrade.value * 0.6) -
grade.value)) / 10;
document.getElementById("pointsNeeded").innerHTML = pointsNeeded;
}
gradePercentage being the actual percentage, totalGrade being the full grade, and grade being the grade you have.
Also these are the grade values,
var gradeLetter = "A"
document.getElementById("result").innerHTML = gradeLetter + " " + result + "%";
}
if (gradePercentage > 79.9, gradePercentage < 90) {
var gradeLetter = "B"
document.getElementById("result").innerHTML = gradeLetter + " " + result + "%";
}
if (gradePercentage > 69.9, gradePercentage < 80) {
var gradeLetter = "C"
document.getElementById("result").innerHTML = gradeLetter + " " + result + "%";
}
if (gradePercentage > 59.9, gradePercentage < 70) {
var gradeLetter = "D"
document.getElementById("result").innerHTML = gradeLetter + " " + result + "%";
}
if (gradePercentage < 59.9) {
var gradeLetter = "F"
document.getElementById("result").innerHTML = gradeLetter + " " + result + "%";
}
This code is pretty self-explanatory:
let startingPoints = 952.3 // How many points you got on the test
let maxPoints = 1049 // Max possible points you could have gotten
// Your grade (0-100%):
let gradePercentage = 100 * startingPoints / maxPoints; // E.g. 90.7816968541468
// How much less you'd need (as a percentage) to get the next lowest grade:
let extraPercentage = ( gradePercentage % 10 ) + 0.01; // E.g. 0.7916968541468015
// Your new grade (as a percentage) if you bumped it down:
let newGrade = gradePercentage - extraPercentage; // E.g. 89.99
// How many points you'd have to reduce your score by to bump it down to the next lowest
let extraPoints = ( extraPercentage / 100 * maxPoints ) // E.g. 8.304899999999947
// What your score would be if you bumped it down to the next level:
let newExtraPoints = startingPoints - extraPoints; // E.g. 943.9951
console.log( `Your grade is ${gradePercentage}% (${startingPoints} points out of a possible ${maxPoints}). If you subtract ${extraPercentage}% (or ${extraPoints} points), your grade will be ${newGrade}% (${newExtraPoints} points)` );
The only trickiness is that we're adding 0.01, which technically could be 0.001, or 0.0001, or...well, we have to add something to drop below the limit, and with no set "right" amount, I'm choosing 0.01 because it works out nicely.
Example output:
Your grade is 90.7816968541468% (952.3 points out of a possible 1049).
If you subtract 0.7916968541468015% (or 8.304899999999947 points),
your grade will be 89.99% (943.9951 points)
Related
I have been trying to get a progress bar representation that looks like this:
The user has to enter an input, and as of the input, the loop will run and get to a 100%.
Enter State: 70
[####### ] 70 %
[######## ] 80 %
[######### ] 90 %
[##########] 100 %
Here is what I have ade so far, but I am stuck now:
let hashtag = "";
for (let i = 1; i <= 3; i++) {
hashtag += "#";
}
console.log(
"[" + hashtag + " ",
" ",
" ",
" ",
" ",
" ",
" " + "]" + " " + "30%"
);
Any ideas of how to solve this problem? I a a total beginner, please go easy on me" :)
Math.floor() the percent value
Use String.prototype.repeat() to create the hashes "#"
Use String.prototype.padEnd() to fill the remaining spaces " "
const generateOutput = (pct, width = 10) => {
const flr = Math.floor(pct * width / 100);
const str = "#".repeat(flr).padEnd(width, " ");
return `[${str}] ${pct}%`;
};
// Example 90% (width 10)
console.log(generateOutput(90));
// Example 80% (width 30)
console.log(generateOutput(80, 30));
Given the above Formatted String generator, if you need a loop that will change the output:
const generateOutput = (pct, width = 10) => {
const flr = Math.floor(pct * width / 100);
const str = "#".repeat(flr).padEnd(width, "-");
return `[${str}] ${pct}%`;
};
const EL_output = document.querySelector("#output");
const step = 1; // Increment step
const width = 30; // Progressbar width
const time = 80; // Timeout ms
const progress = (val) => {
EL_output.textContent = generateOutput(val, width);
if (val >= 100) return; // Stop
setTimeout(() => progress(val += step), time);
};
// DEMO TIME! Start at 30
progress(30);
#output {white-space: pre;}
<code id="output"></code>
Good day all,
I am trying to create a simple small bet calculator with the following line of codes:
function betCalculator(moneyLine) {
var odds;
var betAmount = 500;
if (moneyLine > 0) {
odds = (moneyLine / 100) + 1;
} else {
odds = (100 / moneyLine) + 1;
}
return parseFloat((odds * betAmount).toFixed(2));
}
console.log(betCalculator(130)); // Result / Expected = 1150.00
But if I change the Money Line to negative, say -130, as shown below:
function betCalculator(moneyLine) {
var odds;
var betAmount = 500;
if (moneyLine > 0) {
odds = (moneyLine / 100) + 1;
} else {
odds = (100 / moneyLine) + 1;
}
return parseFloat((odds * betAmount).toFixed(2));
}
console.log(betCalculator(-130)); // Result I am getting = 115.38 // Expected = 884.62
What I am trying to do is:
if (moneyLine > 0) {
odds = (moneyLine / 100) + 1;
But
if (moneyLine < 0) {
odds = (100 / moneyLine) + 1;
Any help would be appreciated.
Regards,
ZeManel
For the calculation for the negative moneyLine, you want to change the sign, or use the absolute value, when you move it to the denominator.
If you change odds = (100 / moneyLine) + 1; in your else condition to odds = (100 / Math.abs(moneyLine)) + 1;, then you will get your expected answer.
I have an issue with the decimals in a result in my script, it gives unlimited decimals, I want to limit it to 2, I have tried using to.fixed(2) without luck, but the script broke.
This is my script:
$.each(rows, function () {
quantity = $(this).find('[data-quantity]').val();
if (quantity == '') {
quantity = 1;
$(this).find('[data-quantity]').val(1);
}
_amount = parseFloat($(this).find('td.rate input').val()) * quantity;
$(this).find('td.amount').html(_amount);
subtotal += _amount;
row = $(this);
item_taxes = $(this).find('select.tax').selectpicker('val');
if (item_taxes) {
$.each(item_taxes, function (i, taxname) {
taxrate = row.find('select.tax [value="' + taxname + '"]').data('taxrate');
calculated_tax = (_amount / 100 * taxrate);
if (!taxes.hasOwnProperty(taxname)) {
if (taxrate != 0) {
_tax_name = taxname.split('|');
tax_row = '<tr class="tax-area"><td>' + _tax_name[0] + '(' + taxrate + '%)</td><td id="tax_id_' + slugify(taxname) + '"></td></tr>';
$(discount_area).after(tax_row);
taxes[taxname] = calculated_tax;
}
} else {
// Increment total from this tax
taxes[taxname] = taxes[taxname] += calculated_tax;
}
});
}
});
The code line that does the operation is:
calculated_tax = (_amount / 100 * taxrate);
The correct is toFixed(), not to.fixed(), see the example:
let number = 12.128361;
let _amount = number.toFixed(2);
let calculated_tax = (_amount / 100 * 100);
console.log(calculated_tax);
Use this method to round to any amount of decimal places:
let v = 3.486894716724;
let rounded = Math.round(v * 100) / 100; // => 3.49
Multiply and divide by 10 to round to one DP, 100 for 2DP, 1000 for 3, etc...
I need a javascript where with every second call i get a random number between 0-100 where current number should be greater than previous number. I wrote a code to get random numbers every second but stuck at generating it with increment.
<script>
var span = document.getElementsByTagName("span")[3];
var i = 100;
(function randNumber() {
var a = Math.floor((Math.random() * i) + 1);
span.innerHTML = "RandNumber: " + a;
setTimeout( randNumber, 1000);
})();
Note : The numbers should generate randomly.
example result may be : 2,5,7,8,22,23,34,56,78,88.....
You should not create a new random number between zero and your maximum (i), but just between the last created number (lastNumber) and max (i).
Also you might want to stop, when the random numbers reached the maximum.
var span = document.getElementsByTagName("span")[3],
i = 100,
lastNumber = 0;
function randNumber() {
lastNumber = lastNumber + Math.floor( Math.random() * (i - lastNumber) + 1 );
span.innerHTML = lastNumber;
if( lastNumber < i ) {
setTimeout( randNumber, 1000 );
}
}
randNumber();
AS for the comments and the requirement of a minimum amount of steps until reaching the maximum:
In each iteration, just increase you number by a random value between 1 and ((max - min) / steps. It is pretty much the same code as above.
var span = document.getElementsByTagName("span")[3],
max = 100,
min = 0,
lastNumber = 0,
minSteps = 30;
// how wide can the average step be at most?
var stepWidth = (max - min) / minSteps;
function randNumber() {
lastNumber = lastNumber + Math.floor( Math.random() * stepWidth + 1 );
span.innerHTML = lastNumber;
if( lastNumber < max ) {
setTimeout( randNumber, 1000 );
}
}
randNumber();
If you extract the "between two numbers" logic into its own function like this, this becomes a lot easier. This way, you just generate a number between your last generated number and your maximum.
var max = 100
var last_number = 1
var interval_id = setInterval(function(){
last_number = get_random_number_greater_between(last_number, max)
span.innerHTML = "RandNumber: " + last_number;
if(last_number >= max){
window.clearInterval(interval_id)
}
}, 1000)
function get_random_number_greater_between(low, high){
return Math.floor(Math.random() * (high - low + 1) + low);
}
Try this:
// generate a random number from 0 to max - 1.
function rand(max) {
return Math.floor(max * Math.random());
}
// generate a random number from min to max.
function range(min, max) {
return min + rand(1 + max - min);
}
// the loop function
function next(n, callback) {
var m = range(n, 100);
if (m < 100) setTimeout(next, 1000, m + 1, callback);
callback(m);
}
var span = document.getElementById("rand");
next(0, function (m) {
span.innerHTML = "Random number: " + m;
});
<span id="rand"></span>
I'm working on the classic "making change" problem, which is highly documented in plenty of other languages, but there's not much out there for it in Javascript. So far, I have this:
var total = $('#total').val();
var coins = [];
function makeChange(total, coins) {
var remainder = 0;
if (total % 0.25 < total) {
coins[3] = parseInt(total / 0.25);
remainder = total % 0.25;
total = remainder;
}
if (total % 0.10 < total) {
coins[2] = parseInt(total / 0.10);
remainder = total % 0.10;
total = remainder;
}
if (total % 0.05 < total) {
coins[1] = parseInt(total / 0.05);
remainder = total % 0.05;
total = remainder;
}
coins[0] = parseInt(total / 0.01);
}
function showChange(coins) {
if (coins[3] > 0) {
$('.quarter').html(coins[3] + " quarter(s).");
}
if (coins[2] > 0) {
$('.dime').html(coins[2] + " dime(s).");
}
if (coins[1] > 0) {
$('.nickel').html(coins[1] + " nickel(s).");
}
if (coins[0] > 0) {
$('.penny').html(coins[0] + " pennies.");
}
}
makeChange(total, coins);
showChange(coins);
However, this seems awfully repetitive and I'm finding that with certain values, it's a penny off. How can I make it more accurate and concise?
I'm finding that with certain values, it's a penny off.
Probably due to floating-point issues. And you shouldn't use parseInt to convert a number - it's meant for strings.
this seems awfully repetitive
A loop, with a data structure that represent the different coins will help. You already did something like that for your result: coins is an array, not 4 different variables.
function makeChange(total, values) {
var coins = [],
epsilon = 1e-5; // this is wrong in general!
// assume values are ascending, so we loop backwards
for (var i=values.length; i--; ) {
coins[i] = Math.floor(total / values[i].val + epsilon);
total %= values[i].val;
}
return coins;
}
function showChange(coins, values) {
for (var i=values.length; i--; ) {
var el = $(values[i].sel);
if (coins[i] > 0) {
el.html(coins[i] + " "+values[i].name+".");
} else {
el.empty();
}
}
}
var values = [
{val:0.01, sel:'.penny', name:"pennies"},
{val:0.05, sel:'.nickel', name:"nickel(s)"},
{val:0.10, sel:'.dime', name:"dime(s)"},
{val:0.25, sel:'.quarter', name:"quarter(s)"}
];
showChange(makeChange(parseFloat($('#total').val()), values), values);
Your best bet to avoid rounding problems is to just multiple your total by 100 to convert your dollar amount into all pennies, then do you conversion. For example:
function makeChange(total, coins) {
var remainder = 0;
total = Math.round(total * 100);
coins[3] = Math.floor(total / 25);
remainder = total - coins[3] * 25;
total = remainder;
coins[2] = Math.floor(total / 10);
remainder = total - coins[2] * 10;
total = remainder;
coins[1] = Math.floor(total / 5);
remainder = total - coins[1] * 5;
total = remainder;
coins[0] = total;
}
http://jsfiddle.net/t14cwdph/4/
For making your code easier to manage - see #Bergi's answer.