Skip to content
wannacode

Conditions

Problem

The shipping that should not be there

An online shop promises free shipping on orders of €50 and up. Under €50, shipping is €4.99. The order is €62, and the program still adds shipping:

const total = 62;
const shipping = 4.99;
console.log(`To pay: €${total + shipping}`);
Output
To pay: €66.99

The program runs every line, one after another. Here it has to choose: one line in one case, another line in another.

The idea

A comparison answers yes or no

First the program has to ask: is the total €50 or more? For this there are comparison operators. Their answer is not a number, but true or false: a value of type boolean.

const total = 62;
console.log(total >= 50);
console.log(total === 50);
console.log(total !== 50);
Output
true
false
true
You write It asks
a > b, a < b greater, less
a >= b, a <= b greater or equal, less or equal
a === b are they equal
a !== b are they different

Be careful: === compares, and = stores a value. total === 50 asks whether the total is 50, and total = 50 makes it 50.

JavaScript also has == with two signs. It first turns both values into one type and only then compares, so the text "5" turns out to be equal to the number 5:

console.log("5" == 5);
console.log("5" === 5);
Output
true
false

Always write === and !==. That is also how you will see them in other people's code.

Text in JavaScript is compared with the same ===:

const answer = "yes";
const yes = answer === "yes";
console.log(yes);
Output
true
More precisely, if you are curious

Decimal numbers are rarely exactly equal. The computer stores 0.1 and 0.2 approximately, so their sum is not exactly 0.3:

console.log(0.1 + 0.2 === 0.3);
console.log(0.1 + 0.2);
Output
false
0.30000000000000004

For decimal numbers, ask whether they are close enough: Math.abs(a - b) < 0.000001. Comparisons with > and < do not have this problem.

The idea

if and else: one of two paths

Now the program can choose. if checks the condition in the parentheses. If it is true, it runs the block after it. If it is not, it runs the block after else:

const total = 62;
let shipping;
if (total >= 50) {
shipping = 0;
} else {
shipping = 4.99;
}
console.log(`Shipping: €${shipping}`);
Output
Shipping: €0

For an order of €18.50 the same program prints Shipping: €4.99. Only one of the blocks runs, never both.

else is not required. Without it, if the condition is not true, the block is simply skipped and the program continues after it.

More precisely, if you are curious
  • If the block is one line, the braces { } can be left out. Do not do it: as soon as you add a second line, it will be outside the if, and the indentation will fool you into thinking it is inside.
  • The condition can be any value, not only true or false. The number 0 and the empty text "" count as false, everything else as true:
const total = 0;
if (total) {
console.log("There is a total");
} else {
console.log("0 counts as false");
}
Output
0 counts as false
  • That is why if (total = 50) is not an error: it stores 50 in total, and 50 counts as true. The condition is true for any total, and the total is now something else:
let total = 10;
if (total = 50) {
console.log("Free shipping");
}
console.log(total);
Output
Free shipping
50

Try it

An order bigger than the stock

There are 3 items in the warehouse, and the customer orders 5.

What will the program print?

const stock = 3;
let ordered = 5;
if (ordered > stock) {
console.log("Not enough in stock");
ordered = stock;
}
console.log(`Sending ${ordered} items`);
Answer

The idea

else if: more than two paths

A teacher turns test points into a grade. There are four possibilities. You put an if after the else:

const points = 76;
if (points >= 90) {
console.log("Excellent");
} else if (points >= 75) {
console.log("Very good");
} else if (points >= 50) {
console.log("Good");
} else {
console.log("Fail");
}
Output
Very good

The checks go from top to bottom. The first branch with a true condition runs, and the rest are skipped. 76 is not >= 90, but it is >= 75, so it is "Very good". The program never gets to >= 50, even though it is true too.

That is why the order matters: the strictest condition comes first. If points >= 50 were at the top, everyone with 50 points or more would get "Good".

const points = 76;
if (points >= 90) {
console.log("Excellent");
} else if (points >= 75) {
console.log("Very good");
} else if (points >= 50) {
console.log("Good");
} else {
console.log("Fail");
}
Step by step, in words
  1. points is 76.
  2. 76 >= 90? No. The "Excellent" branch is skipped.
  3. 76 >= 75? Yes. We go into the "Very good" branch.
  4. It prints "Very good".
  5. 76 >= 50 is true too, but it is not checked: the chain stops at the first true branch.

