The_Exile

The_Exile

Need A Lot of Assistance From An Actual js Dev

I am new to programming.

I started reading Eloquent Javascript 3rd Edition, as the book comes highly recommended as a good place for beginners to start. Like every book that makes this claim, it seems to not be the case.

I already ran into problems in Chapter 2.

This is the same problem I run into in every language I’ve tried to use in my attempt to learn how to program.

I never quite understand how to properly construct loops. And it seems every dev making a book to help “beginners” always leaves out important details and assumes that the beginner isn’t a beginner, which is understandable, they are developers not teachers and Pedagogy is it’s own field, still, because of the lack of understanding I am stuck.

They explain the concept of a loop just fine, what it does, and why I’d use one but, they always fail to properly explain how to properly create one and the pieces it uses to do what it does, and how those pieces work with whatever interpreter, etc.

Moving on to where I am stuck…

Chapter 2 - Exercise 2 - FizzBuzz
Write a program that uses console.log to print all the numbers from 1 to 100,
with two exceptions. For numbers divisible by 3, print “Fizz” instead of the
number, and for numbers divisible by 5 (and not 3), print “Buzz” instead.
When you have that working, modify your program to print “FizzBuzz”
for numbers that are divisible by both 3 and 5 (and still print “Fizz” or
“Buzz” for numbers divisible by only one of those).

This was my solution for the Chapter 2 - Exercise 2 problem…


/*
for ( let indexCounter = 1; indexCounter <=100; indexCounter++){
  if ( indexCounter % 3 == 0)
    console.log("Fizz");
  else if ( indexCounter % 5 == 0)
    console.log("Buzz");
  else if ( indexCounter % 3 == 0 && indexCounter % 5 == 0)
    console.log("FizzBuzz");
    else ( indexCounter == Number )
  console.log(indexCounter);
}
*/

It works… Kind of… It generates output but, it’s not the correct output after I compared my solution to the author’s. There is a semantic error and I can’t understand why. I am bashing my head against the wall feeling like a total failure in life, and I am, wanting to jump off my roof, and end my existence for being such a failure. For those who might be concerned with my statement, don’t worry, I won’t but, I feel like it.

The author’s solution is here…

/*
for (let n = 1; n <= 100; n++) {
  let output = "";
  if (n % 3 == 0) output += "Fizz";
  if (n % 5 == 0) output += "Buzz";
  console.log(output || n);
}
*/

When I look at the author’s solution… I just can’t understand what it’s doing or even how it’s doing it. I’ve re-read the chapter 3 times now and it’s just not clicking. The way the author explains it does not stick or make sense to me. I am extremely bad with memorization and it seems the author wants me to memorize a ton of stuff.

I understand the for loop and understand that for loops are great for iteration on a set of values and that if I run into a scenario like this I should use a for loop rather than a while loop. In this case the range of 1-100 are the numbers I am iterating over.

for (let n = 1; n <= 100; n++)

One other thing that throws me off is…
Why define the variable inside the for loop? Why not before?
Is this done because of scope? Aka Local variable being safer than a global? Am I even understanding that?
The author uses “let n = 1” which I am assuming acts as an index counter but, I am not sure.
Another thing is how does the JavaScript know that the variable I set, in this case I used indexCounter, that it’s referring to a range if I never defined a range?

I am assuming n++ is just short hand for n = n + 1. Am I correct?

I am so lost, the author creates a variable called output.
Why? Why is the variable empty? How does an empty string and a number generate any sort of output?

Then he does…

if (n % 3 == 0) output += "Fizz";
if (n % 5 == 0) output += "Buzz";

The way I read that is…

If (expression result) * output += “Fizz”?

What is “+=” ?

I have no idea how that works. Output is null/nill, it’s just an empty string.
How does the result of the previous expression and the variable output even do anything with each other as they are two totally different value types? Better yet, how are they even interacting at all?

Then the author uses this line… console.log(output || n);

Console.log( output or n ) is how I read that. I don’t even know if that’s right or even why he did that. Lol. ( Bashes head into desk )

This is all extremely confusing and JavaScript is making me want to claw my eyes out. The syntax of the language is overly complex compared to others I’ve tried in the past and it’s seemingly for no reason. Yet the world at large has decided to make it the face of the web, which is making me question my faith in humanity. What sadistic group of people thought making JavaScript this integral part of the world wide web? I curse them, I curse them all. Lol.

/js

Marked As Solved

mindriot

mindriot

Looking at your answer, the loop structure itself is pretty good and indexCounter will count from 1 to 100 running the block (between { and } symbols) for each value of indexCounter.

