I am trying something with javascript closure - javascript

I got 2 functions:
var number1 = 9
var number2 = 17;
//Get Percent of a the number1
function getPercent(x, y) {
return x * 100 / y;
}
var percentOfNumber1 = getPercent(number1, number2);
//Get rid of remainder
function getRemain(t) {
var remainder = t % 2;
t = t - remainder;
return t;
}
alert(getRemain(percentOfNumber1));
That works..but I want to close the getRemain function in the first function.
so What I did and I dont' get result with:
function getPercent(x, y) {
return x * 100 / y;
function getRemain(t) {
var remainder = t % 2;
t = t - remainder;
return t;
}
var numberClear = getRemain(result);
}
var result = getPercent(number1, number2);
alert(numberClear);
Can anyone explain the wrong approach to this?
"this is the first time I try closures I read couple of good explanations but didin't get the calling functions part really good I guess.."
Thnx.

You need to declare numberClear outside if you want to access it outside:
var numberClear;
function getPercent(x, y) {
function getRemain(t) {
return t - t % 2;
}
var result = x * 100 / y;
numberClear = getRemain(result);
return result;
}
var result = getPercent(number1, number2);
alert(numberClear);

Why not this?
Return both the values at once
function getPercentage(a, b){
function getRemain(t)
{
var remainder = t % 2;
t = t - remainder;
return t;
}
return {
percentage: a / b * 100,
remain: getRemain(a / b * 100)
}
};
var result = getPercentage(9, 17);
alert(result.percentage);
alert(result.remain);

You simply didn't return the result properly:
function getPercent(x,y)
{
function getRemain(t)
{
var remainder = t % 2;
t = t - remainder;
return t;
}
return getRemain(x * 100 / y); // <-- return what getRemain() gives you!
}
var result = getPercent(number1, number2);

There is no way to access a variable declared inside a function from outside it.
You could try this:
var getPercent = (function() {
function getRemain(t)
{
var remainder = t % 2;
t = t - remainder;
return t;
}
return function (x,y)
{
var percent = x * 100 / y;
return {
percent: percent,
remainder: getRemain(percent)
};
}
})();
In this way the getRemain function is not accessible and the getPercent function will return both the percent and remainder values.

try this
var numberClear;
function getPercent(x, y) {
var percentange = x * 100 / y;
numberClear = getRemain(result); // set your numberClear Variable here
return percentange;
}
function getRemain(t) {
return t - t % 2;
}
var result = getPercent(number1, number2);
alert(numberClear);

Related

How to calculate the square root without using library and built-in methods in Javascript?

Please help me to write a function to compute the square root of positive real numbers using the formula:
x i+1 = (1/2) * (xi + (A / x1)),
where 'A' - input real number.
On the zero iteration next statements have been taken x0 = A
The error should be at least 10-6
Output
sqrt (2) = 1.414
sqrt (9) = 3
sqrt (25) = 5
You could take xi (x) and the new value of xi + 1 (x1) and check if the values are equal. Then end the series and return that value.
For starting, you need an apporopriate value like the half of the given value.
function sqrt(a) {
var x,
x1 = a / 2;
do {
x = x1;
x1 = (x + (a / x)) / 2;
} while (x !== x1);
return x;
}
console.log(sqrt (2)); // 1.414
console.log(sqrt (9)); // 3
console.log(sqrt (25)); // 5
You can also use bisection - a more general method for solving problems:
var sqrt = function(n) {
if (n<0) {
throw "are you kidding?! we are REAL here.";
}
if (n === 0) {
return 0;
}
var bisect = function(l,r) {
var avg = (l+r)/2;
if (r-l<0.00000001) {
return (l+r)/2;
}
if (avg*avg > n) {
return bisect(l, avg);
} else if (avg*avg < n) {
return bisect(avg, r);
}
}
return bisect(0, n < 1 ? 1 : n);
}

Accessing local JSON data in function on Global Scope

