basic Javascript While loop and boolean value questions - javascript

I would ask my instructor, but whenever I do, he gives me an even more vague answer to my questions, so I'm asking yall for help. We "learned" (i.e. watched videos) about for and while loops and I get it, I feel like I do, but whenever it comes to doing the assignments given, I feel like they don't make sense. Like back in math class in high school, they'd teach you about the problems, but then when it came time to do your homework, the problems were completely different from what you just learned about. For instance, it says the basic while loop structure is:
while(condition is true) {
//do something
}
But then in this assignment, it gives me:
// Another way to write a while loop is to have a boolean variable
// where the condition goes and then test every time if you need to
// change the boolean to false.
// Below we have a variable lessThan5 and it is set to true.
// Create a loop that tests if our variable 'j' is less than 5.
// If it is less than 5 then Increment it by 1. If it is not
// less than 5 then set our lessThan5 variable to be false.
let lessThan5 = true;
let j = 0;
while(lessThan5) {
}
We didn't learn anything about using boolean values in while loops and I feel like I'm meant to infer what to do, and what structure to use and I just have no idea. Aside from the fact I feel like the instructions to many of these questions are poorly worded, which only confuses me more!
So then there's this third one:
// Example of what the number game would look like:
// Couple things to note:
// Math is a built in object in javascript.
// Math.round() will round a decimal number to a whole number.
// Math.random() returns a decimal number between 0 to 1.
// (But not including 1)
function guessNumberGame(guess) {
let guessing = true;
let number = Math.round(Math.random() * 100);
while(guessing) {
if(guess === number) {
guessing = false;
} else {
guess = Number(prompt("That number didn't work. Try again: "));
}
}
}
// Problem 3
// We will give you a number through the 'num' parameter
// Create a while loop that will loop 'num' amount of times.
// For example if num is 3 then your while loop should loop 3 times
// If num is 20 then the loop should loop 20 times.
// Increment k every loop.
let k = 0;
function keepLooping(num) {
}
If this Problem 3 is meant to be related somehow to the number game example, I can't see it. I don't even know what it is I need to be asking. Does this make any sense to anyone? And nobody else is publicly asking questions about any of this, and it's making me feel stupid and like I am the only one too dumb to get what's going on. I was doing really well and ahead of schedule with all this until this point, but just none of this is making any sense to me.

Welcome to programming, JavaScript (JS), and StackOverflow (SO)!
Let's dive into this a little deeper. First, a quick JavaScript primer: in JavaScript, everything can be classified as either an expression or a statement. At a super high and not-technical level:
expression: something that produces a value
statement: an instruction to the computer
(For a much longer explanation, see here)
Often, statements have slots that can take expressions. Loops are a great example of that.
For example, 1 + 1 is an expression, since it produces the value 2. Even more simply, 1 on its own is also an expression, since it produces the value 1. while(/*some expression here*/) is a statement that has a slot for an expression. for(s1, e2, e3) is also a statement that has slots for statements and slots.
So, the while loop acts on an expression, and will continue to loop as long as the value returned by that expression is truthy. truthy and falsey is an interesting concept in JavaScript and can be a whole essay on it's own, but the tl;dr of it is that anything that == true is truthy, and anything that == false is falsey
So for your first question, 0 < 5 == true, while 5 < 5 == false. Thus, if you make the value of j be greater than or equal to 5, the loop will break.
let lessThan5 = true;
let j = 0;
while(lessThan5) {
// For each cycle of the loop, check if `j` is less than 5
if (j < 5) {
// If `j` is less than 5, increment it
j++; // This is equivalent to saying j = j + 1, or j += 1
} else {
// If `j` is not less than 5, set `lessThan5` to `false`
// Not when the loop goes to iterate again, `false == false`, and it stops
lessThan5 = false;
}
}
I think given the above you should be able to solve the third problem. Please let us know if you have trouble with it, show us what you try, and we'll be happy to help some more :)

