Undefined Variable thrown - javascript

This is a freecodecamp problem where the string argument should be multiplied by the num argument. I understood the other methods they provided, but I'm hung up on how this one works.
repeatStringNumTimes("abc", 3);
//should return "abcabcabc"
I am trying to figure out how the last part of this function (the else statement) inherently knows to multiply the parameters together even though there is no instruction to do so. The way I see it, all it says is: x + (x, y - 1) yet somehow it's still returning correctly.
What am I missing?
function repeatStringNumTimes(str, num) {
if(num < 0)
return "";
if(num === 1)
return str;
else
return str + repeatStringNumTimes(str, num - 1);
}

This is a form of computing called "recursion". It refers to functions that can refer to themselves, thus restarting their cycles until a certain condition is met. In this case, the function is recursively calling itself num times, which in this case yields a simple repetition of its commands.

Related

Quiz, is their answer wrong?

I had this question in a test.
What is the output of the following incorrect javascript code and what is the error?
num=0;
if (num > 10);
{
num = num + 10;
}
alert(num);
The possible answers:
a) Output 10. There should not be a semicolon(;) at the end of the if statement if(num > 10)
b) Output 0
There should not be quotes around the num in the alert statement alert("num");
c) Output 10. There should not be a semicolon(;) at the end of the if statement if (num > 10)
d) Does not execute at all. There is an error with the calculation num = num + 10;. num == num + 10;
My answer is:
As is it would not execute, but if we removed the semicolon after if statement, and added var it would. The output would be zero.
This is because num is not greater than 10, therefore the if statement doesn't do anything. num still = 0.
There should be no semicolon after the IF statement. var should be used in front of the num variable.
Their answer was a).the output would be 10, and there should be no semicolon after if statement.
The statement doesn't work, but if we tidy it up the answer would still never be 10.
Is the question a poorly written question? Are they wrong, or am I wrong?
A semicolon after an if condition is not a syntax error, unfortunately - it just means that the result of the if condition is not used, because no statements run if it's true.
The { immediately following it is valid syntax, despite being disconnected from the if - it's a bare block. Bare blocks are valid too, but pretty weird - they mostly just create a new scope that const and let variables declared inside do not leak out of.
num=0;
if (num > 10);
{
num = num + 10;
}
alert(num);
See how "Run code snippet" results in 10 popping up.
The quiz is correct.
Since there's a semicolon after the if statement, it essentially has no body and therefore nothing to run if it's true. You can think of it as ending at the semicolon.
Block statements (statements inside of brackets, {}) are valid in Javascript and, in this case, would just run like normal code. So the num = num + 10 runs. Since the if statement above ended at the semicolon, this code runs regardless of the result of the if statement. Think of it as having nothing to do with the if statement.
So the result is 10. And yes, you likely want to remove the semicolon after the if statement to get the desired result.
You can test it out if you want:
num=0;
if (num > 10);
{
num = num + 10;
}
alert(num);
Since there is a semicolon after the if statement, the if statement is ignored.
The statements inside the block will be executed so the below code executes :
num = num+10
And you get 10 as your answer.

Unable to understand this recursion code [duplicate]

I was reading Eloquent JavaScript and I came across this example for the puzzle:
Consider this puzzle: By starting from
the number 1 and repeatedly either
adding 5 or multiplying by 3, an
infinite amount of new numbers can be
produced. How would you write a
function that, given a number, tries
to find a sequence of additions and
multiplications that produce that
number?
Here's the code for the solution:
function findSequence(goal) {
function find(start, history) {
if (start == goal)
return history;
else if (start > goal)
return null;
else
return find(start + 5, "(" + history + " + 5)") ||
find(start * 3, "(" + history + " * 3)");
}
return find(1, "1");
}
print(findSequence(24));
Could someone clear up how dod find get executed if it didn't have a value for the arguments start and goal? Also how did the recursion happen?
But find didn't get executed without a value for start and goal. It was first executed with the value 1 for start, and the only value for goal was 24.
Perhaps you're confused about the order of operations. There we see the declaration of a function, findSequence. During the declaration, no code is executed. The findSequence function only gets executed later, on the last line, where the result of executing the function gets printed out.
Within the declaration of findSequence, there's a declaration of another function, find. Once again, it doesn't get executed until later. The findSequence function has just one executable line of code, the one that calls find(1, "1"). Execution of that one line triggers the execution of find some number of times, recursively. The find function makes reference to goal; when the Javascript interpreter executes the code, goal always refers to the parameter of findSequence, and since in this example findSequence is only called once, goal always has the same value, 24.
You should be able to see where the recursion happened. If start was equal to goal, then the function stops; it returns the history of how it arrived at that number. If start is greater than goal, then it returns null, indicating that that path was not a path to the target number. If start is still less than goal, then the function tries calling itself with its start value plus 5. If that returns a non-null value, then that's what gets returned. Otherwise, it tries multiplying by 3 and returning that history value instead.
Note that although this code can return many numbers, it cannot return all numbers. If the goal is 2, for example, findSequence will return null because there is no way to start at 1 and get to 2 by adding 5 or multiplying by 3.
When find is called inside of findSequence, it has access to the goal variable that is set in findSequence's definition. A simple example of this is:
function outerFunction() {
var a = 2;
function innerFunction() {
alert(a);
}
innerFunction();
}
outerFunction();
The start variable is defined when it does:
return find(1, "1");
Effectively having an initial start variable of 1, goal variable of 24, and a history of "1" on the first pass.
EDIT: Per Rob's comment, closures aren't actually what's causing this here, as find() is not being executed outside of findSequence(), scoping is causing goal to be found.
If I'm understanding your question correctly: The final line of code is calling findSequence(), with a goal of 24. In findSequence() there's a function called find(), which is defined and then called in the return statement for findSequence, with start equaling 1, and history equaling 1.

Javascript Recursive function and || [duplicate]

I was reading Eloquent JavaScript and I came across this example for the puzzle:
Consider this puzzle: By starting from
the number 1 and repeatedly either
adding 5 or multiplying by 3, an
infinite amount of new numbers can be
produced. How would you write a
function that, given a number, tries
to find a sequence of additions and
multiplications that produce that
number?
Here's the code for the solution:
function findSequence(goal) {
function find(start, history) {
if (start == goal)
return history;
else if (start > goal)
return null;
else
return find(start + 5, "(" + history + " + 5)") ||
find(start * 3, "(" + history + " * 3)");
}
return find(1, "1");
}
print(findSequence(24));
Could someone clear up how dod find get executed if it didn't have a value for the arguments start and goal? Also how did the recursion happen?
But find didn't get executed without a value for start and goal. It was first executed with the value 1 for start, and the only value for goal was 24.
Perhaps you're confused about the order of operations. There we see the declaration of a function, findSequence. During the declaration, no code is executed. The findSequence function only gets executed later, on the last line, where the result of executing the function gets printed out.
Within the declaration of findSequence, there's a declaration of another function, find. Once again, it doesn't get executed until later. The findSequence function has just one executable line of code, the one that calls find(1, "1"). Execution of that one line triggers the execution of find some number of times, recursively. The find function makes reference to goal; when the Javascript interpreter executes the code, goal always refers to the parameter of findSequence, and since in this example findSequence is only called once, goal always has the same value, 24.
You should be able to see where the recursion happened. If start was equal to goal, then the function stops; it returns the history of how it arrived at that number. If start is greater than goal, then it returns null, indicating that that path was not a path to the target number. If start is still less than goal, then the function tries calling itself with its start value plus 5. If that returns a non-null value, then that's what gets returned. Otherwise, it tries multiplying by 3 and returning that history value instead.
Note that although this code can return many numbers, it cannot return all numbers. If the goal is 2, for example, findSequence will return null because there is no way to start at 1 and get to 2 by adding 5 or multiplying by 3.
When find is called inside of findSequence, it has access to the goal variable that is set in findSequence's definition. A simple example of this is:
function outerFunction() {
var a = 2;
function innerFunction() {
alert(a);
}
innerFunction();
}
outerFunction();
The start variable is defined when it does:
return find(1, "1");
Effectively having an initial start variable of 1, goal variable of 24, and a history of "1" on the first pass.
EDIT: Per Rob's comment, closures aren't actually what's causing this here, as find() is not being executed outside of findSequence(), scoping is causing goal to be found.
If I'm understanding your question correctly: The final line of code is calling findSequence(), with a goal of 24. In findSequence() there's a function called find(), which is defined and then called in the return statement for findSequence, with start equaling 1, and history equaling 1.

JavaScript Fibonacci breakdown

I hope it is ok that I am posting this question here even though I have also posted it on other sites. If I have failed to follow proper protocols, I apologize and please let me know right away so I may remove the post and learn my lessons.
I've been a front end developer for over a year now. I went to school to learn web development, and I consider myself a somewhat capable coder when it comes to simple JavaScript stuff.
But when it comes to writing any type of Fibonacci function I cannot do it. It is as if I have a piece missing from my brain that would understand how to deal with this simple sequence of numbers.
Here is a piece of a working code that I'm pretty sure I got from a John Resig book or somewhere online:
fibonacci = (function () {
var cache = {};
return function (n) {
var cached = cache[n];
if (cached) return cached;
if (n <= 1) return n;
console.log(n);
return (cache[n] = fibonacci(n - 2) + fibonacci(n - 1));
};
}());
When I call this function with 10 as the argument, I get this sequence: 10,8,6,4,2,3,5,7,9
Here's what I understand:
fibonnaci is assigned an immediately invoked function expression (or self executing blah blah blah), to which a cache is initiated with whatever argument was passed.
If the argument was already in the cache, we just return it and live our lives in everlasting peace.
If the argument is 1 or less, that is also the end of the function, everlasting peace ensues once more.
But if neither of these conditions exist, then the function returns this statement that makes me feel as if I am just a monkey in a human suit.
What I'd like to do is generate the first 10 fibonnaci numbers in the correct sequence, because if I can do that, then I'll feel like I at least understand it.
So when the first two conditions fail, the code creates a new cache variable and sets it equal to the result of the fibonacci function with whatever argument was passed minus 2, and then it adds the result minus 1.... now for my questions
Question 1: How does the function know what fibonacci(n-2) is if fibonacci(n) has never been computed?
Question 2: Are recursive functions linear, or what order do they follow?
Question 3: If I can't understand this, do I have any hope of becoming a programmer?
Thank you for your time.
After getting past this block, I changed the function a bit to see if I could hold on to the result in a variable and output it, just to see what happens, and I got some really unexpected results.
Here's the change:
fibonacci = (function () {
var cache = {};
return function (n) {
var cached = cache[n];
if (cached) {
console.log(cached);
return cached;
}
if (n <= 1) {
console.log(n);
return n;
}
console.log(n);
var result = (cache[n] = fibonacci(n - 2) + fibonacci(n - 1));
console.log(result);
return result;
};
}());
Here's the resulting pattern:
10,8,6,4,2,0,1,1,3,1,1,2,3,5,2,3,5,8,7,5,8,13,21,9,13,21,34,55
Any help with why this happens?
Well, let's start with what you understand (or say you understand):
fibonnaci is assigned an immediately invoked function expression (or self executing blah blah blah), to which a cache is initiated with whatever argument was passed.
Not quite: fibonnaci is assigned the return value of an IIFE. There's a difference. Inside the IIFE, we se a return function(n) statement. The IIFE is, as it's name suggests, invoked immediatly. the function is created, executed and, once returned, is not being referenced (explicitly) anywhere. The function is returned, is assigned to the variable fibonacci.
This IIFE does create an object literal, called cache. This object resides in the scope of the IIFE, but because of JS's scope scanning(this answer links to others... all of them together explain how JS resolves names to their values), this object is still accessible to the returned function, now assigned to fibonaci.
If the argument was already in the cache, we just return it and live our lives in everlasting peace. If the argument is 1 or less, that is also the end of the function, everlasting peace ensues once more. But [...]
Well, now cache is not created over and over again on each function call (the IIFE is only called once, and that's where cache is created). If the returned function (fibonnaci) changes it, that change to the object will persist in memory. Closure vars, for that is what cache is can be used to hold state between function calls. All the other things you say (n <= 1) is standard recursive function stuff... it's the condition that prevents infinite recursion.
But if neither of these conditions exist, then the function returns this statement that makes me feel as if I am just a monkey in a human suit.
Well, this is actually the fun part. This is where the actual magic happens.
As I've explained, fibonnaci does not reference the IIFE, but rather, it references teh returned function:
function(n)
{
var cached = cache[n];
if (cached)
{
return cached;
}
if (n <= 1)
{
return n;
}
return (cache[n] = (fibonacci(n-2) + fibonnaci(n-1)));
}
This means, that every occurance of fibonacci can be replaced with the function body. When calling fibonnaci(10), the last (return) statement should be read as:
return (cahce[n] = fibonacci(8) + fibonnaci(9));
Now, as yousee, fibonacci(8) and fibonnaci(9) are called, in the return value. These expression can be written in full, too:
return (cache[10] = (fibonnaci(6) + fibonacci(7)) + (fibonacci(7) + fibonacci(8)));
//which is, actually:
return (cache[10 = ( retrun (cache[6] = fibonacci(4) + fibonacci(5))
//since fibonacci(6) cached both fibonacci(5) & fibonacci(6)
+ return (cache[7] = cache[5] + cache[6])
+ return cache[7] + return (cache[8] = cache[6] + cache[7]
That's how this cache function actually ties in...
We can repeat this until we call fibonnacci(1) or fibonacci(0), because in that case n<=1, and will be returned without any more recursive calls.
Also note that, in writing fibonnaci(9) in full, this actually breaks down into fibonacci(7) + fibonacci(8), both these calls have been made before, and that's why there results were cached. If you don't cache the results of each call, you'll waste time calculating the same thing twice...
BTW: this code is very much "condesed", and works because the specs say that an assignment expression (cache[n] = ...) evaluates to the assigned value, you're returning cache[n], essentially.
Great questions. Thinking in recursive terms is tricky. If you try to grasp all the process you probably will fail miserably. I remembered to be frustrated as you are for not understanding the recursive solution to the Hanoi towers problem. I tried to trace on paper the sequence of steps but it was not of any help to understand the magic of what was going on.
What it worked for me was to think that the recursive function is a kind of "oracle" that knows the return value of the function fib(i) for any value of i < n. If the oracle knows fib(n-1) and fib(n-2), then it just has to give the instructions to calculate fib(n) from these known values. As a consequence we can say that the oracle, this function, also knows the value of fib(n).
A warning: there is a tricky part in all recursive functions, we need at least one not recursive value known at start the process, otherwise we will have an infinite recursion. In fibonacci example, these values are: fib(0) = 0 and fib(1) = 1
Your example is a bit more complex than that, as is using memoization, a technique to store the values of fib(n) in a cache to avoid recalculating them. In this case, this cache is an sparse array (array with "holes") that stores in its position i the value of fib(i) the first time it is calculated. This is a way to avoid repeating a costly computation the next time the same value of fib(i) is requested.
Aswering your questions:
fib(n-2) doesn't need to know the value of fib(n) to be calculated, what it needs are the values of fib(n-3) and fib(n-4). The only thing to do is to invoke them in ordert to ask the "oracle" their values.
It depends, there are linear recursive functions and tree shaped recursive functions, depending of how many other values they use. In this case you have a tree shaped invocation order. (Actually memoization makes it more complex and I would represent it as as a directed acyclical graph instead of a tree, but it is not relevant for the discussion).
Keep thinking on it, one day you will have an "aha" moment and then recursive functions will become evident to you.
If you still want to trace the execution of this function maybe it would help to refactor your calculation to an equivalent way as it makes more evident the order of execution:
// var result = (cache[n] = fibonacci(n - 2) + fibonacci(n - 1));
var fib2 = fibonacci(n - 2);
var fib1 = fibonacci(n - 1);
var result = fib2 + fib1;
cache[n] = result;
I know the question is a bit old, and the answers are helpful. I was doing this exercise in GoLang, and thought how I would write in Javascript, and use this answer to refresh my mind as well. I see your code has a cache variable to store the value of the fib(n-2) + fib(n-1) iteration. If you're doing recursive, you don't need a variable to store the result, because each time the function is called it returns a number, and these numbers are added up to the first function call.
function fib(n) {
if (n<=1) return n;
return fib(n - 1) + fib(n - 2);
}
To see why you don't need the cache variable is go through each function call, and start calculate the values once n equal 1 or 0.
for example:
iteration 1)
fib(3) {
return fib(3-1) + f(3-2)
}
---------------------------
iteration 2)
fib(3-1) {
return fib(2 - 1) + fib(2-2)
}
iteration 3)
fib(3-2) {
return 1
}
---------------------------
iteration 4)
fib(2-1) {
return 1
}
iteration 5)
fib(2-2) {
return 0
}
----------------------
if you calculate it the return value backward from iteration 5)
5) 0
4) 1
3) 1
2) 1 <== 4) + 5) = 1 + 0
1) 2 <== 2) + 3) = 1 + 1
so fib(3) is 2

