Creating an Arithmetic Task Runner - javascript

I have been tasked to create an Arithmetic Task Runner as part of my assignment.
Up until today I've never used NodeJS or even the terminal to execute a script.
I have been working on this for the past 5 hours and still no luck. I have avoided coming here and asking as I'd like to figure it out for myself, however, I have succumbed to desperately needing help.
This is the code I have so far:
class ArithmeticTaskRunner {
static set taskCount(counter) {
throw new('This is a readOnly accessor, the value is ${value}');
}
add(y) {
this.y = y || 0
console.log(y)
}
minus(x) {
this.x = Math.abs(this.y) * -1;
console.log(this.x);
};
multiply(z) {
this.z = z * this.x;
console.log(this.z)
}
execute(startValue) {
this.startValue = startValue + this.y
this.y = this.startValue
console.log(this.startValue)
this.startValue = this.minus
console.log(this.startValue)
this.startValue = this.multiply(this.startValue)
console.log(this.startValue)
}
}
tasks = [
function() { minus()},
function() { multiply(z)},
function() { add(x)},
function() { execute(x)}
]
This is nowhere near perfect, but it's 80%-90% near completion.
This is the task I have been given:
You should implement a class called ArithmeticTaskRunner with the following:
- An instance variable named tasks which is initialised to an empty array upon
creation.
- A method named addNegationTask which adds an anonymous function to the
tasks array. This anonymous function should take one argument, x, and return the
negation, -x.
- A method named addAdditionTask which takes a single argument y, and adds
an anonymous function to the tasks array. This anonymous function should take
one argument, x, and return the result x + y.
- A method named addMultiplicationTask which takes a single argument y,
and adds an anonymous function to the tasks array. This anonymous function
should take one argument, x, and return the result x * y.
- A read-only accessor named taskCount which returns the number of queued tasks.
- A method named execute, which takes a single argument named startValue.
If omitted, startValue defaults to zero. Starting at startValue, this method should iterate over the tasks array executing each function on the current value. It then returns the resulting number after all arithmetic operations have been executed.
I'd be grateful for any help I could get.
The issues I have are the following: The execute method (trying to make the startValue, after the addition, a negative), the multiplication method and the fact I cannot call the addition method twice without overriding the value. The examples of the program fully working have shown I should allow for a method to be called multiple times without overriding the previous value.
I know there's a rule where it's one question per issue, I concede that. But if anyone can help me out with any of the issues I will truly be grateful and I will compensate people for their efforts.
Thank you.
Edit - This is an example of both the expected inputs/outputs
> let taskRunner = new ArithmeticTaskRunner()
undefined
> taskRunner.addAdditionTask(2)
undefined
> taskRunner.addMultiplicationTask(4)
undefined
> taskRunner.addAdditionTask(10)
undefined
> taskRunner.execute(2)
26
> taskRunner.execute(-2)
10

I don't want to provide the whole answer because this is an assignment for you, but here's some code that might help you out. This starts with 5 then calls doubleIt and then calls addOne to arrive at 11.
It does this by creating an array of functions, each one performs a simple task and returns the result of its input modified in some way.
Then it creates a function called execute that uses Array.reduce to call the first function in the array with a given initial value, then repeatedly calls each function in the array on the result. Check the documentation for Array.reduce if you're confused about how it works.
doubleIt = x => x * 2;
addOne = x => x + 1;
tasks = [doubleIt, addOne];
execute = (initial) => tasks.reduce((x,fn) => fn(x), initial)
document.write(execute(5))
Hint #2
class ArithmeticTaskRunner {
constructor() {
this.tasks = [];
}
addAdditionTask(arg) {
this.tasks.push(x => x + arg);
}
addMultiplicationTask(arg) {
this.tasks.push(x => x * arg);
}
execute(startValue) {
return this.tasks.reduce((x, fn) => fn(x), startValue);
}
}
let taskRunner = new ArithmeticTaskRunner()
taskRunner.addAdditionTask(2)
taskRunner.addMultiplicationTask(4)
taskRunner.addAdditionTask(10)
document.write(taskRunner.execute(2));
document.write(', ');
document.write(taskRunner.execute(-2));

Related

Tensorflow.js Please make sure the operations that use variables are inside the function f passed to minimize()

