Generator in ES6 - ecmascript-6

I have the code:
function countA() {
return 1;
}
function* sendStuff() {
let y = yield countA();
console.log("y: ", y);
yield;
}
var gen = sendStuff();
console.log(gen.next().value);
console.log(gen.next().value);
The result is:
> 1
> "y: " undefined
> undefined
Why y is undefined? as I know I should be 1 instead (get from countA result).
Please help me with it. Thank you a lot

Related

Creating an Apps Script function that takes other functions as arguments

I want to create a function in APPSCRIPT that takes as argument another APPSCRIPT function.
I tried this:
function mainFunction(spreadsheetRange, secondaryFunction) {
// values = array of values retrieved from range
for (var i = 0; i < values.length; i = i+1) {
values[i] = secondaryFunction(values[i]);
}
// update the range with the new values
}
function function1() {
//something
}
function function2() {
//something
}
and running (after importing all these functions) in a google sheet cell the following formula:
=mainFunction(validrange, function2)
But this error appears:
TypeError: fun is not a function.
The same happens with=mainFunction(validrange, function2())
How can I solve this problem?
Although I'm not sure whether I could correctly understand your goal, the following modified script is your expected result?
Modified script:
function mainFunction(spreadsheetRange, secondaryFunction) {
// values = array of values retrieved from range
for (var i = 0; i < values.length; i = i+1) {
values[i] = this[secondaryFunction](values[i]); // <--- Modified
}
// update the range with the new values
}
In this modification, for example, when you put =mainFunction(validrange, "function2") to a cell, the function function2 is used with values[i] = this[secondaryFunction](values[i]).
But when I saw your function of function2, no arguments are used. So, in this case, values[i] is not given to function2. Please be careful about this.
In this case, please use "function2" of =mainFunction(validrange, "function2") as the text value. Please be careful about this.
I see no problem to pass a function as an argument:
function main() {
function mainFunction(func, arg) {
return func(arg);
}
function function1(num) { return num * 2 }
function function2(num) { return num * 3 }
var value = mainFunction(function1, 2);
console.log(value) // output ---> 4
var value = mainFunction(function2, 2);
console.log(value) // output ---> 6
}
You can try it right here:
function mainFunction(func, arg) {
return func(arg);
}
function function1(num) { return num * 2 }
function function2(num) { return num * 3 }
var value = mainFunction(function1, 2);
console.log(value) // output 4
var value = mainFunction(function2, 2);
console.log(value) // output 6

generators in ES6: nested yields?

Can anyone explain to me how this code works? (nested yields):
function* anotherGenerator(i) {
yield i + 1;
yield i + 2;
yield i + 3;
}
function* generator(i){
yield i;
yield* anotherGenerator(i);
yield i + 10;
}
var gen = generator(10);
console.log(gen.next().value); // 10
console.log(gen.next().value); // 11
console.log(gen.next().value); // 12
console.log(gen.next().value); // 13
console.log(gen.next().value); // 20
At first console.log() we get a value of 10 ,
after that 11 ..12...13...20... how does this nested yield work?
yield* anotherGenerator(i); is basically a convenient shorthand for
for (var value of anotherGenerator(i)) {
yield value;
}

Generate Random Mathematical Functions

