JavaScript calculator isn't working - javascript

My hourly wage calculator isn't working. I should be getting 3 different numbers, but the two first numbers don't show up, and the last number is NaN. Please help. The code I'm using is shown below.
var hourly = $('#txtHourlyWage').val();
var fraction = hourly/60/60/10;
var calc = new Calculator();
function addCommas(str){
return(str+"").replace(/\b(\d+)((\.\d+)*)\b/g,function(a,b,c){
return(b.charAt(0)>0&&!(c||".").lastIndexOf(".")?b.replace(/(\d)(?=(\d{3})+$)/g,"$1,"):b)+c;
});
}
$('#year-calculation').html(addCommas(Math.round(calc.annual/(hourly*calc.per_hour))) + ' years' );
$('#your-time').html( (((hourly*2080)/ calc.annual) * 52 * 5 * 8).toFixed(1) + " hours");
$('#txtHourlyWage').bind('keypress', function(e) {
if ($('#txtHourlyWage').length < 2) {
return ( e.which!=8 && e.which!=0 && (e.which<48 || e.which>57)) ? false : true ;
} else {
return false;
}
return
})
$('#txtHourlyWage').keyup(function (){
$('#year-calculation').html(addCommas(Math.round(calc.annual/(hourly*calc.per_hour))) + ' years' );
$('#your-time').html( (((hourly*2080)/ calc.annual) * 52 * 5 * 8).toFixed(1) + " hours");
$('#HourlyWageOutput').html("At this rate, it would take you <span id=\"year-calculation\"> </span> to earn his yearly income and <span id=\"your-time\"> </span> for him to earn yours.");
});
This code produces the following:
At this rate, it would take you to earn his yearly income and for him to earn yours.
NaN hours
As you can see from above, what the code has produced doesn't make sense because the numbers are missing. I can't tell what I'm doing wrong. Please help.

You're not setting the numbers on the keyup event.
You need to put these lines:
$('#year-calculation').html(addCommas(Math.round(calc.annual/(hourly*calc.per_hour))) + ' years' );
$('#your-time').html( (((hourly*2080)/ calc.annual) * 52 * 5 * 8).toFixed(1) + " hours");
inside the keyup. As it is, they are only fired once, onload, presumably before there is anything to calculate with.
EDIT AGAIN: Still untested but I think it should work:
function addCommas(str){
return(str+"").replace(/\b(\d+)((\.\d+)*)\b/g,function(a,b,c){
return(b.charAt(0)>0&&!(c||".").lastIndexOf(".")?b.replace(/(\d)(?=(\d{3})+$)/g,"$1,"):b)+c;
});
}
$('#txtHourlyWage').bind('keypress', function(e) {
if ($('#txtHourlyWage').length < 2) {
return ( e.which!=8 && e.which!=0 && (e.which<48 || e.which>57)) ? false : true ;
} else {
return false;
}
return;
});
$('#HourlyWageOutput').html("At this rate, it would take you <span id=\"year-calculation\"> </span> to earn his yearly income and <span id=\"your-time\"> </span> for him to earn yours.");
$('#txtHourlyWage').keyup(function (){
var hourly = $(this).val();
var fraction = hourly/60/60/10;
var calc = new Calculator();
$('#year-calculation').html(addCommas(Math.round(calc.annual/(hourly*calc.per_hour))) + ' years' );
$('#your-time').html( (((hourly*2080)/ calc.annual) * 52 * 5 * 8).toFixed(1) + " hours");
});
Of course, you don't need to set $('#HourlyWageOutput') if it's already defined in the HTML.

Related

Javascript issue with code developing a credit card schedule [duplicate]