Let's take a deep breath and relax. I'm a very senior developer and can't tell -- from your examples -- what's going on here. Maybe that's because your instructor is terrible, maybe it's because you've missed some context in your class, and so it's omitted from the question.
I can answer the two questions you've been given. Hopefully it'll be helpful.
First:
I do not know why your materials claim that a while loop might be written this way. I've completed the assignment, but it seems very odd. But if they want you to complete it, here's a solution.
// Another way to write a while loop is to have a boolean variable
// where the condition goes and then test every time if you need to
// change the boolean to false.
// Below we have a variable lessThan5 and it is set to true.
// Create a loop that tests if our variable 'j' is less than 5.
// If it is less than 5 then Increment it by 1. If it is not
// less than 5 then set our lessThan5 variable to be false.
let lessThan5 = true;
let j = 0;
while(lessThan5) {
if (j >= 5) {
lessThan5 = false;
} else {
j++;
}
}
Moving on to the second snippet, the second snippet does not, to me, appear to be related to guessNumberGame in any way.
And the solution to "Problem 3" seems useless to me. A loop that doesn't do anything is not useful in real life.
That said, the solution to "Problem 3" is as follows:
// Problem 3
// We will give you a number through the 'num' parameter
// Create a while loop that will loop 'num' amount of times.
// For example if num is 3 then your while loop should loop 3 times
// If num is 20 then the loop should loop 20 times.
// Increment k every loop.
let k = 0;
function keepLooping(num) {
while(k < num) {
k++;
}
}

Related

What does the declared function returnMe() do in this loop?

I'm a very beginner learning Javascript, alongside other code languages, and while looking at information here and in other sites, I've pieced together a simple code loop:
function returnMe() {
for (let i = 1; i <= 10; i++) {
if (i == 10) return i;
console.log(i)
}
}
console.log(returnMe());
I understand what everything does except the function I've created. The function is to stop the loop from continuing endlessly, but I'm not sure how exactly I've enabled that, nor why it should be logged (though I figured out that both pieces must be there for it to work or else it will either not work or come back as undefined.)
I was hoping someone here could help quickly define the simple issue for me, since search engines and other sites believe I'm asking what the return function is instead (which makes sense why), and I just need to understand how that bit works.
the output of the function is
1
2
3
4
5
6
7
8
9
10
it will console log every number from 1 to 9 in the for loop and then it will return 10 which will be printed outside
The For Loop Consists Of for (let i = 1; i <= 10; i++) the parameters: Initiatlisation, Condition, Incrementation. So When You Use i<=10 you are allowing the function to run until the value is less than 10.
Going further It will console log all the numbers from 1 to 10 because of the console.log(i) afterwards. Then at i=10 it will return the value which will be then displayed by console.log(returnMe());

Beginner query: Using function parameters with a for loop, skipping the loop for some reason