I am trying to access JSON data retrieved from JSON-Server within a function outside the function scope for the past 3 hours with no luck, below is my Code:
http.get(`http://localhost:3000/${depairport}`)
.then(data => airportNav(data))
.catch(err => console.log(err));
var number1 = 1.0;
var number2 = 2.0;
var airportNav = function calculateDepNav(depNav){
number1 = depNav.lat;
number2 = depNav.lon;
return number1, number2;
}
console.log(number1, number2);
How should I access depNav outside of this scope?
Got it, was able to do it with the below, used a for loop for html requests then used an if statement to calculate the distance when the html responses were done.
for(let i=0; i<urls.length; i++){
http.get(urls[i])
.then(data => {
responses.push(data);
if(responses.length == 2){
distance(responses[0].lat, responses[0].lon, responses[1].lat, responses[1].lon);
function distance(lat1, lon1, lat2, lon2) {
var p = 0.017453292519943295; // Math.PI / 180
var c = Math.cos;
var a = 0.5 - c((lat2 - lat1) * p)/2 +
c(lat1 * p) * c(lat2 * p) *
(1 - c((lon2 - lon1) * p))/2;
console.log(12742 * Math.asin(Math.sqrt(a)));
return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
}
}
})
.catch(err => console.log(err));
}

High order function with javascript trouble