This isn’t a great place to be, when you get stuck like this you do really need to walk away for a bit, take a break and try come back with a fresh mind. Sometimes you will see the answer, other times you might need to ask for help, but continuing on when you feel like this is only going to make it worse. In terms of the actual problem, it is to do with your if/else. A couple of important things about if/else:

  • Only one part (branch) will be evaluated when its matching condition is true. It could be the if, it could be the else or it could be an else if.
  • Each of the possible conditions will be checked from top to bottom to determine which branch to run. Combined with the previous point, this means when multiple conditions are true then only the first branch with a condition which is true is run.
  • Else does not have a condition, it runs in the case that all previous conditions have evaluated to false.

The problem with your version is the sequence of conditions that are checked means the FizzBuzz case can never happen. I’ll leave it as an exercise to work out how to fix this based on the points above, if you are still struggling I can help further.

I haven’t read the book so it is hard to comment much on the way the content is provided. It does feel like there are a couple of things in this solution that for a beginner in chapter 3 are adding some noise / confusion, regardless lets walk through the basic elements of what is going on here and address your questions.

So basically the for loop is a short hand for a common pattern and has become the idiomatic way to express that pattern. You are correct that the author is using n as the index counter, sometimes people frequently use “I” as a short name as well, you are also correct that n++ is a shorthand for n = n + 1. With those things in mind here is a while loop that has exactly the same semantic structure as your for loop here.

let n = 1; // initialise the start of the range before the loop
while (n <= 100) { // check the current value of n before entering the loop body if it is within 1-100
    /// do the stuff
    n++; // increment the counter at the end of the loop body to move to the next number in the range
}

What is happening in the for loop version is the 3 elements used to manage working through the range (the start, the check and the increment) are brought together in the for loop version. This makes the for loop version much easier to see that it is working over a range and what that range is.

The += is another one of those short hands similar to ++. It combines the plus and the assignment together so output = output + "Fizz" and output += "Fizz" are the same. Also + when used on numbers does addition, but when used on strings (like here) joins them together (concatenates).

You seem to roughly understand this correctly. It is really common to see in javascript but is not something I’d personally throw at a beginner. To go a little bit deeper into this, many things in javascript are not true/false but are often “truthy”. If you do a comparison with === or !== then it is strictly comparing true/false values but in most other cases if it has a value then it is interpreted as true and if it does not then it is interpreted as false. In particular, empty strings are considered false, 0 is also considered false, while a string with some letters in it "hello" is considered true and a number other than 0 is also considered true. In addition to this fuzzy version of true and false, javascript also doesn’t care much about types of values and will in many cases try to force the type of a value into one that works. So this output || n thing evaluates to the value of output if the value of output is truthy or the value of n if the value of n is truthy and the value of output is not, otherwise it evaluates to false. The result of evaluating output || n is used as the input to the console log. A clearer way of writing this particular example would be something like:

if (output) {
    console.log(output);
} else {
    console.log(n);
}

Lets go through this authors loop with some comments…

for (let n = 1; n <= 100; n++) // starting at 1, run the block (from { to } ) for each number n up to and including 100
{ 
  // for this particular n
  let output = ""; //  start with an empty output string
  if (n % 3 == 0) output += "Fizz"; // if this n is divisible by 3, join "Fizz" to the output string
  if (n % 5 == 0) output += "Buzz"; // if this n is divisible by 5, join "Buzz" to the output string
  console.log(output || n); // log the output if it isn't empty, log n if the output is empty
}  // move on to the next n

One thing of note beyond your questions here, unlike your version this author is using 2 independent ifs. Your version uses if with else if meaning only the if or else if will be run, but these two ifs will both be checked every time because they do not have else linking them together so they can both run if their conditions both evaluate to true. This means that when n is 15 for example, it can join both Fizz and Buzz to the output string.

You aren’t the only one that feels that way. What is worse is many of the things that create confusion or end up biting you pretty hard were actually intended to make it easier for people to get started with :man_facepalming: It is also worth remembering that it was intended to be easy to add fairly trivial little snippets to web pages and is now being used to build desktop class applications with many millions of lines of code. Along the way some things have improved, but the old things are still there and improvements have to work with them, so even though much of the evolution looks like improvements there is all kinds of hidden spicy bits in there.

Also Liked

Hallski

Hallski

Hi and welcome to the art of programming!

I started writing a longer answer but saw that @mindriot already answered. Like @mindriot I also think you got the looping right but were confused by the decision logic inside of it.

Programming can be quite abstract and it can sometimes help to try to reframe the problem into something more tangible. Maybe this helps or gives inspiration to future problems:

Say that you have a group of people in a large room and you want to give them each a clothing item depending on their color preferences. A red t-shirt with the logo Fizz if they like red, a blue hat with the logo Buzz if they like blue and both the t-shirt and the hat if they like both colors.