This is kind of a weird question, and might not be entirely appropriate for Stack Overflow, but I couldn't find anything about it online, so here it is...
Is there a way (or what is the best way) to generate random mathematical functions? By this I don't mean that I want a function that generates a random number (line an RNG), but rather I want to dynamically create some function which which maps one or more real inputs from a domain to a single output using some mutate-able rules.
For example, in the simplest case, I could just generate a function of the form f(x1,x2) -> Y by applying a random operator to x1 and x2. For example f could be:
f = x1 + x2
or f = x1 - x2
or f = x1 * x2
etc...
However, I would like to be able to include more complex formulas including trigonometry, power functions, pseudorandom constants, possibly some calculus functions, etc... Obviously, I cant just concatenate different chunks in a completely random way, since these functions always need to always have valid syntax.
This isn't for anything crypto-related so it doesnt have to be perfect, but the more entropy the better. It would also be great if there is an easy way to keep track of what operations are being preformed and mutate them.
I'm not sure if anyone has any insights on this, or if it even made sense, but thank you anyway
I would suggest that you try to generate random expression trees; pseudocode (somewhat Scala-inspired) for that might look something like this:
NVars = 2
def generateTree(level) = {
if (level > 100) { generateVarref() }
else {
val choice = randomChoice(4)
switch (choice) {
case 0 => generateVarref()
case 1 => generateConstant()
case 2 => generateUnary(level + 1)
case 3 => generateBinary(level + 1)
}
}
}
def generateVarref() = {
val c = randomChoice(NVars)
VarRef(c)
}
def generateConstant() = {
Number(randomChoice(100))
}
def generateUnary(level) = {
val c = randomChoice(6)
val subexpr = generateTree(level)
switch (c) {
case 0 => Negate(subexpr)
case 1 => Sin(subexpr)
// etc. More unary functions here
}
}
def generateBinary(level) = {
val c = randomChoice(4)
val sub1 = generateTree(level)
val sub2 = generateTree(level)
switch (c) {
case 0 => Plus(sub1, sub2)
case 1 => Minus(sub1, sub2)
case 2 => Times(sub1, sub2)
case 3 => Divide(sub1, sub2)
}
}
Where Plus, Varref, etc are constructors for an expression type that implements a method that will then allow you to evaluate the expression at given values.
Let's assume your functions have 2 variables x1 and x2 (if this assumption is too restrictive just adapt my answer to n variables x1, ..., xn.)
[Start] Generate random polynomial functions
This would entail
modeling polynomials in 2 variables (x1 and x2)
implementing the evaluation of polynomials on (any) particular values of the variables
generating random polynomial functions by taking a random degree (up to a certain max) and random coefficients (inside a given interval)
[Compose] Enable Function Composition
This would entail
implementing the composition of functions so that if, say f, g and h are functions in your model (randomly generated or not), then f(g,h) is also a function in your model.
[Enrich] Add new function families to your model
Here you have to consider (and implement) other types of functions to the one you already have (polynomial): rational, trigonometric, logarithmic, exponential, etc. For every new type, you will have to model them and also, to implement a way of generating random instances of them (much as you did for the polynomials.)
[Generate] Create random functions combining all of the above
Choose some types randomly
For every type, generate a random instance
Compose all the types into a final result.
[Iterate] Go to [Enrich] and add new types of functions
Ditto.
Thanks everyone for the help. What I ended up doing was something along the lines of a parse tree, recursively generating new nodes with 2, 1, or 0 children (for binary or unary operators or constants). You could cap depth by checking Node.getDepth(). Below is some JavaScript code showing this process. I'm not sure how useful it will be but it works pretty much how I had envisioned.
'use strict';
var print = console.log;
function randint(a, b) {
return Math.floor((Math.random() * (b + 1 - a)) + a);
}
function Node(parentNode, numberOfVars,
mode, weight, method, numberOfChildren, varIndex, value) {
this.mode = mode ? mode : randint(0, 3);
this.parent = parentNode;
this.weight = weight ? weight : 1;
if (this.mode == 0) { //constant
this.value = value ? value : 1;
} else if (this.mode == 1) { //variable
this.varIndex = varIndex ? varIndex : randint(0, numberOfVars - 1);
} else if (this.mode == 2) { //binary
this.method = method ? method : Node.binary[randint(0, Node.binary.length - 1)];
} else if (this.mode == 3) { //unary
this.method = method ? method : Node.unary[randint(0, Node.unary.length - 1)];
}
if (numberOfChildren) {
this.children = new Array(numberOfChildren);
} else {
this.children = [];
if (this.mode == 2) { //binary
this.children = [new Node(this, numberOfVars),
new Node(this, numberOfVars)
];
} else if (this.mode == 3) { //unary
this.children = [new Node(this, numberOfVars)];
}
}
//Methods
this.execute = function(top_level_variables) {
print("executing " + this.mode);
var inputs = [];
this.children.forEach(function(child, index) {
print("child index " + index);
inputs.push(child.execute(top_level_variables) * child.weight);
});
print(" inputs = " + inputs);
if (this.mode == 0) {
print(" mode == 0");
return this.constant();
}
if (this.mode == 1) {
print(" mode == 1");
return this.variable(top_level_variables);
}
if (this.mode == 2) {
print(" mode == 2");
return this.method(inputs[0], inputs[1]);
}
if (this.mode == 3) {
print(" mode == 3");
return this.method(inputs[0]);
}
};
var getIndent = function(indent) {
var str = "";
if (indent === 0)
return str;
for (var i = 0; i < indent; i++) {
str += " | ";
}
return str;
};
this.getTree = function(indent) {
if (this.mode == 0) {
print(getIndent(indent) + "(" + this.value + ")");
} else if (this.mode == 1) {
print(getIndent(indent) + "x[" + this.varIndex + "]");
} else if (this.mode == 2) {
print(getIndent(indent) + this.method.name);
this.children[0].getTree(indent + 1);
this.children[1].getTree(indent + 1);
} else if (this.mode == 3) {
print(getIndent(indent) + this.method.name);
this.children[0].getTree(indent + 1);
}
};
this.getStr = function() {
if (this.mode == 0) {
return this.value;
} else if (this.mode == 1) {
return "x[" + this.varIndex + "]";
} else if (this.mode == 2) {
return this.method.name + "( " + this.children[0].getStr() + ", " + this.children[1].getStr() + " )";
} else if (this.mode == 3) {
return this.method.name + "( " + this.children[0].getStr() + " )";
}
};
}
Node.binary = [
function add(a, b) {
return a + b
},
function multiply(a, b) {
return a * b
},
function power(a, b) {
return Math.pow(a, b)
}
];
Node.unary = [
function sin(a) {
return Math.sin(a)
}
];
Node.prototype.constant = function() {
return this.value
};
Node.prototype.variable = function(variables) {
return variables[this.varIndex]
};
//Test
var a = new Node(null, 2, 2);
a.getTree(0);
print(a.getStr())
print(a.getDepth());
var b = a.execute([1, 3]);
print(b);