I want to be able to run the func n times with this createIterator function.
var createIterator = function (func, n) {
getDouble = function (x) {
return x + x;
};
return getDouble * n;
};
I want to be able to do this with the code:
var getQuad = createIterator(getDouble, 2);
getQuad(2) //8
Here are the tests is needs to pass:
Test.describe("Iterator for 'getDouble' function", function() {
var getDouble = function (n) {
return n + n;
};
Test.it("Running the iterator for once", function() {
var doubleIterator = createIterator(getDouble, 1);
Test.assertEquals(doubleIterator(3), 6, "Returns double of 3 as 6");
Test.assertEquals(doubleIterator(5), 10, "Returns double of 5 as 10");
});
Test.it("Running the iterator twice", function() {
var getQuadruple = createIterator(getDouble, 2);
Test.assertEquals(getQuadruple(2), 8, "Returns quadruple of 2 as 8");
Test.assertEquals(getQuadruple(5), 20, "Returns quadruple of 5 as 20");
});
});
I have been at this for awhile and have not been able to figure this out. Any help would be awesome. Thanks!
You can write a simple repeat procedure that when applied to n, f, and x, will repeat the application of function f to argument x, n times.
// ES6
const repeat = n => f => x =>
n === 1 ? f(x) : repeat(n-1)(f)(f(x));
const getDouble = x => x * 2;
const double = repeat(1)(getDouble);
const quad = repeat(2)(getDouble);
See it work
console.log(double(3)); // 6
console.log(double(5)); // 10
console.log(quad(2)); // 8
console.log(quad(5)); // 20
Let step through the evaluation of one of the examples:
const double = repeat(1)(getDouble);
Because repeat has been applied to n and f here, it returns
x => 1 === 1 ? getDouble(x) : repeat(0)(getDouble)(getDouble(x))
Now, when we call
double(3);
Substitute 3 for x
1 === 1 ? getDouble(3) : repeat(0)(getDouble)(getDouble(3));
Because 1 === 1, the first part of the ternary expression is returned
getDouble(3); // 6
Recap:
double(3) === getDouble(3) === 6
Now let's see the same process for quad
const quad = repeat(2)(getDouble);
Because repeat has been applied to n and f here, it returns
x => 2 === 1 ? getDouble(x) : repeat(1)(getDouble)(getDouble(x))
Now, when we call
quad(2);
Substitue 2 for x
2 === 1 ? getDouble(2) : repeat(1)(getDouble)(getDouble(2));
Because 2 === 1 is false, the second part of the ternary expression is returned
repeat(1)(getDouble)(getDouble(2))
repeat(1)(getDouble)(4)
So we have to call repeat again, with n=1, f=getDouble, x=4, so
1 === 1 ? getDouble(4) : repeat(0)(getDouble)(getDouble(4))
Because 1 === 1, the first part of the ternary expression is returned
getDouble(4); // 8
Recap:
quad(2) === getDouble(4) === 8
If you need the ES5, here you go
// ES5
var repeat = function repeat(n) {
return function (f) {
return function (x) {
return n === 1 ? f(x) : repeat(n - 1)(f)(f(x));
};
};
};
var getDouble = function getDouble(x) {
return x * 2;
};
var double = repeat(1)(getDouble);
var quad = repeat(2)(getDouble);
console.log(double(3)); // 6
console.log(double(5)); // 10
console.log(quad(2)); // 8
console.log(quad(5)); // 20
Lastly,
If you want your original API, which I believe to be inferior, we can still implement that
// ES6
const createIterator = (f, n) => x =>
n === 1 ? f(x) : createIterator(f, n-1)(f(x));
const getDouble = x => x * 2;
const double = createIterator(getDouble, 1);
const quad = createIterator(getDouble, 2);
And here's the ES5
// ES5
var createIterator = function createIterator(f, n) {
return function (x) {
return n === 1 ? f(x) : createIterator(f, n - 1)(f(x));
};
};
var getDouble = function getDouble(x) {
return x * 2;
};
var double = createIterator(getDouble, 1);
var quad = createIterator(getDouble, 2);
Both implementations work identically
So why is repeat(n)(f)(x) better ?
Well, because the function is fully curried, you can partially apply it in meaningful ways.
const getDouble = x => x * 2;
const once = repeat(1);
const twice = repeat(2);
const thrice = repeat(3);
const quad = twice(getDouble);
quad(5); // 20
const annoyingAlert = thrice(x => {alert(x); return x;});
annoyingAlert('wake up !'); // displays 'wake up !' three times
Your function isn't as flexible because it takes the function, f, and the number of times, n, as a tuple. Getting around this would require manually currying your function or using a Function.prototype.bind hack.
Try rearranging variables. Note, getDouble would be undefined at var getQuad = createIterator(getDouble, 2); as getDouble is defined within createIterator
var createIterator = function (func, n) {
getDouble = function (x) {
return (x + x) * n;
};
return func || getDouble;
};
var getQuad = createIterator(null, 2);
console.log(getQuad(2)) //8
alternatively
var createIterator = function(func, n) {
getDouble = function(x) {
return x + x;
};
return func.bind(null, n * n) || (getDouble(n)) * n;
};
var getQuad = createIterator(function(x) {
return x + x;
}, 2);
console.log(getQuad(2))
I just want to run getDouble n times.
You could use a loop inside of createIterator , return accumulated value as variable within function returned from createIterator that can be multiplied by parameter passed to getQuad
var createIterator = function(func, n) {
getDouble = function(x) {
return x + x;
};
var curr = n, res = 0;
while (--curr) {
res += func && func(n) || getDouble(n);
}
return function(y) {
return res * y
}
};
var getQuad = createIterator(null, 2);
console.log(getQuad(5)) // 20
You can do it like this,
Create an empty array of n
Fill the array by the function(arguments)
Join the array by operator
Create a function constructor using the joined array and arguments
Use the new function inside another function to pass the arguments from outside, and then return this new function.
Code snippet of what I am saying is here (if your browser supports Array.prototype.fill)
var createIterator = function (func, n, operator) {
operator = operator || "+";
var inner = Function(["f", "a"], "return " + Array(n ).fill("f(a)").join(operator) + ";");
return function (arg) {
return inner(func, arg);
};
};
var c = createIterator(function (n) {return n + n;}, 2);
document.write(c(3) + "<br/>");
document.write(c(6) + "<br/>");
var d = createIterator(function (n) {return n + n;}, 3, "+");
document.write(d(3) + "<br/>");
document.write(d(6) + "<br/>");
otherwise use this snippet
var createIterator = function (func, n, operator) {
operator = operator || "+";
var array = [];
for (var i = 0; i < n; i += 1) {array[i] = "f(a)";}
var inner = Function(["f", "a"], "return " + array.join(operator) + ";");
return function (arg) {
return inner(func, arg);
};
};
var c = createIterator(function (n) {return n + n;}, 2);
document.write(c(3) + "<br/>");
document.write(c(6) + "<br/>");
var d = createIterator(function (n) {return n + n;}, 3, "+");
document.write(d(3) + "<br/>");
document.write(d(6) + "<br/>");

