Lab 2: Conditionals
Welcome to the second lab of Team Edge!
In this lab, we cover conditionals and how to implement control flow into our programs.
Open conditionals.js in your text editor and solve the challenges listed.
Make sure to run your code after each attempt to make sure you don't have any bugs!
Challenges :
New Skills :
Getting user input via readline-sync in the console
Writing if/ else if/ else conditional statements
Using logical expressions and logical operators
Create flowcharts to help visualize control flow
Review Skills :
Using console.log to print to the console
Declaring and initializing variables, assigning data to variables
Naming variables effectively
Using template literals
Using math operators
Reference
readline-sync
Getting User Input
At the top of your file, import the readline-sync module. Get user input using READLINE.question() to prompt the user to type in their response. The user will be prompted to enter and submit a string which will be stored in a variable.
let variable = READLINE.question("message");
Example:
let userInput = READLINE.question("Type anything and I'll repeat it back!");
console.log(`You typed: ${userInput}`);
Conditional Statements
if statements
The if statement is the most basic example of a conditional.
It begins with the keyword if, followed by a logical expression enclosed in parentheses, and ends with a block of code enclosed in curly braces.
If the logical expression in the parentheses evaluates to true, then the code in the curly braces will run; otherwise, that code will be skipped over entirely.
if (x === 2) {
console.log(`x is 2`);
}
else statements
The else statement is a conditional that can follow an if (or else if) statement with an "otherwise" path. Any else statement always applies to the if statement directly before it, and you cannot have an else follow another else.
An else statement begins with the keyword else and ends with code enclosed in curly braces. The code of an else statement will only run when the if statement before it evaluates to false; otherwise, it will be skipped over entirely.
if (x === 2) {
console.log(`x is 2`);
} else {
console.log(`x is not 2`);
}
else if statements
The else if statement is simply an alternative if statement that must follow another if (or else if) statement.
In JavaScript, an else if statement begins with else if, and from then on looks and behaves identically to an if statement.
In the example below, the program is checking if x is 2, and if that evaluates to false, then it checks if x is 3. Note that if x is neither 2 nor 3, the else statement's code at the very end is run as a "default" branch.
if (x === 2) {
console.log(`x is 2`);
} else if (x === 3) {
console.log(`x is 3`);
} else {
console.log(`x is neither 2 nor 3`);
}
Nested Conditionals
Nested conditionals are conditionals inside other conditionals. They are just as useful in programming as they are in real life, particularly when certain conditionals depend on previous outcomes in a program's control flow.
A simple example of nesting conditionals is a list of all the things you can do as you grow older (depending on the state where you live, in some cases).
If you are at least 16, you can obtain a driver license.
If you are at least 18, you can vote.
If you are at least 21, you can purchase alcohol.
If you are at least 35, you can run for United States President (provided other factors, of course).
These are cumulative outcomes. If you are at least 18, you can obtain a driver license, but you can't vote, purchase alcohol, or become the president. However, if you are at least 18, you can vote as well as obtain a driver license. If you are 21 you can purchase alcohol, in addition to everything an 18 and a 16 year old can do.
Let's have a closer look, this time with JavaScript.
let READLINE = require("readline-sync");
let age = READLINE.question(`Enter your age: `);
if (age >= 16) {
console.log(`You can obtain a driver license.`);
if (age >= 18) {
console.log(`You can vote.`);
if (age >= 21) {
console.log(`You can purchase alcohol.`);
if (age >= 35) {
console.log(`You can be President of the United
States.`);
}
}
}
}
else {
console.log(`You can't do anything at all, apparently.
Gotta wait till you're older, kid!`);
}
Because of the way the conditionals are nested, this code will print all messages up until the point where your age is not old enough, in which case it'll skip the rest of the code beneath it. After all, if your age is not at least 21, there is no point in checking if you are also at least 35. Last, notice how we use indentation to organize our code; this makes it easier for a human to see how the conditionals are nested.
Flowcharting
A flowchart is a diagram that provides a visual representation of a program's "control flow".
There is no "right" way to do a flowchart. The point is to create a visual representation of how your program flows, from start to finish, that's easy for you to understand and use as a reference while programming. Remember: the better detailed your plan is, the easier it will be to execute it!
Be detailed, but simple
You don't need to write paragraphs in your flowchart boxes. As you can see in our example, simple language will suffice, so long as it is detailed and captures what is supposed to happen at that point.
Also, don't be unnecessarily reductionist. For example, our flowchart didn't mention that we should first obtain a friend to play the number guessing game with us. In your flowchart, you don't need a sequence like "purchase a phone", "get friend's number", "dial friend's number", "wait for friend to answer phone" and so forth, when "call friend" suffices... unless your flowchart is describing how to call a friend in the first place, of course.
Logical Expressions
To check if two values are equal, we use the equal/not equal operators.
> 3 == 3
true
> 3 != 3
false
Simple enough. Notice this though:
> 3 == "3"
true
Even though we are comparing values of completely different types (numbers and strings, respectively), JavaScript considers them equal. In many other languages this would not fly, since it would be like saying an actual apple is equal to a picture of an apple! However, for now just keep in mind that the equal/not equal operators are not "strict". JavaScript temporarily converts one of them to the other's type (e.g., string into number), and then does the comparison from there.
To draw contrast, let's try the stricter version of these: the strict equal/not equal operators.
> 3 === 3
true
> 3 !== 3
false
> 3 === "3"
false
As we can see here, JavaScript does not perform any kind of type conversion. It compares each value strictly, just as they are. So in the case of 3 === "3", we know that a number cannot be equal to a string (again, an apple isn't equal to a picture of an apple), so the expression evaluates to false as a result. These stricter versions are preferable in most cases.
The last two groups of comparison operators should be nothing new to you, since they work just as they do in math.
> 3 < 4
true
> 3 > 4
false
> 3 <= 3
true
> 3 >= 5
false
Note that all logical expressions evaluate to boolean type values. For example, the expression 3 > 4 evaluates to a boolean value of false. Meanwhile, 3 === 3 evaluates to a boolean value of true.
Logical Operators
First, let's see how the && ("and") operator works. According to the table, an expression using this operator will evaluate to true if both values on the left and right are true. Otherwise, the expression will evaluate to false. Let's use booleans to test this out:
> true && true
true
> true && false
false
> false && false
false
Notice that we only get true when both the left and right values are true. If either of them are false, the entire expression evaluates to false.
Let's try a few using comparison expressions. As we said in the previous section, comparison expressions evaluate to boolean values. So this should work. The parentheses here are optional, we are only including them for readability.
> (3 === 3) && (3 < 5)
true
> (3 <= 3) && (3 > 5)
false
> (3 !== 3) && (3 === "3")
false
Now for the || ("or") operator. According to the table, an expression using this operator will evaluate to true if either (or both) values on the left or right are true. Otherwise, the expression will evaluate to false. Test it out with both booleans and comparison expressions.
> true || true
true
> true || false
true
> false || false
false
> (3 === 3) || (3 < 5)
true
> (3 <= 3) || (3 > 5)
true
> (3 !== 3) || (3 === "3")
false
Notice that the only time an expression using the || operator evaluates to false is when both of the values on the left and right are false. If at least one value is true, the entire expression evaluates to true.
Finally, let's try the ! ("not") operator (also referred to as "bang"), which means "the value to the right is not true". For example, if "the sky is blue" is true, then "not(the sky is blue)" is false. Similarly, if "ducks are a kind of fish" is false, then "not(ducks are a kind of fish)" is true.
> !true
false
> !false
true
> !(3 === 3)
false
> !(3 !== 3)
true
Compound logical expressions
So far, all logical expressions we've written have only used two boolean values. However, you can use as many values (or expressions) as you like!
For example, notice that with the && operator, if any one of the values is false, the entire compound expression is false.
> true && true && false
false
> true && true && true
true
On the other hand, notice that with the || operator, if at least one value is true, the entire compound expression is true.
> true|| false || false || false
true
> false || false || false || false
false
Now for some shenanigans:
> true && false || true
true
Why is this true? Well...
First, true && false evaluates to false.
However, false || true evaluates to true.
Therefore, the entire compound expression is true.
Try this one:
> !(true || false) || true
true
Here's how it works:
First, we evaluate true || false , which we know is true.
Then we negate that because of the ! operator (the parentheses operate like they do in math here), making it false.
The compound expression is now reduced to false || true, which evaluates to true.
Short circuit evaluation
Consider this expression:
> false && (true || false)
false
This is just like one we did at the beginning of this section. However, there's a key difference that you can't notice from looking at the result alone.
Notice that false appears as the first value in this expression. Well, it just so happens that when the computer saw this false value along with the && operator, it completely ignored the other expression (true || false), since it knows that one false makes an entire && expression false as well.
This is called short circuit evaluation (or simply "short circuiting"), and is one of the cool economical features of many languages, including JavaScript. After all, why waste the computer's precious time/power checking the rest of the values if it knows the whole thing is false already?