number manipulation in angular

I was trying to convert some number automatically from x=1 to x=00001 so that x takes 5 spaces in total. If x=20.2, I want to format x to be 00020. How can I do that?
I am using html and angularjs. Thanks.
Is this what you want?
function convert(input)
{
var a = Math.floor(input).toString();
return ("00000").substr(0, 5 - a.length) + a;
}
Example:
console.log(convert(20.2)); // 00020
write this filter to achieve the logic
<div>{{number | decimalConvertion:5}}</div>
filter('decimalConvertion', function() {
return function(str, max){
function pad(str, max){
str = str.toString();
return str.length < max ? pad("0" + str, max) : str;
}
return pad(str,8);
};
}
for your reference jsfiddle link

Underscore with count for duplicate values in angular json array

Can anyone please tell me how to put count in duplicate values in angular JSON array:
My actual array is given below:
$scope.datas.resultsOrder =['Data1','Data2','Data3','Data3','Data4','Data4'];
in the above array Data3 and Data4 is repeating twice, so i need it to come as Data3_1, Data3_2, Data4_1, Data4_2 order within that array like as shown below:
$scope.datas.resultsOrder =['Data1','Data2','Data3_1',
'Data3_2','Data4_1','Data4_2'];
Also the values within that array are dynamic values and not static
Can anyone please tell me some solution for this?
I like UnderscoreJS for these kind of problems. In underscoreJS you can do something like this:
function uniq(array) {
var grouped = _.groupBy(array);
return _.reduce(grouped, function(result, x) {
if(x.length > 1) {
_.each(x, function(val, key) {
result.push(val + '_' + (key + 1));
});
} else {
result.push(x[0]);
}
return result;
},[]);
}
uniq(['Data1','Data2','Data3','Data3','Data4','Data4']);
// ["Data1", "Data2", "Data3_1", "Data3_2", "Data4_1", "Data4_2"]
You can do this:
function transform(arr) {
var c = {};
for (var i = 0; i < arr.length; i++) {
var ar = arr[i];
if(! (ar in c) ) {
c[ar] = 0;
}
c[ar]++;
}
var res = []
;
for(var d in c) {
if(c.hasOwnProperty(d)) {
var l = c[d]
;
if(l === 1) {
res.push(d);
continue;
}
for(var i = 0; i < l; i++) {
res.push(d + '_' + (i + 1));
}
}
}
return res;
}
$scope.datas.resultsOrder = transform(passTheArrayHere);
Note: No guarantee for order.