How to use Javascript class for xirr formula

Hello I have found a javascript class for some excel functions but i dont know how to use it. I need to use XIRR function but i dont know the type and format of parameters and the syntax.
Here is the code:
/* Based on
* - EGM Mathematical Finance class by Enrique Garcia M. <egarcia#egm.co>
* - A Guide to the PMT, FV, IPMT and PPMT Functions by Kevin (aka MWVisa1)
*/
var ExcelFormulas = {
PVIF: function(rate, nper) {
return Math.pow(1 + rate, nper);
},
FVIFA: function(rate, nper) {
return rate == 0? nper: (this.PVIF(rate, nper) - 1) / rate;
},
PMT: function(rate, nper, pv, fv, type) {
if (!fv) fv = 0;
if (!type) type = 0;
if (rate == 0) return -(pv + fv)/nper;
var pvif = Math.pow(1 + rate, nper);
var pmt = rate / (pvif - 1) * -(pv * pvif + fv);
if (type == 1) {
pmt /= (1 + rate);
};
return pmt;
},
IPMT: function(pv, pmt, rate, per) {
var tmp = Math.pow(1 + rate, per);
return 0 - (pv * tmp * rate + pmt * (tmp - 1));
},
PPMT: function(rate, per, nper, pv, fv, type) {
if (per < 1 || (per >= nper + 1)) return null;
var pmt = this.PMT(rate, nper, pv, fv, type);
var ipmt = this.IPMT(pv, pmt, rate, per - 1);
return pmt - ipmt;
},
DaysBetween: function(date1, date2) {
var oneDay = 24*60*60*1000;
return Math.round(Math.abs((date1.getTime() - date2.getTime())/oneDay));
},
// Change Date and Flow to date and value fields you use
XNPV: function(rate, values) {
var xnpv = 0.0;
var firstDate = new Date(values[0].Date);
for (var key in values) {
var tmp = values[key];
var value = tmp.Flow;
var date = new Date(tmp.Date);
xnpv += value / Math.pow(1 + rate, this.DaysBetween(firstDate, date)/365);
};
return xnpv;
},
XIRR: function(values, guess) {
if (!guess) guess = 0.1;
var x1 = 0.0;
var x2 = guess;
var f1 = this.XNPV(x1, values);
var f2 = this.XNPV(x2, values);
for (var i = 0; i < 100; i++) {
if ((f1 * f2) < 0.0) break;
if (Math.abs(f1) < Math.abs(f2)) {
f1 = this.XNPV(x1 += 1.6 * (x1 - x2), values);
}
else {
f2 = this.XNPV(x2 += 1.6 * (x2 - x1), values);
}
};
if ((f1 * f2) > 0.0) return null;
var f = this.XNPV(x1, values);
if (f < 0.0) {
var rtb = x1;
var dx = x2 - x1;
}
else {
var rtb = x2;
var dx = x1 - x2;
};
for (var i = 0; i < 100; i++) {
dx *= 0.5;
var x_mid = rtb + dx;
var f_mid = this.XNPV(x_mid, values);
if (f_mid <= 0.0) rtb = x_mid;
if ((Math.abs(f_mid) < 1.0e-6) || (Math.abs(dx) < 1.0e-6)) return x_mid;
};
return null;
}
};
You want to use XIRR, so let's look at its signature:
XIRR: function(values, guess)
What does it do with values?
var f1 = this.XNPV(x1, values);
So values must be whatever XNPV is expecting. It has this chunk at its core:
for (var key in values) {
var tmp = values[key];
var value = tmp.Flow;
var date = new Date(tmp.Date);
xnpv += value / Math.pow(1 + rate, this.DaysBetween(firstDate, date)/365);
};
So it is expecting values to be a dictionary (associative array), where the value part of the key-value pair has members .Flow and .Date. I assume .Flow is the cashflow, and from the DaysBetween method I can see that .Date is a javascript Date. The key is ignored, so it can be a numeric if we want. So let's make one of those:
var myInstrument = { 0: {Flow: 5, Date: new Date(2015, 7, 6)},
1: {Flow: 105, Date: new Date(2016, 7, 6)} };
(That is a dictionary (or array) declaration).
The other input to XIRR is guess, which it will use to solve something, but it will default to using 0.1 (10% !) if given a falsy input value. So we can call it with our myInstrument thus:
var myInternalReturn = XIRR(myInstrument, false);
NB: The XIRR function is implementing the Actual/365 Fixed day count convention for Annual payment frequency, which may not be appropriate for the instrument you are valuing. Maybe it won't make much difference, but it will be incorrect for semi-annual or 30/360, with particular problems around month-end dates, simple interest instruments and so on