Try it

Find the bug

Everyone with 90 points or more gets "Excellent". A student with exactly 90 points gets "Very good". Which line is the bug on?

Pick the line with the bug.

The idea

And, or, not

The cinema gives a discount ticket to children and to students. There are two conditions, and one is enough. You connect them with logical operators:

const age = 16;
const student = false;
if (age < 18 || student) {
console.log("Discount ticket: €6");
} else {
console.log("Ticket: €10");
}
Output
Discount ticket: €6
  • a && b is true when both are true ("and").
  • a || b is true when at least one is true ("or").
  • !a is true when a is not true ("not"): !student.

Free shipping over €50 and only in the city is total >= 50 && inCity. A number is between 1 and 12 if month >= 1 && month <= 12. The math notation 1 <= month <= 12 does not work here, and it fails without an error: first 1 <= month becomes true or false, and then that is compared with 12 as 1 or 0. The result is always true, even for 13:

const month = 13;
console.log(1 <= month <= 12);
console.log(month >= 1 && month <= 12);
Output
true
false
More precisely, if you are curious
  • If the left operand already decides the answer, the right one is not checked: with false && … and with true || …. This is called short-circuit evaluation, and sometimes it protects you from an error: count !== 0 && total / count > 10 never divides by 0.
  • && comes before ||, like * before +. When you mix them, add parentheses so it reads clearly: (a && b) || c.
  • A condition can also be inside another if. That is a nested if. This code is the same as if (total >= 50 && inCity):
if (total >= 50) {
if (inCity) {
shipping = 0;
}
}

Try it

By 5 and by 7

What goes in the blank so the condition is true only for numbers divisible by both 5 and 7?

const number = 35;
if (number % 5 === 0  number % 7 === 0) {
  console.log("Divisible by both 5 and 7");
}

The idea

The ternary operator ? :

Sometimes the whole if is only there to pick one of two values. There is a short form for that, the ternary operator (it has three parts):

const points = 76;
const message = points >= 50 ? "You passed!" : "You did not pass.";
console.log(message);
Output
You passed!

You read it like this: condition ? the value if it is true : the value if it is not. The same with if and else takes several lines, and here it is one.

Use it to pick a value. If the program has to do different things in the two cases, write if.

More precisely, if you are curious
  • The two values can be of different types: text in one case and a number in the other. The program runs, but afterward you do not know what the variable holds. Pick between values of one type.
const points = 40;
const result = points >= 50 ? "Passed" : 0;
console.log(result);
Output
0
  • Ternary operators can be nested inside each other, but code like that is hard to read. For three or more possibilities, write else if.

The idea

switch: choosing by value

The shop is open from 9:00 to 18:00 on weekdays, until 14:00 on Saturday, and it is closed on Sunday. If the day is a number (1 is Monday, 7 is Sunday), you compare it with several exact values. For this there is switch:

const day = 6;
switch (day) {
case 6:
console.log("10:00–14:00");
break;
case 7:
console.log("Closed");
break;
default:
console.log("9:00–18:00");
}
Output
10:00–14:00
  • switch takes the value in the parentheses and jumps to the case with the same value.
  • break ends the switch. Without it execution continues into the next case.
  • default is for all other values, like the last else.
  • Several values with the same action are written one under the other: case 6: and right after it case 7:.

switch works with numbers and text. It compares like ===, so the text "6" does not match case 6. For checks like "from 50 and up", write if.

More precisely, if you are curious
  • If you forget break, execution "falls through" into the next case, with no check. For day 6, two lines are printed:
const day = 6;
switch (day) {
case 6:
console.log("10:00–14:00");
case 7:
console.log("Closed");
break;
default:
console.log("9:00–18:00");
}
Output
10:00–14:00
Closed
  • Because of ===, text from the input does not match a number in a case. Convert it first with Number(...):
const day = "6";
switch (day) {
case 6:
console.log("10:00–14:00");
break;
default:
console.log("No such day");
}
Output
No such day
  • In Java and C#, switch can also give a value. In JavaScript it cannot: store the value in a variable in each case, or pick it with the ternary operator.