I have started to use javascript and TensorFlow.js to work on some machine learning projects, I am working on creating a linear regression model, however, I cannot figure out what is causing this error
Can not find a connection between any variable and the result of the loss function y=f(x). Please make sure the operations that use variables are inside the function f passed to minimize()."
I have created two Tensors
globalTensorXs = tf.tensor2d(globaArrayXs); //input data
globalTensorYs = tf.tensor1d(globaArrayYs); //y output
I have created the coefficients/weights as below as an array of tf scalars.
function createWeights(_numWeights)
{
for ( var x = 0; x < _numWeights; x++)
{
globalWeightsTensorArr.push(tf.variable(tf.scalar(Math.random())));
}
}
There is A training function which I pass the x and y Tensors into, it is the call to the optimise.minimize that causes the issue. it does not detect the variable for training, which are stored in globalWeightsTensorArr
async function train(xsTensor, ysTensor, numIterations)
{
/*//////OPTIMISER.MINIMISE/////////////
Minimize takes a function that does two things:
It predicts y values for all the x values using the predict
model function.
It returns the mean squared error loss for those predictions
using the loss function. Minimize then automatically adjusts any
Variables used by thi predict/loss function in order to minimize
the return value (our loss), in this case the variables are in
"globalWeightsTensorArr" which contains the coefficient values
to be altered by the modeld during "numIterations" iterations of
SGD.
*/
for (let iter = 0; iter < numIterations; iter++)
{
optimiser.minimize(function ()
{
return loss(predict(xsTensor), ysTensor);
}, globalWeightsTensorArr);
}
}
// the predict and loss function are here...
//The following code constructs a predict function that takes inputs(X's) //and returns prediction Y: it represents our 'model'. Given an input //'xs' it will try and * predict the appropriate output 'y'.
function predict(_Xs)
{
return tf.tidy(() => {
for ( var x = 0; x < 8; x++)
globalWeightsArr[x] = globalWeightsTensorArr[x].dataSync();
const weightTensor = tf.tensor1d(globalWeightsArr);
const prediction = tf.dot(_Xs, weightTensor);
return prediction;
});
}
//The loss function takes the predictions from the predict function
//and the actual lables and adjusts the weights
//the weights are considered to be any tensor variable that impact the //function We can define a MSE loss function in TensorFlow.js as follows:
function loss(_predictedTensor, _labels)
{
const meanSquareError =_predictedTensor.sub(_labels).square().mean();
return meanSquareError ;
}
can anyone please help explain the problem?
Regards
Aideen
We resolved the issue by changing the way the weights/coefficients were created. Now minimize can detect the variables used by predict, and it adjusts them accordingly. later I will post the entire solution to codepen. still learning!
function createWeights(_numWeights) {
const randomTensor = tf.randomUniform([_numWeights, 1]);
globalWeightsTensorVar = tf.variable(randomTensor);
}
here is the predict function used b
function predictLogical(_Xs) {
return tf.dot(_Xs, globalWeightsTensorVar);
}
The issue is related to tf.variable. One needs to use tf.variable to create the weights that will be updated by the function created by optimiser.minimize().
A variable created by tf.variable is mutable contrary to tf.tensor that is immutable. As a result if one uses tf.tensor to create the weights they could not be updated during the training

Does it ever make sense to include a value in the first next call to generator iterator?

As the question states, does it ever make sense to pass a value to the first iterator.next() call or will it always be ignored? As an example:
function* foo(x) {
var y = 2 * (yield(x + 1));
var z = yield(y / 3);
return (x + y + z);
}
var it = foo(5);
// note: not sending anything into `next()` here
console.log(it.next()); // { value:6, done:false }
console.log(it.next(12)); // { value:8, done:false }
console.log(it.next(13)); // { value:42, done:true }
Notice there is not a value being passed to the first next(). However, in the article I'm trying to learn from, it goes on to say:
But if we did pass in a value to that first next(..) call, nothing bad would happen. It would just be a tossed-away value
Okay. That makes sense. But now I'm curious to know if there is a use case (or if it's even possible to utilize) where passing in a value has a benefit.
Article: https://davidwalsh.name/es6-generators
Will it always be ignored?
Yes.
Is a use case where passing in a value has a benefit?
When it simplifies the rest of your code. In your example, that could be using a loop instead of writing it out:
const it = foo(5);
for (let i=11; i<=13; i++)
console.log(it.next(i));
Now we're passing 11 into the first call to .next even if there's no use for the value anywhere.

What is being passed into this 'function(x)'?

I'm having a hard time grasping some finer details of javascript, I have this function function(x) it doesn't seem to be receiving any parameters. Maybe I'm not understanding the Math.sin part. I'm not sure. Any ideas on what is happening?
function makeDerivative( f, deltaX )
{
var deriv = function(x) // x isn't designated anywhere
{
return ( f(x + deltaX) - f(x) )/ deltaX;
}
return deriv;
}
var cos = makeDerivative( Math.sin, 0.000001);
// cos(0) ~> 1
// cos(pi/2) ~> 0
Update
I tried this instead and got NaN, then 15
function addthings(x, y)
{
var addition = function(m)
{
return( x + y + m);
}
return addition;
}
var add = addthings(5, 5);
alert(add());
alert(add(5));
To understand how that code works you have to read more about currying in functional javascript and functions closures.
The outer function returns the inner function, so everything you pass to
cos later theoretically is what you pass into the inner function. Imagine calling it like this:
console.log(makeDerivative( Math.sin, 0.000001)(0)); // 1
would output the same as if you're doing it as described
console.log(cos(0)) // 1
as cos is assigned reference to a function (the one that gets returned by makeDerivative).
The other answers touch on the issue, but I'm going to try to get to the core of it.
JavaScript variables are untyped, which means that they can dynamically change what kind of variable they are. On a simple level, this means that var a can be instantiated as an array, and then later assigned as a string on the fly.
But you can also store entire functions within those untyped variables. For example;
var test = 'hey'
console.log(test) //:: hey
test = function(input){ console.log('inner function: ' + input) }
console.log(test) //:: function(input){ console.log('inner function' + input) }
test() //:: inner function
test('with input') //:: inner function with input
Where //:: _____ represents the output to the console.
So the function you are using returns another dynamic function. You can then call that function in a normal fashion, inputting the value for x when you call it.
Well, you don't really call the function in the code you posted.
The makeDerivative gets reference to Math.sin function and inside it uses it to create reference to function which compute derivation of the passed function (see the f parameter).
In your example this reference is assigned to cos variable. If you called it with (0) argument, you would get 1 as return value and the argument (0) would be passed into that deriv function...

