Looping with Object Literal in JavaScript - javascript

Alert: shameless homework help.
I am trying to create an amortization schedule for paying off a credit card. I'm stuck because I think I need to create a loop that does all the calculations until the credit card balance is zero. I know basic loops, I know basic objects; and, referencing a different function (aka not local function) for the payment id. Combining the principles is baffling me atm.
Full problem details commented out in code.
Ive tried messing around with different loop ideas; after I'm asking for loop help, i think. I cant get the loop to work, it usually ends up being infinite and crashing the browser. But in relation to above criteria confuses me a bit.
function displayWelcome() {
printLine();
console.log('Welcome to the credit card payoff tool.');
printLine();
console.log('This program will determine the time it \nwill take to pay off a credit card!');
printLine();
}
displayWelcome();
function calculateMinimumPayment(balance, interestRate) {
var calcMinPay = balance * interestRate;
return calcMinPay
}
function generatePaymentId() { // lines 14 - 22 are a closure function.
var count = 0;
function paymentId() {
count ++;
return count;
}
return paymentId;
};
var id = generatePaymentId();
function processPaymentSchedule(balance, interest, minimumPayment) {
var year = 1;
var counter = 0;
while (balance > counter) {
var interestDecimal = interest / 100;
var interestMonthly = interestDecimal / 12;
var interestPaid = balance * interestMonthly;
var payment = {
year: year,
balance: balance,
paymentId: id(),
interest_paid: interestPaid
}
displayPayment(payment);
balance = balance - interestPaid;
return balance;
}
}
function displayPayment(payment) {
console.log(payment.year);
}
printLine();
function printLine() {
console.log('---------------------------------------');
}
printLine();
processPaymentSchedule(1500,18, calculateMinimumPayment());
/*
It should take the balance monthly interest rate and minimum payment as arguments. Each time you calculate a new payment line, create an object literal with properties for the year balance and payment id and interest paid. Pass this object literal to the displayPayment function.
*/
Given these numbers (balance=1500, interest=18%, minimumPayment(a separate function showing 2% of the balance as minimum payment.))
Year / Balance / PaymentID / InterestPaid
1 1492.50 1 22.50
1484.89 2 67.16
(continue to till balance is zero)

Related

Wrong results calculating EMA (exponential moving average) using Javascript, Nodejs

I'm trying to calculate the EMA with this script.
But it does not give me the correct EMA.
This could be of many reasons, but i'm not sure what it is.
I've tried different formulas for the EMA without any better results, I'm really not a professional coder nor mathematician and thus i can't see what I'm doing wrong.
How Is the EMA value calculated over time? For the first value I calculate the first EMA using the SMA, i guess that should work - right?
My EMA value = 0.033144798412698406
Real EMA value = 0.033084
Close = last closing price
Period = 20;
Multiplier = (2 / (period + 1));
function calculateEMA() {
if (EMA == 0) {
EMA = (Close - SMA) * multiplier + SMA;
calculateEMA();
} else {
for (a = 0; a < period; a++) {
EMA = (Close - previous_ema) * multiplier + previous_ema;
console.log(EMA + " ema");
previous_ema = EMA;
}
}
}
// UPDATE Added my whole script (which can be runned)- https://pastebin.com/91GEuATM
You need Nodejs and the binance node api installed (npm install node-binance-api --save) ; Keep in mind that this is just my "test script" hence all the weird variable names etc.
//UPDATE 2 Ticks sample data https://pastebin.com/AFzf7GwQ

issues with this program