In an array, how do I find the closest key given a float value?

I'm making an "acceleration" array like this:
acc["0100"] = 1;
acc["0300"] = 2;
acc["0600"] = 4;
acc["0900"] = 8;
acc["2000"] = 16;
acc["5000"] = 32;
And, when the user presses a key, I start a timer: this._startTick = (new Date()).getTime();
Now I have a timer that checks if the key is still pressed. If so, then I do something like:
this._delay = (new Date()).getTime() - this._startTick;
And now, based on this._delay, I'd like to find one of the previous values (1, 2, 4 or 8). How would you do that?
NB: if the value is greater than "5.0" then the result should always be 32.
NOTA: my goal is, given an elapsed time, find out which value is the best. I started the way I've just explained, but if you have another solution, I'll take it!
It's easier to operate on an array than on an object:
var accArr = [];
for (time in acc) {
accArr.push({time: time, value: acc[time]});
}
Assuming you have an array, you can do:
function getValue(delay) {
var diffs = accArr.map(function (e) { return Math.abs(e.time - delay); });
return accArr[diffs.indexOf(Math.min.apply(null, diffs))].value;
}
EDIT:
Well, you didn't mention that this is a performance-critical function. In that case, I would recommend picking a granularity (e.g. 0.05, so the multiplier for delay is 20) and pre-calculating all values from 0 to MAX_DELAY:
var multiplier = 20,
granularity = 1 / multiplier;
var delayValues = (function () {
var result = [];
for (var delay = 0; delay <= MAX_DELAY; delay += granularity) {
result.push(getValue(delay));
}
return result;
})();
During the animation, fetching the value will be a simple lookup in a relatively small table:
function getValueFast(delay) {
return (delayValues[Math.round(delay * multiplier)] ||
delayValues[delayValues.length - 1])
}
JSPerf comparison between this solution and simple if statements shows they perform equally fast for searching around a middle value.
Here is the jsfiddle test page.
var getAccForDelay = (function () {
var acc = {
0.1: 1,
0.3: 2,
0.6: 4,
0.9: 8,
2.0: 16,
5.0: 32
};
return function(delay) {
var key,
bestKey = undefined,
absDiff,
absDiffMin = Number.MAX_VALUE;
for (key in acc) {
if (acc.hasOwnProperty(key)) {
absDiff = Math.abs(delay - key);
if (absDiffMin > absDiff) {
absDiffMin = absDiff;
bestKey = key;
}
}
}
return bestKey === undefined ? undefined : acc[bestKey];
};
}());
Test:
console.clear();
console.log(getAccForDelay(0));
console.log(getAccForDelay(0.33));
console.log(getAccForDelay(3.14));
console.log(getAccForDelay(123456.789));
Output:
1
2
16
32
=== UPDATE ===
The above solution doesn't utilize of the fact that acc is sorted by key. I optimized the code by replacing linear search with binary search, which is much faster on long arrays. Here is the test page.
var getAccForDelay = (function () {
var accKey = [ 0.1, 0.3, 0.6, 0.9, 2.0, 5.0 ],
accValue = [ 1, 2, 4, 8, 16, 32 ],
accLength = accKey.length;
return function(delay) {
var iLeft, iMiddle, iRight;
iLeft = 0;
if (delay <= accKey[iLeft])
return accValue[iLeft];
iRight = accLength - 1;
if (accKey[iRight] <= delay)
return accValue[iRight];
while (true) {
if (iRight - iLeft === 1)
return delay - accKey[iLeft] < accKey[iRight] - delay ? accValue[iLeft] : accValue[iRight];
iMiddle = ~~((iLeft + iRight) / 2);
if (delay < accKey[iMiddle])
iRight = iMiddle;
else if (accKey[iMiddle] < delay)
iLeft = iMiddle;
else
return accValue[iMiddle];
}
};
}());
In my humble opinion I think the best solution to this problem is to write a function which picks the best acceleration based on the time using if statements as follows:
function getAcceleration(time) {
if (time < 0.20) return 1;
if (time < 0.45) return 2;
if (time < 0.75) return 4;
if (time < 1.45) return 8;
if (time < 3.50) return 16;
return 32;
}
However this is a static solution. If that's alright with you then I recommend you use this method. On the other hand if you need a dynamic solution then use this instead:
var getAcceleration = createAccelerationMap(0.1, 0.3, 0.6, 0.9, 2.0, 5.0);
function createAccelerationMap(previous) {
var length = arguments.length, limits = [];
for (var i = 1; i < length;) {
var current = arguments[i++];
limits.push((previous + current) / 2);
previous = current;
}
return function (time) {
var length = limits.length, acceleration = 1;
for (var i = 0; i < length;) {
if (time < limits[i++]) return acceleration;
acceleration *= 2;
}
return acceleration;
};
}
Either way you may then use getAcceleration as follows:
console.log(getAcceleration(0)); // 1
console.log(getAcceleration(0.33)); // 2
console.log(getAcceleration(0.64)); // 4
console.log(getAcceleration(1.42)); // 8
console.log(getAcceleration(3.14)); // 16
console.log(getAcceleration(123456.789)); // 32
See the demo: http://jsfiddle.net/QepT7/
If the 0.1 is the number of seconds, and you want to round to 1 decimal you can do something this:
// 0.42332 * 10 = 4.2332
// Math.round( ) will be 4
// 4 / 10 = 0.4
acc[ (Math.round(this._delay * 10) / 10).toString() ]
var seconds = this._delay.toString().substring(0,2)
console.log(acc[seconds]);
This is a straight-forward approach of your problem: First I convert the float to a string, second I cut off everything after the third character.
What units are you using?
this._startTick = (new Date()).getTime();
// ms = ms
this._delay = (new Date()).getTime() - this._startTick;
// ms = ms - ms
So to get to "0.1"/etc from milliseconds I'm assuming you are doing
(Math.floor(ms / 100) / 10).toString();
Why not just keep everything in ms/100 so you can use integers?
var acc = [];
acc[ 1] = 1;
acc[ 3] = 2;
acc[ 6] = 4;
acc[ 9] = 8;
acc[20] = 16;
acc[50] = 32;
Then you can create a "nearest" lookup function like this
function find(x) {
var i = 0;
x = x | 0; // The | 0 will cause a cast to int
if (x < 0) x = 0;
if (acc[x] !== undefined) return acc[x];
if (x > acc.length) return acc[acc.length - 1];
while (++i < acc.length) {
if (acc[x - i] !== undefined) return acc[x - i];
if (acc[x + i] !== undefined) return acc[x + i];
}
}
find(this._delay / 100);
Now examples are
find(30); // 16
find(100.5); // 32
find(0); // 1

Categories