Save sum in variable in jQuery each for range - javascript

I am working on a specific calculator and I need to sum up variables in my jQuery.each for a range from 0 to 4 (= 5 years).
I have found many pages where the solution is described, but only with references to an element, not to the range.
My code:
jQuery.each(new Array(duration),
function(n){
var investment = 1000; // 1000$
var duration = 5; // 5 years
var revenueRatio = 10; // 10% revenue / year
var reinvest = 50; // 50% reinvestment
if(n == 0){
var revenueReinvest = 0;
var newInvestment = investment;
}else{
console.log(revenueReinvest); // undefined
console.log(newInvestment); // undefined
var interest = ( ( newInvestment - investment ) * ( revenueRatio / 100 ) );
var removeInterest = interest * reinvest / 100;
var restIntereset = interest - removeInterest;
revenueReinvest += restIntereset;
newInvestment = newInvestment + revenueReinvest;
}
}
);
Any help or idea would be great! Thank you!

The issue with the code is that you have declared revenueReinvest and newInvestment inside the if block and using it inside the else block. This wont be possible. Declare revenueReinvest and newInvestment outside each loop and assign the values to them inside if statement. Now you can access the assigned values inside else statement.
You have to declare the variable outside the loop to prevent redeclaring of the variable inside the loop. Each time the variable gets redeclared inside the loop, old value will be lost.
The below code will work
$(document).ready(function () {
const duration = 4;
// Declare here
var revenueReinvest;
var newInvestment;
jQuery.each(new Array(duration),
function (n) {
var investment = 1000; // 1000$
var duration = 5; // 5 years
var revenueRatio = 10; // 10% revenue / year
var reinvest = 50; // 50% reinvestment
if (n == 0) {
// assign value here
revenueReinvest = 0;
newInvestment = investment;
} else {
var interest = ((newInvestment - investment) * (revenueRatio / 100));
var removeInterest = interest * reinvest / 100;
var restIntereset = interest - removeInterest;
revenueReinvest += restIntereset;
newInvestment = newInvestment + revenueReinvest;
}
}
);
console.log(revenueReinvest); // will be defined
console.log(newInvestment); // will be defined
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

Related

set variable by using localstorage

i am trying to create the driver performance assistant.
when i start up the page it needs to read the variable from the last time and use that to count up.
(i have created a dashboard that reads data through a plugin from a game. i am trying to create the driver performance assistant from DAF (truck brand). the way it should work is when rolling out the vehicle it counts up a variable accordingly to the time it is rolling out (this part i have created and it works) now my problem is. i am also trying to save it in the localstorage so it wont get lost. but the variable is doing weird things when i tries to read the localstorage data.
this code only needs to be in javascript.
// variables for driver score
var startBrake = 0;
var endBrake = 0;
var timeDiffBrake = 0;
var countBrake = localStorage.getItem('brake');
var startRollout = 0;
var endRollout = 0;
var timeDiffRollout = 0;
var countRollout = localStorage.getItem('rollout');
var speed = Math.abs(data.truck.speed > 0 ? Math.floor(data.truck.speed) : Math.round(data.truck.speed));
var throttle = utils.formatFloat(data.truck.gameThrottle, 2);
var serviceBrake = utils.formatFloat(data.truck.userBrake, 2);
var retarder = data.truck.retarderBrake;
var engineBrake = data.truck.motorBrakeOn;
var cruiseControl = data.truck.cruiseControlOn;
var fuelConsumption = data.truck.fuelAverageConsumption * 100;
// ANTICIPATE
// Braking to long
if (speed >= 50) {
if (serviceBrake < 0.1) {
startBrake = new Date();
} else if (serviceBrake > 0.25) {
endBrake = new Date();
timeDiffBrake = (endBrake - startBrake) / 1000;
if (timeDiffBrake > 5) {
countBrake -= 0.01;
// add "te lang remmen" display
}
}
}
localStorage.setItem('brake', countBrake);
// Rolling out
if (speed > 30 && speed < 89) {
if (throttle > 0) {
startRollout = new Date();
} else if (throttle < 0.05 && serviceBrake == 0) {
endRollout = new Date();
timeDiffRollout = (endRollout - startRollout) / 1000;
if (timeDiffRollout > 1) {
countRollout += 0.01;
// maybe add display
}
}
}
localStorage.setItem('rollout', countRollout);
// EFFICIENT BRAKING
var brake = localStorage.getItem('brake');
var rollout = localStorage.getItem('rollout');
var anticipate = brake + rollout;
var efficientBraking = 0; // haven't done this yet
var driverScore = Math.round((efficientBraking + anticipate) / 2);
data.drivingScorePercent = driverScore <= 0 ? 0 : driverScore >= 100 ? 100 : driverScore;
the main problem is this variable
var countRollout = localStorage.getItem('rollout');
it keeps saying my data is NAN (i think undefined)
i changed the lines to what "mister jojo" suggested but somehow i get some wierd data from the localstorage. i assumed that a "var += 0.01" would count 0.01 up but somehow it goes like this "0.010.010.010.010.01" instead of 0.01, 0.02, 0.03.
When you are declaring the countBrake and countRollout variables, the value are undefined because you didn't set the values to localStorage yet. So, you can check whether there is already a value set in localStorage and set default value incase the value isn't set yet:
var countBrake = localStorage.getItem('brake') !== undefined ? localStorage.getItem('brake') : 0;
var countRollout = localStorage.getItem('rollout') !== undefined localStorage.getItem('rollout') : 0;
more simple for Shuvo answer is
with the use of the Nullish coalescing operator (??)
var countBrake = localStorage.getItem('brake') ?? 0
, countRollout = localStorage.getItem('rollout') ?? 0
;

Not Throwing an error, but not logging to console to test

Morning. I'm trying to calculate population density using for loop and if/else statements. When logging the results I get no errors but also get no log results for the variable density. Wonder if folks might be able to see what I'm missing in my functions. Thanks!
var cityCoords = [[30.5833302, -114.2666702], [48.864716, 2.349014],[40.730610, -73.935242 ]] // city coords
var cityPops = [8266000, 10958000, 19491339] // city populations
var cityAreas = [3280, 41, 303]// city areas in sq. miles
// NOTE. You can use the arrays you built in Lab 3, just make sure you keep track of your variable names
var button = document.getElementById("map-cities");
button.addEventListener("click", function () {
var units = prompt('Enter the units for calculating population density', 'Enter "miles" or "km"');
var mapCities = function(){ // assign function to variable mapCities
mapCities(units); // call mapCities function units variable as an argument
}
// call a function named mapCities, and send the units variable as an argument
}); // addEventListener callback function ends here
// Define function
function mapCities(units) {
for (var i = 0; i < cities.length; i++) {
var cityName = cities[i] ;
var cityNumPeeps = cityPops[i];
var cityZone = cityAreas[i];
var density = calcPopDensity(CityNumPeeps, CityZone, units); // call calcPopDensity passing population, cityZone and units as arguments
console.log(density);
}
};
function calcPopDensity(pop,area,unit){
if (units == "miles"){
cityZone/cityNumPeeps
return
} else if (units == "km"){
cityZone * 1.60934 / cityNumPeeps
return
}
};
There's... a few issues here. But, we all learn from our mistakes!
var cityCoords = [[30.5833302, -114.2666702], [48.864716, 2.349014],[40.730610, -73.935242 ]]
var cityPops = [8266000, 10958000, 19491339]
var cityAreas = [3280, 41, 303]
var button = document.getElementById("map-cities");
button.addEventListener("click", function () {
var units = prompt('Enter the units for calculating population density', 'Enter "miles" or "km"');
mapCities(units); // <= You just want to call the function here, no need to do the function-wrapping you had!
}
});
function mapCities(units) {
for (var i = 0; i < cities.length; i++) { // <= You don't actually have this array defined (cities)?
var cityName = cities[i] ;
var cityNumPeeps = cityPops[i];
var cityZone = cityAreas[i];
var density = calcPopDensity(CityNumPeeps, CityZone, units); // <= match case - 'cityNumPeeps' vs 'CityNumPeeps' etc
console.log(density);
}
};
function calcPopDensity(pop,area,unit){
if (units == "miles"){
return cityZone/cityNumPeeps // <= move the return to this line - we want the result of the calculation back!
} else if (units == "km"){
return cityZone * 1.60934 / cityNumPeeps // <= again, return statement
}
};

How to reduce number of computations during d3.js transition?

So right now, I'm trying to implement a search bar function into my d3.js plot. Right now it doesn't do anything, but that's not the issue at the moment. The problem is that when I type/delete something from the bar, there's visible lag/choppiness in the characters appearing/disappearing. I believe the issue is stemming from my plot. I have 140+ dots moving around the screen, and their position is being interpolated. So from the beginning to the end of the transition, my code has to compute 140 positions thousands of times over.
I've looked into trying to reduce the cardinality of the d3.interpolateNumber function, but it appears that there isn't a third argument to change the number of terms like in a linspace command. Right now I have an array of 1000 numbers for my function to run through, but I don't know how to pass the array to my other functions.
Below are the pertinent functions for this issue. The commented line in tweenPatch is the original code I had that made my code run, but gave my plot computational issues. Variables arr, curr, and step were my attempt to fix the situation, but I haven't been able to figure out how to pass the array into displayPatch().
function tweenPatch() {
var patch = d3.interpolateNumber(1, 26);
var arr = [];
var curr = 1;
var step = (26 - 1) / (1000 - 1);
for (var i = 0; i < 1000; i++) {
arr.push(curr + (step * i));
}
return arr.forEach(function(d) {
console.log(arr[d]);
displayPatch(arr[d]);
});
//return function(t) { displayPatch(t); };
}
function displayPatch(patch) {
dots.data(interpolateData(patch), function(d) { return d.name; }).call(position).sort(order);
var inter = Math.floor(patch);
var seas = 8;
var patc = 1;
if (inter > 24) {
seas = 9;
patc = inter - 24;
} else {
patc = inter;
}
label.text("Patch " + seas + "." + patc);
}
function interpolateValues(values, number) {
old = Math.floor(number);
upd = Math.ceil(number);
var old_data = values.filter(function(d) {return d.internal == old;});
var new_data = values.filter(function(d) {return d.internal == upd;});
var oobj = old_data[0];
var nobj = new_data[0];
var onum = oobj[Object.keys(oobj)[4]];
var nnum = nobj[Object.keys(nobj)[4]];
var difint = number - old;
var difdis = 0;
var newnum = nnum;
if (nnum > onum) {
difdis = nnum - onum;
newnum = ((difint) * difdis) + onum;
} else if (onum > nnum) {
difdis = onum - nnum;
newnum = onum - ((difint) * difdis);
}
return newnum;
}
I believe switching my SVG to a canvas may help things, but since I have no knowledge of canvas I'd rather leave that as a last resort.

Creating a slider between two numbers

So I've been working on re-producing the slider found here https://www.skylight.io/ ( Scroll down to find the price slider ).
So far Ive managed to create something similiar, but some numbers are hard coded, making it difficult to change and not very re-usable.
I've been researching around and I think I need to use Math.log() and Math.exp() together to achieve something like in the link above but I'm not sure.
Heres a jsfiddle of what I have so far https://jsfiddle.net/7wrvpb34/.
I feel that its the maths part of this problem that is halting me I think, so any help would be greatly appreciated.
Javascript code below:
var slider = document.getElementById("slider")
var sliderFill = document.getElementById("slider-fill")
var knob = document.getElementById("knob")
var mouseDown;
var mousePos = {x:0};
var knobPosition;
var minPrice = 20;
var price = 0;
var minRequests = 50;
var requests = 50 + ",000";
var incrementSpeed = 2;
var incrementModifier = 20;
var incrementValue = 1;
var minMillionCount = 1;
var millionCount = 1;
var previousRequestAmount = 0;
document.getElementById("price").innerHTML = price;
document.getElementById("requests").innerHTML = requests;
highlightTable(1);
document.addEventListener('mousemove', function(e) {
if(mouseDown) {
updateSlider(e);
}
})
function updateSlider(event) {
mousePos.x = event.clientX - slider.getBoundingClientRect().left;
mousePos.x -= knob.offsetWidth / 2;
console.log(mousePos.x);
if(mousePos.x < 0) {
knob.style.left = "0px";
sliderFill.style.width = "0px";
price = 0;
requests = 50 + ",000";
document.getElementById("price").innerHTML = price;
document.getElementById("requests").innerHTML = requests;
return
}
if(mousePos.x > slider.offsetWidth - 20) {
return
}
sliderFill.style.width = mousePos.x + 10 + "px";
knob.style.left = mousePos.x + "px";
//Increase requests by using X position of mouse
incrementSpeed = mousePos.x / incrementModifier;
requests = minRequests + (mousePos.x * incrementSpeed);
//Round to nearest 1
requests = Math.round(requests / incrementValue) * incrementValue;
if (requests >= 1000){
var m = requests/ 1000;
m = Math.round(m / 1) * 1;
//Problem, lower the modifier depending on requests
incrementModifier = 20 * 0.95;
document.getElementById("requests").innerHTML = m + " million";
//Adjust Prices
if(( requests >= 1000) && (requests < 10000)) {
var numOfMillions = requests / 100;
//Round to closest 10.
//10 * number of millions
var rounded = Math.round(numOfMillions / 10) * 10;
price = minPrice + rounded;
highlightTable(3);
}
//Adjust Prices
if(requests >= 10000) {
var numOfMillions = requests / 1000;
var rounded = Math.round(numOfMillions / 1) * 1;
var basePrice = minPrice * 6;
price = basePrice + rounded;
highlightTable(4);
}
} else {
incrementModifier = 20;
document.getElementById("requests").innerHTML = requests + ",000"
if(requests < 100) {
highlightTable(1);
price = 0;
} else {
highlightTable(2);
price = 20;
}
}
previousRequestAmount = requests;
document.getElementById("price").innerHTML = price;
}
knob.addEventListener('mousedown', function() {
mouseDown = true;
});
document.addEventListener('mouseup', function() {
mouseDown = false;
});
function highlightTable(rowNum) {
var table = document.getElementById("payment-table")
for(var i = 0; i < table.rows.length; ++i) {
var row = table.rows[i]
if(i == rowNum) {
row.style.background = "grey"
} else {
row.style.background = "white";
}
}
}
Thank you for your time.
If you want it to be reusable you need to create a mathematical function that assigns a result to the number of requests. I will give you a very easy example.
If you want a different result for 1,10,100,100,10000 etc
var d = Math.log10(requests);
if(d<1){
doSomething();
}else if(d<2){
doSomethingElse();
} //etc
This way if you want to change the specific values that create certain results, all you need to do is change the function.
This only works if your tiers of requests follow a math function, if they don't you need to hard code it.
However if say they don't follow a math function, but you know how you would like them to change based on a value then you can do this.
var changingValue = 4;
if(requests < 400*changingValue){
doSomthing();
}else if(requests <= 400*changingValue*changingValue){
doSomethingElse();
}else{// the requests is greater than any of the above
doTheOtherThing();
}
Edit:
For the second one you need to make sure that each condition if always larger than the other from top to bottom.
The description "increasingly increasing" matches an arbitrary number of functions. I assume you also want it to be continuous, since you already have a non-continuous solution.
TL;DR
Use an exponential function.
Generic approach
Assuming imin and imax are the minimal and maximal values of the slider (i for input) and omin and omax are the minimal and maximal values to be displayed, the simplest thing I can think of would be a multiplication by something based on the input value:
f(x)
{
return omin + (omax - omin) * g((x - imin) / (imax - imin));
}
This will pass 0 to g if x == imin and 1 if x == imax.
The return value r of g(y) should be
r == 0 for y == 0
r == 1 for y == 1
0 < r < y for 0 < y < 1
The simplest function that I can think of that fulfills this is an exponential function with exponent > 1.
An exponent of 1 would be a linear function.
An exponent of 2 would be make the middle of the slider display one fourth of the maximum price instead of half of it.
But you really need to find that exponent yourself, based on your needs.

Calculating investment values with javascript

I am currently learning javascript. I have created a calculator to find invesment future value. It is giving me an incorrect value when it displays the future value. I have checked the formula several times but it still gives me an error. Also, I have set alerts to appear if the interest is less than 0 or greater than 20 but nothing is showing. How would i be able to properly display the correct future value and alerts when necessary? Example
Javascript
var $ = function (id) {
return document.getElementById(id);
}
var calculate_click = function () {
var investment = parseFloat( $("investment").value );
var annualRate = parseFloat( $("rate").value ) /100;
var years = parseInt( $("years").value );
$("futureValue").value = "";
if (isNaN(investment) || investment <= 0) {
alert("Investment must be a valid number\nand greater than zero.");
} else if(isNaN(annualRate) || annualRate <= 0 || annualRate > 20) {
alert("Annual rate must be a valid number\nand less than or equal to 20.");
} else if(isNaN(years) || years <= 0 || years > 50) {
alert("Years must be a valid number\nand less than or equal to 50.");
} else {
//var monthlyRate = annualRate / 12;
//var months = years * 12;
var futureValue = 0;
for ( i = 1; i <= years; i++ ) {
futureValue = ( futureValue + investment ) *
( 1 + annualRate );
}
$("futureValue").value = futureValue.toFixed(2);
}
}
var clear_click = function () {
$("investment").value = "";
$("rate").value = "";
$("years").value = "";
$("futureValue").value = "";
}
window.onload = function () {
$("calculate").onclick = calculate_click;
$("investment").focus();
$("clear").onclick = clear_click;
}
Using .value is incorrect, its javascript, while this is jquery, try adding a # in front and use .val() instead.
Its similar to this:
jquery function val() is not equivalent to "$(this).value="?
EDIT
He's not using jquery, ignore this.
If I remember the future value correctly, you are messing up the formula, which is why you aren't getting the expected value.
Change:
for ( i = 1; i <= years; i++ ) {
futureValue = ( futureValue + investment ) *
( 1 + annualRate );
}
To:
futureValue = investment*Math.pow((1+annualRate), years);
Not quite sure why you are looping through each year, but it should be based on powers to the number of years (again, if I remember correctly)
// to calculate the increase in production for each month
function getPlan(startProduction, numberOfMonths, percent) { // the function is declared
let Goals = []; //Goals is assigned
let currentProduction=startProduction; //declaring the currentProduction by assigning the value of startProduction
for(let i=0; i<numberOfMonths;i++){ //for each month, increase the currentProduction by the percentage interest = Math.floor(currentProduction+(currentProduction*(percent/100)));
currentProduction= interest;
//after each iteration, assign the new currentProduction
Goals.push(Math.floor(currentProduction));
//adding the currentprodcution of each months to the Goals
} return Goals; } console.log(getPlan(2000,6,67));
Output:
[ 3340, 5577, 9313, 15552, 25971, 43371 ]

Categories

Resources