I came across this program from a You Don't Know JS books book on github:
const SPENDING_THRESHOLD = 200;
const TAX_RATE = 0.08;
const PHONE_PRICE = 99.99;
const ACCESSORY_PRICE = 9.99;
var bank_balance = 303.91;
var amount = 0;
function calculateTax(amount) {
return amount * TAX_RATE;
}
function formatAmount(amount) {
return "$" + amount.toFixed( 2 );
}
// keep buying phones while you still have money
while (amount < bank_balance) {
// buy a new phone!
amount = amount + PHONE_PRICE;
// can we afford the accessory?
if (amount < SPENDING_THRESHOLD) {
amount = amount + ACCESSORY_PRICE;
}
}
// don't forget to pay the government, too
amount = amount + calculateTax( amount );
console.log(
"Your purchase: " + formatAmount( amount )
);
// Your purchase: $334.76
// can you actually afford this purchase?
if (amount > bank_balance) {
console.log(
"You can't afford this purchase. :("
);
}
// You can't afford this purchase. :(
My issue is that it does not matter if I change the value of bank_balance to a higher value, but it keeps printing : You can't afford this purchase.
I have try to make it so it does not print : You can't afford this purchase.
I can't make it work. I'm starting to think that the program is wrong, but I think is just me.
I know the solution is simple but I cant see it nor find it.
It comes from your while(amount < bank_balance). You increase amount until it's bigger than bank_balance. So obviously, it's bigger than bank_balance after that.
Also, you can use the developer tools available in every modern browser (F12 for Chrome or Firefox will open them), where you can put break points and follow your code's flow.
I don't know what the program is meant to do but it doesn't seem to make much sense to me.
It "buys" phones as long as you have money, but doesn't check if you have enough money for an additional phone.
So in the end of the while loop you have spend exactly your whole money on phones or (much more likely) spend more money than you have.
On top of this there are accessorizes and taxes. So in the end, you won't ever be able to afford your purchase.
And no matter how high you raise you balance, the program is written to exceed it.
The programm would work probably better with the line
while (amount + PHONE_PRICE + calculateTax(amount + PHONE_PRICE) <= bank_balance)
or even
while (amount + PHONE_PRICE + ACCESSORY_PRICE + calculateTax(amount + PHONE_PRICE + ACCESSORY_PRICE)<= bank_balance)
Although I have to admit that I'm not sure what the purpose of the SPENDING_THRESHOLD is.
You keep adding new phones and accessories until it reaches the total amount. I guess total cost becomes very close to the amount hence when you add the tax on top of that it crosses the limit and you see that message. I would suggest you to compare(in the while loop) the phone price along with the tax. Something like:
while (amount + PHONE_PRICE + calculateTax( PHONE_PRICE ) < bank_balance) {
// buy a new phone!
amount = amount + PHONE_PRICE + calculateTax( PHONE_PRICE );
// can we afford the accessory?
if (amount < SPENDING_THRESHOLD) {
amount = amount + ACCESSORY_PRICE;
}
}
Refer https://jsfiddle.net/Lxwscbbq/
Open the browser console to see the messages.
Program is not wrong it is simple:
var bank_balance = 303.91;
which is global. Suppose you provided
amount = 200;
amount = amount + calculateTax( amount );
amount = 200 + calculateTax(200);
if you check condition and you can see amount is grater than entered amount. Thats why you are getting "You can't afford purchase"
if (amount > bank_balance) {
console.log(
"You can't afford this purchase. :("
);
}

Javascript: How do you enter in unknown variables?