I imagine this is something pretty simple but I'm stumped and think this could be a good learning moment for me.
Here's the code:
var sumAll = function(lowRange, highRange) {
var sumOf;
var i;
for (i = lowRange; i > highRange; i++) {
sumOf += i;
}
return sumOf;
}
module.exports = sumAll
I'm working my way through the odin project, currently doing TDD section. So the function skeleton and final line of code was premade. The function parameters in this case are 1, 4. Expected result of 10.
Instead my test is throwing back undefined. I checked and this changes depending on what I define it as at the top.
It is as if it's skipping the loop all together, I've no idea why this would be.
A for loop's 3 major pieces can typically be understood like this.
Initialize the variable
Continue looping for as long as the condition is true
Change the variable's value after every iteration
During step two of the list above, your code is running i > highrange. This will immediately test false and skip your loop, because i has a value of lowrange, and I assume lowrange > highrange will never be true. What you want in its place is i <= highrange, "less than or equal to."
For loops are tricky, these little mistakes will follow you even into advanced territories. :o
Your for loop never executes because you set i equal to lowRange and the execute condition is i > highRange. I assume lowRange < highRange so it terminates without entering the loop, since it will run while i is greater than highRange, but it never is.
initialize your accumulator
var sumOf = 0;
and change your loop condition
for (i = lowRange; i <= highRange; i++) {

Infinite for loops are apparently tricky.

Here I am once again. This is apparently the only way I know how to learn. What I am doing is making a for loop. Yes. Something so simple. Yet, I "have" a problem with them. More or less a problem with infinite loops. What I need to do is make a loop that counts down from 10...0. It seems easy for some of you. Yes I am very aware. I am nothing more than a student learning.
This is the code that I have:
for (var i = 11; i >= 1; i++) {
console.log(i);
}
I am stuck at this point. All that it does is crash my browser every time. Help is greatly appreciated. I would like a thorough explanation of what I am doing wrong, what I should do, and why I might have made this harder than it needed to be. Thank you!
For a loop to run from 10 to 0 iterator i should be decrementing in each iteration. But you are incrementing it instead so for loop never terminates.
for (var i = 10; i>=0; i--) {
console.log(i);
}
Everyone learns differently! In this case, you're asking the code to increment (aka add) with the ++ syntax. So, if i = 1, after i++ i = 2. Similarly i-- decrements (aka subtracts) from i.
Now, the first two parts of the loop check the value of i and continue the operation. In your case, you're asking the program set i equal to 10. If i is greater than 1, add 1 to it. That's where you're getting the infinite loop because i will always be greater than 1. What you want is. for (var i = 10; i >= 0; i--) {//code here};
You could also check out while and do/while loops.
Variable i starts at 11, and is then incremented by one each loop. Since the condition is that i >= 1, it never ends. You need to change it so that i decrements by one each loop, like this:
for (var i= 11; i>=1; i--){
First you need to learn difference between increments and decrements.
increments mean to add specific value to your variable
while on other hand decrements means to reduce the value of your variable by some specific number.
Now in your case i++ means you are adding 1 to your variable i with every iteration of loop, while to end your loop you have set the condition to i>=1
this results in an infinite loop which crashes your browser, as i would never be equal to 1 or i>=1 will never be true as with each iteration the value of i increased by 1 number, so it would continue execution, until your browser crashes.
What you are looking for is:
for (var i = 10; i >= 0; i--) {
console.log(i);
}
now i will start from 10
and will gradually reduce to 0 and your loop will end.
Hope it explained.

Programming optional ignorance

In Javascript what is the best way to handle scenarios when you have a set of arrays to perform tasks on sets of data and sometimes you do not want to include all of the arrays but instead a combination.
My arrays are labeled in this small snippet L,C,H,V,B,A,S and to put things into perspective the code is around 2500 lines like this. (I have removed code notes from this post)
if(C[0].length>0){
L=L[1].concat(+(MIN.apply(this,L[0])).toFixed(7));
C=C[1].concat(C[0][0]);
H=H[1].concat(+(MAX.apply(this,H[0])).toFixed(7));
V=V[1].concat((V[0].reduce(function(a,b){return a+b}))/(V[0].length));
B=B[1].concat((MAX.apply(this,B[0])-MIN.apply(this,B[0]))/2);
A=A[1].concat((MAX.apply(this,A[0])-MIN.apply(this,A[0]))/2);
D=D[1].concat((D[0].reduce(function(a,b){return a+b}))/(D[0].length));
S=S[1].concat((S[0].reduce(function(a,b){return a+b}))/(S[0].length));
}
It would seem counter-productive in this case to litter the code with tones of bool conditions asking on each loop or code section if an array was included in the task and even more silly to ask inside each loop iteration with say an inline condition as these would also slow down the processing and also make the code look like a maze or rabbit hole.
Is there a logical method / library to ignore instruction or skip if an option was set to false
All I have come up with so far is kind of pointless inline thing
var op=[0,1,1,0,0,0,0,0]; //options
var L=[],C=[],H=[],V=[],B=[],A=[],D=[],S=[];
op[0]&&[L[0]=1];
op[1]&&[C[0]=1,console.log('test, do more than one thing')];
op[2]&&[H[0]=1];
op[3]&&[V[0]=1];
op[4]&&[B[0]=1];
op[5]&&[A[0]=1];
op[6]&&[A[0]=1];
It works in that it sets only C[0] and H[0] to 1 as the options require, but it fails as it needs to ask seven questions per iteration of a loop as it may be done inside a loop. Rather than make seven versions of the the loop or code section, and rather than asking questions inside each loop is there another style / method?
I have also noticed that if I create an array then at some point make it equal to NaN rather than undefined or null the console does not complain
var L=[],C=[],H=[],V=[],B=[],A=[],D=[],S=[];
L=NaN;
L[0]=1;
//1
console.log(L); //NaN
L=undefined;
L[0]=1
//TypeError: Cannot set property '0' of undefined
L=null
L[0]=1
//TypeError: Cannot set property '0' of null
Am I getting warmer? I would assume that if I performed some math on L[0] when isNaN(L)===true that the math is being done but not stored so the line isn't being ignored really..
If I understand what you want I would do something like this.
var op = [...],
opchoice = {
//these can return nothing, no operation, or a new value.
'true': function(val){ /*operation do if true*/ },
'false': function(val){ /*operation do if false*/ },
//add more operations here.
//keys must be strings, or transformed into strings with operation method.
operation: function(val){
//make the boolean a string key.
return this[''+(val == 'something')](val);
}
};
var endop = [];//need this to prevent infinite recursion(loop).
var val;
while(val = op.shift()){
//a queue operation.
endop.push(opchoice.operation(val));
}
I'm sure this is not exactly what you want, but it's close to fulfilling the want of not having a ton of conditions every where.
Your other option is on every line do this.
A = isNaN(A) ? A.concat(...) : A;
Personally I prefer the other method.
It looks like you repeat many of the operations. These operations should be functions so at least you do not redefine the same function over and over again (it is also an optimization to do so).
function get_min(x)
{
return +(MIN.apply(this, a[0])).toFixed(7);
}
function get_max(x)
{
return +(MAX.apply(this, a[0])).toFixed(7);
}
function get_average(x)
{
return (x[0].reduce(function(a, b) {return a + b})) / (x[0].length);
}
function get_mean(x)
{
return (MAX.apply(this, x[0]) - MIN.apply(this, x[0])) / 2;
}
if(C[0].length > 0)
{
L = L[1].concat(get_min(L));
C = C[1].concat(C[0][0]);
H = H[1].concat(get_max(H));
V = V[1].concat(get_average(V));
B = B[1].concat(get_mean(B));
A = A[1].concat(get_mean(A);
D = D[1].concat(get_average(D));
S = S[1].concat(get_average(S));
}
You could also define an object with prototype functions, but it is not clear whether it would be useful (outside of putting those functions in a namespace).
In regard to the idea/concept of having a test, what you've found is probably the best way in JavaScript.
op[0] && S = S[1].concat(get_average(S));
And if you want to apply multiple operators when op[0] is true, use parenthesis and commas:
op[3] && (V = V[1].concat(get_average(V)),
B = B[1].concat(get_mean(B)),
A = A[1].concat(get_mean(A));
op[0] && (D = D[1].concat(get_average(D)),
S = S[1].concat(get_average(S)));
However, this is not any clearer, to a programmer, than an if() block as shown in your question. (Actually, many programmers may have to read it 2 or 3 times before getting it.)
Yet, there is another solution which is to use another function layer. In that last example, you would do something like this:
function VBA()
{
V = V[1].concat(get_average(V));
B = B[1].concat(get_mean(B));
A = A[1].concat(get_mean(A));
}
function DS()
{
D = D[1].concat(get_average(D));
S = S[1].concat(get_average(S));
}
op = [DS,null,null,VBA,null,null,...];
for(key in op)
{
// optional: if(op[key].hasOwnProperty(key)) ... -- verify that we defined that key
if(op[key])
{
op[key](); // call function
}
}
So in other words you have an array of functions and can use a for() loop to go through the various items and if defined, call the function.
All of that will very much depend on the number of combinations you have. You mentioned 2,500 lines of code, but the number of permutations may be such that writing it one way or the other will possibly not reduce the total number of lines, but it will make it easier to maintain because many lines are moved to much smaller code snippet making the overall program easier to understand.
P.S. To make it easier to read and debug later, I strongly suggest you put more spaces everywhere, as shown above. If you want to save space, use a compressor (minimizer), Google or Yahoo! both have one that do a really good job. No need to write your code pre-compressed.

Simple Confusing Loops and Variable working

In this question,I'm asking how the following snippets work, as it involves weird use of variable:
while (+(+i--)!=0)
{
i-=i++;
}
console.log(i);
Interesting problem... you've tagged it Java, JavaScript and C -- note that while these languages have the same syntax, this question involves very subtle semantics that may (I'm not sure) differ across languages.
Let's break it down:
+(+i--)
The -- postfix decrement operator is most tightly bound. So this is equivalent to +(+(i--)). That is therefore equivalent to the value of +(+i) (that is, i), but it also decrements i after taking the value. It compares the value with 0 to see if the loop should continue. Thus, while (+(+i--)!=0) is equivalent to the following:
while (i-- != 0)
Note that it also performs i-- at the end of the loop.
Inside the loop, I believe you have some undefined behaviour, at least in C, because you are referencing i on the right, and also updating i on the left -- I believe that C doesn't define which order to do that in. So your results will probably vary from compiler to compiler. Java, at least, is consistent, so I'll give the Java answer. i-=i++ is equivalent i = i - i++, which is equivalent to to reading all the values out of the expression, computing the result of the expression, applying the post-increment, and then assigning the result back. That is:
int t = i - i; // Calculate the result of the expression "i - i++"
i++; // Post-increment i
i = t; // Store the result back
Clearly, this is the same as writing i = 0. So the body of the loop sets i to 0.
Thus, the loop executes just one time, setting i to 0. Then, it decrements i one more time on the next while loop, but fails the check because i (before decrementing) == 0.
Hence, the final answer is -1, no matter what the initial value for i is.
To put this all together and write an equivalent program:
while (i-- != 0)
{
int t = i - i;
i++;
i = t;
}
console.log(i);
When I tried it in Java and JavaScript, that's what I got. For GCC (C compiler), it gives -1 only when i starts out as 0. If i starts out as anything else, it goes into an infinite loop.
That's because in GCC (not necessarily all C compilers), i-=i++ has a different meaning: it does the store back to i first, then does the post-increment. Therefore, it is equivalent to this:
int t = i - i; // Calculate the result of the expression "i - i++"
i = t; // Store the result back
i++; // Post-increment i
That's equivalent to writing i = 1. Therefore, on the first iteration, it sets i to 1, and then on the loop, it checks whether i == 0, and it isn't, so it goes around again, always setting i to 1. This will never terminate, but for the special case where i starts out as 0; then it will always terminate the loop and decrement i (so you get -1).
Another C compiler may choose to act like Java instead. This shows that you should never write code which both assigns and postincrements the same variable: you never know what will happen!
Edit: I tried to be too clever using that for loop; that wasn't equivalent. Turned back into a while loop.
That's soooo wierd! (I love it)
first, you can forget about the +(+...) part, it's just like saying 1 + (+1) = 2.
i-- means i = i - 1. In your while condition, you test if i-- is different from 0. Note: the test is made on i != 0 and then i's value is changed. If you wanted to change its value before the test, you should have used --i instead.
As for the i -= i++, it's a very dumb way to say i = 0. You must read it from right to left: i = i + 1 and then i = i - i1 (whatever value of i you have, you'll end up with 0.
Simplier quivalent snippet:
while (i-- != 0) {
i = 0;
}
console.log(i);
1 a -= b means a = a - b.
i -= i++ would mean a similar thing to i = i-i; i++ (if you make the -= explicit).
In a similar fashion, you can pull the side effect of i-- out of the loop condition by
transforming while (foo(i--)) { ... } to while (foo(i)) { i--; ...} i--; (you need to put it both in the loop body and after the loop because, at the end, the condition will be false and the loop body will not be executed but execution continues after the while loop).
The while condition evaluation happens based on operator precedence. I have used explicit braces to help understand the evaluation:
(+(+(i--)) != 0) which is equivalent to using (i-- != 0) as the '+' are just unary operators.
The expression i -=i++; is equivalent to i = i - i++; where the LHS expression gets evaluated from left to right.
i = 4;
while (+(+i--)!=0) //here i would be decremented once to 3.
{
i-=i++; // here i = 3 - 3 = 0; even though i has been incremented by 1 its value is set to 0 with this assignment
}
This is very simple. And I think the only reason to code like this is a concept called "code obfucasion" or "code confusing". This way makes the code harder to read and debug, so that can prevent from reverse engineer your code :-)

Categories

Resources