You put them in a line (the for loop) and start with the first person who happens to only like red. When asked “Do you like red?” and answer “Yes!”, the person is given a red t-shirt.

You then move to the next person and ask the same question:

“Do you like red?”
“No, I really don’t”
“Do you like blue?”
“I do!”

At this point a blue hat is given out and you move on to the next person again. The third person in line happens to like both red and blue and is looking forward to be given both a t-shirt and a hat. But when asked:

“Do you like red?”
“I do…”

Imagine the dissapointment when you hand out a red t-shirt and move on.

“If only they had asked the questions in a different order”, the third person mutters and reluctantly puts on the t-shirt.

Similarly, to apply the same metafor to the authors implementation. In this scenario instead of handing over the merchandise directly upon an affirmative response, the item is put in a bag (output) where multiple items can be put before handing it over.

Ie. something along the lines of:

  1. The questioner prepares an empty bag (let output = "").
  2. “Do you like red?”, “Yes!”. A red t-shirt is put in the bag. (output += "Fizz")
  3. “Do you like blue?”, “Yes!”. A blue hat is put in the bag. (output += "Buzz")
  4. The bag is handed over containing a red t-shirt and a blue hat.
    (console.log(output)).
The_Exile

The_Exile

(BASHES HEAD AGAINST DESK.)

I know this… Why didn’t I notice… UGH. I guess I should have just stepped away and came back to it. Ugh… Now I feel REALLY dumb. The author doesn’t mention it in his book but, I remember it from other books I’ve read.

What if I need to increment more than 1 at a time? Do I just add more + symbols? Or I just need to do the long form like n = n + 2?

I know about the arithmetic use and the concatenation use. But… The others…

output = output + “Fizz” to me makes perfect sense…

output += “Fizz”… That makes sense now that you’ve explained it. Wish the author explained it before using it. Lol.

What? You lost me.

I think I remember him mentioning this in the chapter I read.

The example I think he gave was something like this…

“dog” === “cat”
and it evaluates to false since the strings aren’t identical and it’s looking for an exact match.

“dog” !== “cat”
and it evaluates to true since they are the inverse of the previous example.

Did I remember that correctly?

0 is true and false? You lost me again.

The author mentioned this in the first chapter. So far it seems the info in the book is great it’s just the author’s examples that are causing confusion.

Yes! ok! That is much easier to understand and read. Kinda wish the author gave me that instead Lol.

Omg yes. COMMENTS! Why the author didn’t provide his example like that is beyond me.

Ok so anytime I am going to invoke a for loop I need to follow the following syntax…

for ( declare variable and assign a value ; ( Don’t really know what you would call this part ); Index Counter Increment. )

In the author’s example there are no if’s, did he use some sort of shorthand method or something?

Good to know I am not the only one. Lol. After I typed up my question I went to the ECMA’s website and downloaded the latest ECMAScript Language Specification and started reading the section on for loops. Lol.

Unfortunately, it seems they also have an issue with describing things in such a way that a non-engineer can actually understand what was written. Lol. I tried to read the syntax it provided but, it wasn’t very clear and they do not provide any examples so it’s difficult to understand what they are trying to say. I am sure if I read the spec from start to finish it would make sense but, right now, I just don’t have the time for that.

mindriot

mindriot

You shouldn’t beat yourself up about it, it is very easy to overly focus on one part and completely miss what is really happening. Taking a break to clear your head is usually really helpful in this case. All of us have spent many hours b like this in the past, personally probably amounts to hundreds of hours.

You can use the arithmetic use of += for this, n += 2 or you can write the longer form if you prefer.

I probably shouldn’t have attempted to dive into this and try explain how it works… since we are in that hole now, I’ll give it another shot, if it still doesn’t make sense then don’t worry about it too much for now.

So what I’m talking about here is that there are true and false values which are explicitly true and explicitly false. There are also other values like 1 and "hello" which are neither true or false but can be treated as if they are in some cases, this is often known as “truthyness”. Looking at the slightly clearer if based version of printing the output or n, the use of output as a condition of the if here is depending on the fact that an empty string will be treated as false and conversely a non-empty string will be treated as if it is true.

 if (output) { // <-- when the output here is empty then it behaves as if output is false, if it is not empty it behaves as though it is true
    console.log(output);
} else {
    console.log(n);
}

You can even see this in a simple comparison, "" == false will evaluate to true, "hello" == true will also evaluate to true. The === and !=== versions I mentioned before don’t do this, "hello" === true is false. The version the original author had with output || n is depending in the same way on this implicit way that some values will treated as if they are true and others will treated as if they are false.

You did remember it correctly. These comparisons have 2 versions, these (which have 3 symbols) do a strict comparison that avoids mangling the types of the values and don’t let values pretend to be true/false. They have (generally best avoided) versions with 2 symbols, == and != which are less strict and do mangle types of values.