I'm making a game where the player can pick 3 different characters. However I am running into a glaring problem, that being, when I create a function (like a attack function), it is linked to only 1 specific character.
I would rather have my code be written where when the person picks their character, all can use the same attack skill without me having to write 3 different ones. Also, the attack skills are linked to a button, so it must be diverse.
I can't have a designated attack button for X player. So how do I make my code so it can add all characters instead of just 1 specified character?
Example: Looking at my function below for the strike attack. I can set it to dwarf & angel which is fine. However what if the player picks a ELF character instead? Then the function will not work because it believes the character is a dwarf, fighting a angel. How can I fix this?
New=Object.create;
actor = {
primaryStats: function (level, hp, hpcap, balance, balancecap, exp){
this.level = level;
this.hp = hp;
this.hpcap = hpcap;
this.balance = balance;
this.balancecap = balancecap;
this.exp = exp;
},
player = New (actor),
monster = New (actor),
dwarf = New(player),
human = New(player),
elf = New(player),
angel = New(monster),
demon = New(monster),
dragon = New(monster);
//ATTACK SKILL ONE
dom.el("strike").onclick = function strike() {
playerHitCalc(dwarf, angel);
};
playerHitCalc = function(character, boss){
roll = Math.floor(Math.random() * character.accuracy + 1);
if (roll > boss.agility){
var hit = true;
}
else {
hit = false;
logMessage(boss.ID + " " + "has evaded your attack!")
}
playerDamCalc = function(){
if (hit == true){ //If you score a successful hit
var damage = Math.floor(Math.random() * character.strength + 1);
var totalDamage = damage - boss.armor; // Subtract Damage from Bosses Armor
if(totalDamage <= 0)totalDamage += boss.armor; // Add boss armor to prevent Negative Numbers
boss.hp -= totalDamage; // Subtract bosses HP from damage.
character.exp += totalDamage * 0.25; // Gain 1 exp point per 4 damage done
dom.setText("bosshealthcounter", boss.hp) // Update Bosses Health
logMessage("You hit " + boss.ID + " for " + totalDamage + " damage!");
}
You can use data attributes to link a dom element to particular characters. For example -
<button class="attack-btn" data-attacker="dwarf" data-target="angel">Attack</button>
Then in the on click handler, you can extract that particular element's attributes attacker and target instead of hardcoding the values.
Hope that helps!
One thing you are doing is creating Player and Monster from Actor and then specific player class from Player and the same for monster.
Problem lies in that now you have a specific handle for each type of player and each type of monster.
If we would want to edit current code, you would have to add currentPlayer and currentMonster variables that you would make equal to the Player and Monster you want to fight. Then you could avoid referencing specific player and specific monster and just use
playerHitCalc(currentPlayer, currentMonster);
But I would suggest changing things a little bit and create objects in a little different way.

Car loan calculator in Javascript displays nothing

I hope someone can help with this:
I am currently working on a motor dealership website. On this website is a car loan calculator that calculates your monthly repayments. I have successfully created a basic calculator that calculates the correct amount.
The client isn't happy with that. They want a more advanced calculator that calculates the monthly repayments with balloon considerations and a deposit and initiation and admin fees.
I altered the code to reflect that, but now the thing won't work anymore. I can't find any error in my code.
Here's the Javascript that's supposed to do the calculation:
function calculate() {
// Get the user's input from the form. Assume it is all valid.
// Convert interest from a percentage to a decimal, and convert from
// an annual rate to a monthly rate. Convert payment period in years
// to the number of monthly payments.
var principal = document.loandata.principal.value;
var lessDeposit = document.loandata.deposit.value;
var adminFee = document.loandata.admin.value;
var initiationFee = document.loandata.initiation.value;
var interest = document.loandata.interest.value / 100 / 12;
var payments = document.loandata.years.value * 12;
var balloonPercent = document.loandata.balloon.value / 100;
// Now compute the monthly payment figure, using esoteric math.
var balloonFinal = (principal * balloonPercent);
var totalPrincipal = (principal + initiationFee + balloonfinal - lessDeposit);
var x = Math.pow(1 + interest, payments);
var monthly = (totalPrincipal*x*interest)/(x-1);
// Check that the result is a finite number. If so, display the results
if (!isNaN(monthly) &&
(monthly != Number.POSITIVE_INFINITY) &&
(monthly != Number.NEGATIVE_INFINITY)) {
document.loandata.payment.value = round(monthly + adminFee);
document.loandata.total.value = round(monthly * payments);
document.loandata.totalinterest.value =
round((monthly * payments) - principal);
}
// Otherwise, the user's input was probably invalid, so don't
// display anything.
else {
document.loandata.payment.value = "";
document.loandata.total.value = "";
document.loandata.totalinterest.value = "";
}
}
// This simple method rounds a number to two decimal places.
function round(x) {
return Math.round(x*100)/100;
}
Also, if possible, there needs to be some validation. Like purchase price, interest rate and payment period are required fields. But the rest are not. So if someone fills in the required fields but not the rest, the calculator still needs to work, but if someone does NOT complete one of the required fields, they need to be prompted to do so.
For those who don't know what a balloon payment is, here's an example;
Purchase Price is R117 000
You decide on a balloon payment of 30%. On the initial purchase price, the 30% amounts to R35 100. This amount is then subtracted from your initial purchase price so that means your purchase is now R81 900. After that comes the deposit, which is subtracted, and the extras and the admin and initiation fees. So the monthly repayments are calculated using this new purchase price of R81 900 + extras - deposit (if any). For interest sake, after your contract ends, you have to pay the balloon amount in full or re-finance the vehicle.
PS: I'm a complete newbie when it comes to JavaScript. So any help would be greatly appreciated.
If the result is nothing, one of these three conditions is likely triggering the else statement:
if (!isNaN(monthly) &&
(monthly != Number.POSITIVE_INFINITY) &&
(monthly != Number.NEGATIVE_INFINITY)) {
You have a typo in the JS, you need to change balloonfinal to be balloonFinal with a capital F in the var totalPrincipal = line of code.
The principal, lessDeposit, adminFee, initiationFee may also need to be typecast as an integer/float.

jquery: percentage of two numbers (Part 2)

this is continuation of last successful topic
jquery: percentage of two numbers
First of all I want to thank you for your prompt support of previuous post.
Now I would like to make my script a little bit more complicated. I want to achive the following: If I insert PRICE1 and PRICE2 to have RATE between THEM, then I can change the RATE with other value and PRICE2 to change to the corespondent value according to RATE value.
My script of calculation is close to be correct, but my low knowledge about JQuery make me to ask you where I do something wrong.
Thank you for your support!
<script src="libs/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
$("#PRICE1, #PRICE2").change(function() {
var result = parseFloat(parseFloat($("#PRICE1").val(), 10) - parseFloat($("#PRICE1").val(), 10))/ parseFloat($("#PRICE2").val(), 10) * 100;
$('#RATE').val(result||'');
})
else {
$("#PRICE1, #RATE").change(function() {
var result = parseFloat(parseFloat($("#PRICE1").val(), 10) * parseFloat($("#RATE").val(), 10))/ 100 + parseFloat($("#PRICE1").val(), 10);
$('#PRICE2').val(result||'');
})}
});
</script>
EDITED:
THE CODE ALMOST WORKING CORRECTLY WHICH MIGHT HELP OTHERS:
$(document).ready(function(){
$("#priceOne, #priceTwo").change(function() {
var priceOne = parseFloat($("#priceOne").val());
var priceTwo = parseFloat($("#priceTwo").val());
$('#Rate').val((priceTwo - priceOne) / priceOne * 100); // Set the rate
});
// If price one or the rate is changed, adjust price two.
$("#priceOne, #RATE").change(function() {
var priceOne = parseFloat($("#priceOne").val());
var rate = parseFloat($("#Rate").val());
$('#priceTwo').val((priceOne * rate)/ 100 + priceOne);
});
})
Thank you everyone who help me!!!
There is a else and no matching if. I'm not sure what you're trying to achieve, but some condition needs to be checked.
I'm going to try and code what it appears you need. But I'm going to rename your variables, not only because allcaps are hard to type, but unless it's a constant or a macro, they shouldn't be used.
// In ready() callback
// #NOTE - This does NO error checking for division by 0 or other NaN operations.
// If price two is changed, adjust the rate.
$("#priceTwo").change(function() {
var priceOne = parseFloat($("#priceOne").val());
var priceTwo = parseFloat($(this).val());
$("#rate").val(priceTwo / priceOne); // Set the rate
});
// If price one or the rate is changed, adjust price two.
$("#rate #priceOne").change(function() {
var priceOne = parseFloat($("#priceOne").val());
var rate = parseFloat($("#rate").val());
$("#priceTwo").val(priceOne * rate);
});
There are a few things about your code that needs attention:
parseFloat doesn't take a radix argument, the 10 you pass it is ignored.
parseFloat(parseFloat(... is pointless, I'm not sure why you've done this.
Don't use jQuery to select the same element multiple times in the same scope. Save the value and re-use it - save yourself some cycles.
As I mentioned, don't name your variables in all capitals unless they are some sort of constant that should never be changed, it's good to have clean style habits.

Categories

Resources