This question already has answers here:
Creating multiline strings in JavaScript
(43 answers)
Closed 3 years ago.
I am working on a amortization schedule for a credit card loan. I keep getting one error or another when running the code I've written. It's "Unexpected identifier", to which I can't seem to locate where that is.
Please help me to straighten the code better so it will run the schedule
function displayWelcome() {
var balance = 1500;
var interest = 0.18;
var minimumpaymentRate = 0.02;
console.log("Welcome! \nThis program will determine the time to pay off
a
credit card and the interest paid based on the current balance, the
interest rate, and the monthly payments made.")
console.log("Balance on your credit card: $" + balance.toFixed(2))
console.log("Interest Rate: " + (interest * 100) + "%")
console.log("Assuming a minimum payment of 2% of the balance ($20 min)")
console.log("Your minimum payment would be: $" + minimumPaymentment)
console.log("\nYear Balance Payment # Interest Paid
Minimum Payment")
}
function calculateminimumPaymentment(balance, minimumPaymentRate) {
return Math.max(20, balance * minimumPaymentRate);
}
function generatePaymentId() {
var count = 0;
function paymentId() {
count ++;
return count;
}
return paymentId;
};
function processPaymentSchedule(balance, interest, minimumPayment) {
var id = generatePaymentId();
var year = 1;
var payments = 1;
var interestPaid = 0;
var yearChange;
while (balance > 0) {
yearChange = false;
if (payments % 12 == 0) {
year++
yearChange = true;
}
interestPaid += balance * interest / 12;
balance = Math.max(0, balance - (minimumPayment - balance * interest /
12));
minimumPayment = Math.max(20, balance * minimumPaymentRate);
payments++;
}
}
function displayPayment(pmt){
var pmt = {
balance: 1500,
minimumPaymentRate: 0.02,
interest: 0.18
console.log((yearChange ? year:" ") + " " + pmt.balance + "
"
+ payments + " " + pmt.interest + " " +
pmt.minimumPaymentRate);
return displayPayment
};
}
displayWelcome()
processPaymentSchedule(balance, interest, minimumPayment);
The expected results should be:
An amortization schedule that shows: Year, Balance, Interest
UPDATE:
I have updated with the suggestions listed below, but now am getting this error:
minimumPayment is not defined error
Your code is really buggy. There are several errors:
the multiline string should be created with `` instead of quotes
function displayPayment: move console.log and return outside of an object
declare balance, interest, minimumPayment outside of function so that you can use these variables

Price Variations

So how would one in JavaScript or with the added help of jQuery be able to get price variations. For example the first item is a set base at $450 and every item after that is a additional $150. But here is the trick the client is able to change that price so $450 is now $225 and additional is $75. I know how to do this with a bunch of if else statements but that just seems messy. Is there a better way?
Here's my code so far it only does the divided by two part but not the additions.
Edit: Further explanation of how this works
item#1 450
item#2 150
item#3 150
full[x] half[ ]
item#1 225
item#2 75
item#3 75
full[ ] half[x]
each additional is actually the base divided by 3 so 450 = 150 and 225 = 75 and the half is the original base 450 / 2 = 225
var dropResult;
$(function (){
$(".t").click(function(){
dropResult = $("input[name=drop]:checked").val();
dropCalculate();
});
});
function dropCalculate() {
var dropPrice = 450;
var dropAmount = $(".itemadd", "#items").length;
$("#dropAmount").html("Total: " + dropAmount);
if (dropResult == 1) {
dropTotal = dropAmount * dropPrice;
$("#dropPrice").html("Price Total: $" + dropTotal.toFixed(2));
}else {
dropTotal = dropAmount * dropPrice / 2;
$("#dropPrice").html("Price Total: $" + dropTotal.toFixed(2));
}
}
Okay, so if I understand you correctly, you want to apply a discount to the given price in a clean manner, depending on the number of items. I'd first start by applying the DRY (Don't Repeat Yourself) principle to your code, and putting variables in local scope:
//var dropResult = $("input[name=drop]:checked").val();
//this line doesn't actually do anything, so I removed it. It will always return true, as you're using the :checked pseudo-selector to only select checked checkboxes.
$(function (){
$(".t").click(function(){
dropCalculate(450);
});
});
function dropCalculate(dropPrice) {
var dropAmount = $(".itemadd", "#items").length,
dropTotal = dropAmount * dropPrice;
if (dropResult != 1) {
dropTotal = dropTotal / 2;
}
$("#dropPrice").html("Price Total: $" + dropTotal.toFixed(2));
}
Which is a lot cleaner. Then, if you have more complex discount rules, or multiple rules for multiple products, you can use an object for that. Here is a simple example of that:
$(function (){
$(".t").click(function(){
var pricesObj = {
'default': 75,
'1':450,
'2':225
};
dropCalculate(pricesObj);
});
});
function dropCalculate(priceObj) {
var dropAmount = $(".itemadd", "#items").length;
if (priceObj[dropAmount]) {
dropTotal = priceObj[dropAmount] * dropAmount;
}
else{
dropTotal = priceObj['default'] * dropAmount;
}
$("#dropPrice").html("Price Total: $" + dropTotal.toFixed(2));
}
If you need any help understanding that, just ask!
Update: I misunderstood your use case, but this should still point you in the right direction. In my code, if there is 1 product, the price is 450, 2 is 225, and more is 75 each.
a quick change you could make, it's something like that:
dropTotal = dropAmount * dropPrice;
$("#dropPrice").html("Price Total: $" + dropResult == 1 ? dropTotal.toFixed(2)) : (dropTotal / 2).toFixed(2));
check this fiddle
$('#dropPrice').text( '$' + (450 + ((450 * ($('#items .itemadd').length - 1)) / 3)) / (Number($("input[name=drop]").is(':checked')) + 1));