Sorry for adding to the confusion here. So in this situation that we are discussing where there is a number that is being used in place where a boolean value is expected and it is not a strict comparison (using === / !==) then 0 will be treated as false, other numbers will be treated as true. Here are a couple of examples:

let n = 5;
if (n) {
    console.log("n is not zero");
} else {
    console.log("n is zero");
}

prints “n is not zero”

where as

let n = 0;
if (n) {
    console.log("n is not zero");
} else {
    console.log("n is zero");
}

prints “n is zero”.

The middle part is the stop condition. It should answer the question “should this loop run for the current value of the index counting variable?” with a true or false answer.

We might not be talking about the same code or it might be the way it is formatted. In that part I was meaning about the way the if constructs are used in this code at the start of the commented lines.

for (let n = 1; n <= 100; n++) { 
  let output = "";
  if (n % 3 == 0) output += "Fizz"; // if is at the start of this line
  if (n % 5 == 0) output += "Buzz"; // if is at the start of this line
  console.log(output || n); 
}  

Here is the same code formatted slightly differently that might make the if construct more obvious.

for (let n = 1; n <= 100; n++) { 
    let output = "";
    
    if (n % 3 == 0)
        output += "Fizz";

    if (n % 5 == 0)
        output += "Buzz";
    
    console.log(output || n); 
}  

The main point was that early in the reply I made some comments about how if, else and else if behave in relation to what was going wrong with your solution. I wanted to clarify that those points were not applicable to the authors solution because these are two completely separate if constructs not linked with else or else if. Does that make more sense?

Language specs generally aren’t aimed at beginners, they are mainly a technical reference for people who already have a pretty good grasp on programming and usually are needing to double check a fine detail or are trying to implement a compiler/interpreter for the language.

Popular Frontend topics Top

PragmaticBookshelf
Database-driven sites bring complexity you might not need, but building a site by hand is too much work. Hugo is a static site generator ...
New
malloryerik
Any thoughts on Svelte? Svelte is a radical new approach to building user interfaces. Whereas traditional frameworks like React and Vue...
New
michael
So I have a table of MediaItems and when that list changes, say new entries, I’d like LiveView to know about that so that the Timeline up...
New
First poster: bot
A new Svelte blog post/announcement has been posted! Get the full details here: What's the deal with SvelteKit?
New
AstonJ
Just discovered AssemblyScript (our portal is here). It…“aims to make it easy to compile to WebAssembly using TypeScript, no strings att...
New
First poster: bot
Fable 3.0.2 has been released. Link: Release 3.0.2 · fable-compiler/Fable · GitHub
New
First poster: bot
Hotwire is an alternative approach to building modern web applications without using much JavaScript by sending HTML instead of JSON over...
New
mafinar
I am looking forward to the talks and the new release, I’ve had Alpine on my radar for awhile now, I will probably slowly introduce it in...
New
Ayushk
Hello, This is pretty basic. I was trying to explore the front-end development as I was not from a tech background. But, very much inter...
New
New

Other popular topics Top

axelson
I’ve been really enjoying obsidian.md: It is very snappy (even though it is based on Electron). I love that it is all local by defaul...
New
AstonJ
There’s a whole world of custom keycaps out there that I didn’t know existed! Check out all of our Keycaps threads here: https://forum....
New
foxtrottwist
Here’s our thread for the Keyboardio Atreus. It is a mechanical keyboard based on and a slight update of the original Atreus (Keyboardio ...
New
PragmaticBookshelf
“Finding the Boundaries” Hero’s Journey with Noel Rappin @noelrappin Even when you’re ultimately right about what the future ho...
New
AstonJ
Continuing the discussion from Thinking about learning Crystal, let’s discuss - I was wondering which languages don’t GC - maybe we can c...
New
AstonJ
If you want a quick and easy way to block any website on your Mac using Little Snitch simply… File &gt; New Rule: And select Deny, O...
New
PragmaticBookshelf
Author Spotlight: VM Brasseur @vmbrasseur We have a treat for you today! We turn the spotlight onto Open Source as we sit down with V...
New
PragmaticBookshelf
Author Spotlight: Karl Stolley @karlstolley Logic! Rhetoric! Prag! Wow, what a combination. In this spotlight, we sit down with Karl ...
New
First poster: bot
zig/http.zig at 7cf2cbb33ef34c1d211135f56d30fe23b6cacd42 · ziglang/zig. General-purpose programming language and toolchain for maintaini...
New
CommunityNews
A Brief Review of the Minisforum V3 AMD Tablet. Update: I have created an awesome-minisforum-v3 GitHub repository to list information fo...
New