Are using Parameters necessary?

For example:
function test(x) {
alert("This is a " + x);
}
test("test");
I honestly do not see the point in it (it's probably because I don't have much knowledge on this subject), but if you could explain a bit, that would be magnificent!
There are four patterns of invocation in JavaScript: the method
invocation pattern, the function invocation pattern, the constructor invocation pattern, and the apply
invocation pattern. The patterns differ in how the bonus parameter this is initialized.
The invocation operator is a pair of parentheses that follow any expression that produces a function value. The
parentheses can contain zero or more expressions, separated by commas. Each expression produces one
argument value. Each of the argument values will be assigned to the function's parameter names. There is no
runtime error when the number of arguments and the number of parameters do not match. If there are too
many argument values, the extra argument values will be ignored. If there are too few argument values, the
undefined value will be substituted for the missing values. There is no type checking on the argument
values: any type of value can be passed to any parameter.
"JavaScript: The Good Parts by Douglas Crockford. Copyright 2008 Yahoo! Inc.,
978-0-596-51774-8."
Javascript doesn't support function overloading, but everytime a function is called the arguments variable is set with an array of all the parameters that are passed, even if they're not named in the function declaration. For example:
function prod() {
var res = 1;
for (var i = 0; i < arguments.length; i++)
res *= arguments[i];
return res;
}
var p = prod(5, 3, 7); // => 105
Note: arguments actually isn't an Array object, i.e. it doesn't have the same prototype. But it can easily converted to an array:
var args = Array.prototype.slice.call(arguments, 0);
Parameters allow substition: instead of writing the same code over and over, we re-use it, with our own values. In your example, the method doesn't do much, so there's little advantage.
But with only a minor tweak, it might make more sense:
function test(x) {
var y = x * 2
if (y === NaN) {
alert("That was no number!");
} else {
alert("Multiplied by 2, " + x + " is " + y);
}
}
We wouldn't want to write that every time we wanted to run that code, substituting our values:
var y = "test" * 2
if (y === NaN) {
alert("That was no number!");
} else {
alert("Multiplied by 2, test is " + y);
}
var y = 5 * 2
if (y === NaN) {
alert("That was no number!");
} else {
alert("Multiplied by 5, test is " + y);
}
Note: The value might come from a form, a database, a web service, etc.
In our example it's hardcoded, but in real life, this is less likely.
Instead we create the test method, generic code that handles the cases we care about.
Then we can write:
test("test");
test(5);
If what we needed to do changes, we change a single test method, rather than finding all the places in the code we used the same logic. This makes program maintenance and testing easier.
This will work without prameter check over here
Demo
Note : if you are using that parameter in your function then it's better to pass it in the function call otherwise it remains "undefined"...
Final conculsion
function test(a)
{
alert(a);
}
test(1); // outputs 1
test(); // outputs undefined
when you dont pass the value for argument thatn it Set to undefined. You don't get an exception. It can be a convenient method to make your function more versatile in certain situations. Undefined evaluates to false, so you can check whether or not a value was passed in

Categories

Resources