JavaScript stops execution half way and evaluates wrong answer?, Console.log is correct

I didn't think this was possible until console.log(); shown me that whats happening is impossible.
I can't understand how this is possible it's like those variables are being modified before code execution finishes.
I got this JavaScript code with debugging in it.
It's wrapped in this.
$('#buyAmountInput').keyup(function () {
var buyAmount = parseFloat($(this).val());
var totalPrice = 0;
var max = $(this).attr("max");
var min = $(this).attr("min");
if (buyAmount != $(this).val()) {
if (isNaN(buyAmount)) {
buyAmount = 1;
$(this).val('');
} else {
$(this).val(buyAmount);
}
} else {
if (buyAmount > max) {
buyAmount = max;
$(this).val(buyAmount);
} else if (buyAmount < min) {
buyAmount = min;
//$(this).val(buyAmount);
}
}
totalPrice = buyAmount * unitPrice;
//lots of code trimmed off here.
largessAmount = Math.round(buyAmount * largessRule.rebate) / 100;
////
console.log("Buy amount " + buyAmount + " LargessRebate " + largessRule.rebate);
console.log("Total Price " + totalPrice);
console.log("Largess Amount " + largessAmount);
console.log("New rate " + Number(totalPrice / (buyAmount + largessAmount)).moneyFormat());
console.log("No .moneyFormat() New rate " + Number(totalPrice / (buyAmount + largessAmount)));
console.log("( " + totalPrice + " / ( " + buyAmount + " + " + largessAmount + " ))");
////
$('#unitPrice').html(Number(totalPrice / (buyAmount + largessAmount)).moneyFormat());
});
Debug looks like this
Buy amount 5000 LargessRebate 20
Total Price 4250
Largess Amount 1000
New rate 0.71
No .moneyFormat() New rate 0.7083333333333334
( 4250 / (5000 + 1000))
function fastKeyListener content_script.js:208
Buy amount 5000 LargessRebate 20
Total Price 4250
Largess Amount 1000
New rate 0.00 //<- What happened here
No .moneyFormat() New rate 0.00008499830003399932 //<- What happened here
( 4250 / (5000 + 1000)) //<- Third line executed this will give good rate..
Even if the variables are global and this code is in a keypress up jQuery callback function.
The variables are printed before they are executed by console.log() and they are correct but the answer is dead wrong.
Here is the moneyFormat() which I don't think could be the problem could it?
var effective_bit = -2;
Number.prototype.moneyFormat = function () {
var num = this;
sign = (num == (num = Math.abs(num)));
num = Math.floor(num * Math.pow(10, -effective_bit) + 0.50000000001);
cents = num % Math.pow(10, -effective_bit);
num = Math.floor(num / Math.pow(10, -effective_bit)).toString();
for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++)
num = num.substring(0, num.length - (4 * i + 3)) + ', ' + num.substring(num.length - (4 * i + 3));
if (effective_bit < 0) {
if (cents < 10 && effective_bit == '-2') cents = "0" + cents;
money = (((sign) ? '' : '-') + num + '.' + cents);
} else {
money = (((sign) ? '' : '-') + num);
}
return money;
};
I didn't post the whole code as it's very large, but you can see it live here
Just put into the Unit to buy of 4999, then scroll to 5000 it's all good.. try putting like 5001 or 50000 it will reset it to 5000 and give wrong answer in the process.
EDIT:
could of simplified the question to why does the console.log() functions evaluate incorrect answer if the same equation generated with the same variables just 1 line after in execution after gives correct answer, even on calculator.
Like some quantum going on here, bear with me there is nothing I could have done from 1 line to another line during that code-execution no breakpoints were set nothing plus those callbacks are functions generated in their own sandbox I believe so they are like ajax threads all working to complete sooner or later they all work separately from each other, so nothing working together here to mess it up. What you think could possibly happen here? some temporarily corruption or something?
This occurs sometimes when doing claulations using string variables.
Try converting the buyAmount and any variable that came from HTML to number before any calculation.
You can use the Number() function or parseFloat().
http://jsfiddle.net/rcdmk/63qas2kw/1/