Exercise

Programs that choose

Solve the tasks in your editor. Each number in the input is on a separate line. Try each solution with input that goes through the other branches too.

1. A cinema ticket. Read the age. Up to 6 years old you get in free, up to 17 the ticket is €6, up to 64 it is €10, from 65 up it is €5. A negative age is an error.

Input
15
Output
The ticket is €6

2. A mini calculator. Read a number, an operation (+, -, * or /) and a second number. Pick the action with switch on the text of the operation. You cannot divide by 0.

Input
12
/
5
Output
Result: 2.4

3. A quadratic equation. Read a, b and c from ax² + bx + c = 0. The discriminant is D = b² − 4ac. If D is positive, there are two roots: (−b ± √D) / 2a. If D is 0, there is one root: −b / 2a. If D is negative, there are no real roots. If a = 0, the equation is not quadratic.

Input
1
-3
2
Output
x1 = 2.00, x2 = 1.00

4. A valid date. Read a day, a month and a year and say whether the date exists. Find the number of days in the month with switch. February has 29 days in a leap year: divisible by 4 but not by 100, or divisible by 400.

Input
29
2
2023
Output
Invalid date

For 29, 2, 2024 the output is Valid date.

More tasks

  • Even or odd. For 7: Odd.
  • Positive, negative or zero. For −5: Negative.
  • Greater than 10. For 15: Greater than 10.
  • Are they equal. Read two numbers. For 5 and 5: Equal.
  • The bigger of two. Read two numbers and print the bigger one. Do it once with if and once with ? :.
  • Absolute value. Without Math.abs: if the number is negative, change its sign.
  • Yes or no. Read text. Print true for "yes", false for "no", and Answer not understood for anything else.
  • By 5 and by 7. Say whether the number is divisible by both 5 and 7. For 35: yes, for 10: no.
  • Three numbers in ascending order. Read three numbers and print them from the smallest to the biggest. For 7, 2, 5: 2 5 7.
  • The smallest and the biggest of five. Read five numbers into five variables. Remember the first one as both the smallest and the biggest, then compare each next one with it.
  • Day of the week. Read a number from 1 to 7 and print the day: 1 is Monday. For another number: No such day. Try it with switch.
  • Age group. Up to 12 years old is a child, up to 19 a teenager, otherwise an adult.
  • Season by month. December, January and February are winter, March to May is spring, and so on. For 4: Spring. With switch, put several cases one under the other.
  • Is it a triangle. Three sides make a triangle if the sum of any two is bigger than the third. For 3, 4, 5: yes, for 1, 2, 3: no.
  • A grade in words. Read a grade from 2 to 6 and print Fail, Average, Good, Very good or Excellent.
  • Guess the animal. The program asks questions with a "yes" or "no" answer and guesses which animal you thought of. Start with a greeting and a short explanation of the game. You can ask all the questions and then decide with else if, or ask only what you need with nested if statements. The questions:
Question If "yes" If "no"
Does it fly? a bird or an insect go on
Does it have feathers? a bird if it flies, an insect
Does it swim? if it does not fly: a fish or a small water mammal go on
Does it meow? a cat not a cat
Does it have fur? a dog, a cat or another mammal a lizard or another reptile
Is it green? if it does not fly and does not swim: a frog or a lizard go on
Does it roar? a cow or a lion go on
Does it have a trunk? an elephant go on

An example (the input is the answer to each question, in order):

Input
no
no
no
yes
yes
no
no
no
Output
Think of an animal. I will ask you 8 questions. Answer yes or no.
Does it fly?
Does it have feathers?
Does it swim?
Does it meow?
Does it have fur?
Is it green?
Does it roar?
Does it have a trunk?
I think it is a cat.

Test

Check yourself

1. What does 62.0 >= 50 give?
2. What is the difference between = and ===?
3. The chain if / else if checks points >= 50 first, then points >= 75. What happens with 95 points?
4. There is a discount if age < 18 || age >= 65. Does a 70-year-old get a discount?
5. What happens in a switch if a case has no break at the end?

Made by Ivo Gergov as part of Evo Tech's campaign for accessible programming education ·