Trouble understanding a basic concept in Javascript Higher Order Functions

I am having a little bit of trouble understanding Higher Order Functions in javascript.
Can someone explain to me the difference of what's going on in these two situations?
Scenario 1:
// A function that takes in a number (x) and adds one to it.
function doMath(x){
return function (x){
return x + 1;
}
}
var didMath = doMath(5);
console.log(didMath()); // returns error
var didMath = doMath();
console.log(didMath(5)); // returns 6
var didMath = doMath(100);
console.log(didMath(5)); // still returns 6
Scenario 2:
function doMath2(x,callback){
return callback(x);
}
function add(x){
return x + 1;
}
console.log(doMath2(5,add)); // returns 6, works perfectly fine
I was under the impression that closures have access to parameters from their containing functions. Why is it that in Scenario 1, the "x" param in doMath is not accessible by the contained function?
what is happening here is you are never storing the value of x, you always return a new function, see this example it should work as you expect and maybe helps you to undersant
function doMath(x){
var y = x;
return function(y){
return y + 1;
}
}
In scenario 1
The first one outputs an error because the returned function expects an argument and you don't give one. If you remove the argument it works:
// A function that takes in a number (x) and adds one to it.
function doMath(x){
return function (){ // <--- here
return x + 1;
}
}
var didMath = doMath(5);
console.log(didMath());
In your two other examples you do give an argument and that is the one taken into account. Not the value that you give as parameter to doMath()

Expressing Y in term of SKI-Combinators in JavaScript

I was fiddling with combinators in JavaScript and was being proud of (hopefully) getting S to work when I stumbled upon Wikipedia saying: "The Y combinator can be expressed in the SKI-calculus as: Y = S (K (S I I)) (S (S (K S) K) (K (S I I)))", so I had to try that:
var I = function (x) {
return x;
};
var K = function (x) {
return function(){
return x;}
};
var S = function (x) {
return function (y) {
return function (z) {
return x(z)(y(z));
}
}
};
var Y = S (K(S(I)(I))) (S(S(K(S))(K)) (K(S(I)(I))));
Y; //evals to:
//function (z) {return x(z)(y(z));}
//And this (lifted from Crockford's Site):
var factorial = Y(function (fac) {
return function (n) {
return n <= 2 ? n : n * fac(n - 1);
};
}); //fails:
//RangeError: Maximum call stack size exceeded
What am I doing wrong? Am I not translating that expression correctly? Is there something wrong with how I'm going about this? Does it even make sense? Most of what's to be read about stuff like this just makes my brain want to explode, so the point of this exercise for me was mainly to see if I understood the notation (and would thus be able to translate it to JavaScript).
Oh, and, by the way: what got me reading & fiddling again was that what prototype.js implements as Prototype.K is actually the I combinator. Has anyone noticed?
The problem here is that you are using a strictly evaluated programming language. The Y-combinator, pretty much like any other fixed point combinator, will only work properly when your functions are called by need, or 'lazily evaluated'.
I know of a way to work around this (one of my professors looked into it a while ago), but it will make your code completely unreadable.
Below I've shown what's going on exactly, hoping you can see why JavaScript can't handle a straightforward implementation of SKI-calculus.
This is what Y looks like after JavaScript evaluated your SKI-expression:
var Y = function (q) {
return (function(p){return q(p(p))})(function(p){return q(p(p))});
};
Now let's see what happens if you feed it your function function (fac) { ... }. Let's call that function f:
var factorial = (function(p){return f(p(p))})(function(p){return f(p(p))});
Since the first anonymous function is applied to an argument, it will be evaluated into this:
var factorial = f(
(function(p){return f(p(p))})(function(p){return f(p(p))})
);
In a lazily evaluated language, the argument to f would now be left alone, and f itself would be evaluated. However, because JavaScript is a strictly evaluated language (or 'call-by-value'), it wants to know what argument it needs to pass to function f before actually running that function. So let's evaluate that argument, shall we?
var factorial = f(f(
(function(p){return f(p(p))})(function(p){return f(p(p))})
)
);
I guess now you're starting to see now where things go wrong, and how the Y-combinator actually works. In any case, your JavaScript machine will run out of stack space, because it's trying to build an infinite stack of calls to f.

Categories