Generate multiple random numbers in JavaScript

I'm trying to write a script for roulette system and I want the script to run until the bank variable reaches 0 or 11,000, and produce three pieces of data after each spin.
I have left parts of the code out for simplicity. The code in the if else statement is not the problem. Running the script until the variable reaches a certain point is where I'm stuck.
Would anyone be able to help me rewrite this script please? Thanks in advance.
(function() {
var bank = 10000;
var bet = 1;
function spin() {
var number = Math.floor(Math.random() * 36);
if ( number == 0 ) {
document.write("<p>The number " + number + " is neither high nor low.</p>");
// removed
}
else if ( number > 18 ) {
document.write("<p>The number " + number + " is a high number.</p>");
// removed
}
else {
document.write("<p>The number " + number + " is a low number.</p>");
// removed
}
};
spin();
document.write("<p>Total bank is now " + bank + ".</p>");
document.write("<p>The next bet is " + bet + ".</p>");
})();
If you're calling this loop within a page (i.e. you don't want the page to hang up for the duration, or want to display results) you should use requestAnimationFrame:
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
Then set up your loop to only call itself if the bank is within your accepted range:
function spinLoop() {
spin();
//perform your UI updates here
if (bank >= 0 && bank <= 11000) requestAnimFrame(spinLoop);
}
You will, of course, need to call this function initially to start the loop:
spinLoop();

South African ID Number Validate and Get Age and Gender

I've researched this but none of the code I use seems to work. South African ID numbers contain date of birth and gender. All I want is it to pull in that information and verify it when their ID number is entered into an input field, preferably in jQuery or javascript
Any help is appreciated,
Dawid
You could use Koenyn's regex validation, not so sure how a single-digit number (0-9?) from the input represents the gender but basing on this tool you provided and David Russell's Using Javascript to validate South African ID Numbers, here's an untested attempt:
UPDATE 1:
After following this thread, What is a South African ID number made up of?, I updated my implementation to include the gender and citizenship tests.
UPDATE 2:
Forgot to wrap the month number increment id_month + 1 within the date string fullDate, updating solution with Dawid's fix.
HTML Markup:
<div id="error"></div>
<form id="idCheck">
<p>Enter the ID Number: <input id="idnumber" /> </p>
<p> <input type="submit" value="Check" /> </p>
</form>
<div id="result"> </div>
Javascript:
function Validate() {
// first clear any left over error messages
$('#error p').remove();
// store the error div, to save typing
var error = $('#error');
var idNumber = $('#idnumber').val();
// assume everything is correct and if it later turns out not to be, just set this to false
var correct = true;
//Ref: http://www.sadev.co.za/content/what-south-african-id-number-made
// SA ID Number have to be 13 digits, so check the length
if (idNumber.length != 13 || !isNumber(idNumber)) {
error.append('<p>ID number does not appear to be authentic - input not a valid number</p>');
correct = false;
}
// get first 6 digits as a valid date
var tempDate = new Date(idNumber.substring(0, 2), idNumber.substring(2, 4) - 1, idNumber.substring(4, 6));
var id_date = tempDate.getDate();
var id_month = tempDate.getMonth();
var id_year = tempDate.getFullYear();
var fullDate = id_date + "-" + (id_month + 1) + "-" + id_year;
if (!((tempDate.getYear() == idNumber.substring(0, 2)) && (id_month == idNumber.substring(2, 4) - 1) && (id_date == idNumber.substring(4, 6)))) {
error.append('<p>ID number does not appear to be authentic - date part not valid</p>');
correct = false;
}
// get the gender
var genderCode = idNumber.substring(6, 10);
var gender = parseInt(genderCode) < 5000 ? "Female" : "Male";
// get country ID for citzenship
var citzenship = parseInt(idNumber.substring(10, 11)) == 0 ? "Yes" : "No";
// apply Luhn formula for check-digits
var tempTotal = 0;
var checkSum = 0;
var multiplier = 1;
for (var i = 0; i < 13; ++i) {
tempTotal = parseInt(idNumber.charAt(i)) * multiplier;
if (tempTotal > 9) {
tempTotal = parseInt(tempTotal.toString().charAt(0)) + parseInt(tempTotal.toString().charAt(1));
}
checkSum = checkSum + tempTotal;
multiplier = (multiplier % 2 == 0) ? 1 : 2;
}
if ((checkSum % 10) != 0) {
error.append('<p>ID number does not appear to be authentic - check digit is not valid</p>');
correct = false;
};
// if no error found, hide the error message
if (correct) {
error.css('display', 'none');
// clear the result div
$('#result').empty();
// and put together a result message
$('#result').append('<p>South African ID Number: ' + idNumber + '</p><p>Birth Date: ' + fullDate + '</p><p>Gender: ' + gender + '</p><p>SA Citizen: ' + citzenship + '</p>');
}
// otherwise, show the error
else {
error.css('display', 'block');
}
return false;
}
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
$('#idCheck').submit(Validate);
DEMO: http://jsfiddle.net/chridam/VSKNx/
this is the validation regex we us at our company:
string IdExpression = #"(?<Year>[0-9][0-9])(?<Month>([0][1-9])|([1][0-2]))(?<Day>([0-2][0-9])|([3][0-1]))(?<Gender>[0-9])(?<Series>[0-9]{3})(?<Citizenship>[0-9])(?<Uniform>[0-9])(?<Control>[0-9])";
as far as using regex, it's really simple
http://www.w3schools.com/jsref/jsref_obj_regexp.asp
There is a jQuery plugin that you can use. Check it out at http://www.verifyid.co.za/jqueryid
So there is an issue where if the ID number starts with 0 it gives the year of birth 1901 instead of 2001. #louwki mentioned it in his comment
I'm using your code but running into an issues when adding a id number
010101.... it gives the year of birth 1901 instead of 2001 any work around for this?
I have a work around assuming that there is no one older than a 100 years still alive who wants to get their date
// get first 6 digits as a valid date
var tempDate = new Date(idNumber.substring(0, 2), idNumber.substring(2, 4) - 1, idNumber.substring(4, 6));
var id_date = tempDate.getDate();
var id_month = tempDate.getMonth();
var id_year = tempDate.getFullYear();
// Add a 100 years to the current year if older than 100 years
if(id_year < (new Date()).getFullYear() - 100){
id_year+= 100
}
var fullDate = id_date + "-" + id_month + 1 + "-" + id_year;
DEMO: http://jsfiddle.net/dupies/5fwxvu6d/3/

Categories