Chapter 5. Conditionals
Conditionals are statements which execute a statement or series of statements depending on if a condition or predicate is true
. This chapter will cover if-else statements, while loops, until loops, do-while loops, for loops, and foreach loops.
5.0.1 Function - input
In order to test our conditional functions, it is advantageous to get keyboard input from the user of the program. This will require the use of a global function called input
. The function requires 0 arguments. When input
is called, it blocks program execution until keyboard input is given, terminated by the enter
key. The function returns the input back as a string.
To test the input
function, use the following program.
func main () {
print ("Enter some input, then press enter: ");
string entered = input ();
printf ("You entered {0}\n", entered);
}
5.1 - if else Statements
The most basic way to control program flow is with the if-else
conditional statements. If the condition is true
, the if
body will be executed. If the value was false
, an optional else
body can be executed.
To exhibit the functionality of if statements, let's create a program that prompts the user for a password. If the password is 123456
(correct), the program will display Password Accepted
.
func main () {
print ("Enter the password: ");
string pass = input ();
if (pass == "123456") {
println ("Password Accepted!");
}
The first two lines should make sense. A message is displayed to the user followed by the prompt for input. The third line of main
starts the if
statement. The expression inside of the parentheses is the condition that the statement operates on. In this program, the condition is the binary operation ==
. It compares the the variable with the user input to the string 123456
. If they are equal, it will display Password Accepted!
, otherwise the program will do nothing.
As the name suggests, if
statements can also have an else
component. This is the part of the statement that will execute only if the condition returned false. For our password example, we might want to add an else
component to tell the user that the password they entered was incorrect. Let's add this to the code example.
func main () {
print ("Enter the password: ");
string pass = input ();
if (pass == "123456") {
println ("Password Accepted!");
} else {
println ("Password was Incorrect!");
}
}
Run this program a few times. If you give the input 123456
, the program will output Password Accepted!
. Any input other than 123456
will produce the output Password was Incorrect!
.
5.1.1 Statement - else if
The code example we used in 5.1 uses a simple true or false switch. Either the true statement will execute or the false statement will execute. But what if you wanted to test multiple conditions? To do this, you can chain if statements together using an else if
. This allows you to test multiple conditions and still have a final else
component.
For example, say you wanted to create a program that asked for a number between 1 and 6, displaying a
, b
, c
, d
, e
, or f
based on the number. You would use an if
statement to test for 1
, then else if
components for the rest of the numbers. The final else
will execute if none of the conditions are met, telling you that the number was not between 1 and 6.
func main () {
print ("Enter a number between 1 and 6: ");
string num = input ();
if (num == "1") {
println ("a");
} else if (num == "2") {
println ("b");
} else if (num == "3") {
println ("c");
} else if (num == "4") {
println ("d");
} else if (num == "5") {
println ("e");
} else if (num == "6") {
println ("f");
} else {
printf ("{0} is not a number between 1 and 6!\n", num);
}
}
5.1.2 Chaining Conditions
5.1 and 5.1.1 showed conditionals that operate based on a single condition. You can chain conditions together using the && logical and, as well as the || logical or operator. The logical and operator is a binary operator that returns true
only if the condition on the left is true
AND the condition on the right is true
. The logical or operator is a binary operator that returns true
if either or both conditions on the left and right are true
.
func main () {
if (true && true) {
println ("1");
}
if (true && false) {
println ("2");
}
if (true || true) {
println ("3");
}
if (true || false) {
println (4);
}
if (false || false) {
println (5);
}
}
Output:
1
3
4
5.2 - while Loops
Sometimes you may have a section of code that you would like to have repeated. This could be because it needs to be ran a certain amount of times, until a condition is met, or infinitely.
A simple example of what loops can do would be iterating over a series of numbers. This means displaying all the numbers between a start and an end. Here is an example of a while loop that displays all the numbers from 0 to 10.
func main () {
int num = 0;
while (num <= 10) {
println (num++);
}
println ("All done.");
}
Output:
0
1
2
3
4
5
6
7
8
9
10
All done.
The code starts by setting the local variable num
to 0
. This is the variable that will hold the numbers we iterate over. The next line begins the while
loop. The condition for the while loop is that num <= 10
. Since num
starts as 0
, 0
is less than 10
, so this returns true
and the code executes. The code body prints the number, then increments num
. This will keep going until num
is 11
, where the condition will be false
and the loop will terminate.
5.3 - until Loops
The inverse of a while
loop is an until
loop. An until
loop works the same way as a while
loop, except it executes when a condition is false. This is the same as doing while (!<expression>)
. The reason until loops exist is to make certain loops easier to understand.
Here is the counter program rewritten using an until loop.
func main () {
int num = 0;
until (num > 10) {
println (num++);
}
println ("All done.");
}
The until
loop in this program keeps executing UNTIL the variable num
is greater than 10
.
5.4 - do while Loops
Another style of while
loop is the do while
loop. Unlike any other loop, it will execute the body once, then start checking the condition and looping. This ensures that the body of the loop will execute at least once.
To test out this anomaly, run the following program.
func main () {
do {
println ("Running.");
} while (false);
}
Output:
Running.
Normally if this were a vanilla while
loop, this code would never execute, since the condition would always be false
. But because this is a do while
loop, the body will be ran once, printing out Running.
then exit.
5.5 - for Loops
A for
loop is a loop that allows you to run a statement once, then execute a body and a repeating statement while a condition is true
. This is often used for iterator loops, since the initial statement can be the declaration of a counter variable, the repeat statement can increment that variable, and the condition can check that variable against an upper bound.
Consider the iterative code in 5.2. There is the line that declares the variable num
, a while
loop to check the value of num
, and the expression num++
in the body to increment it. This can be written much more concise and clear using a for
loop.
func main () {
for (int i = 0; i <= 10; i++) {
println (i);
}
println ("All done.");
}
Output:
0
1
2
3
4
5
6
7
8
9
10
All done.
Inside the for
loop, the first statement declares the variable i
(i
is often used as an iterator). This is the initial statement as it only needs to be done once. After the semicolon is the condition i <= 10
. This means that our for
loop need only execute until i
is equal to or greater than 10
. After the condition is the repeat statement, which executes AFTER the loop body runs.
5.6 foreach Loops
The foreach
loop is used to iterate over an iterable object (object which implements the __iter__
method and can be turned into a list) to cycle through the elements in a list (see Chapter 4 for coverage of lists).
Using the foreach
approach instead of a for
loop can be a cleaner and faster alternative. The syntax for foreach
is foreach (<var> in <iterable>) <body>
. Let's create a program which iterates through a list of names and displays them to the terminal.
func main () {
list names = [ "John", "Jamie", "George", "Cameron", "Jackie" ];
foreach (name in names) {
printf ("Name: {0}\n", name);
}
println ("All done.");
}
Output:
Name: John
Name: Jamie
Name: George
Name: Cameron
Name: Jackie
All done.
When the foreach
loop executes, it goes through each element in the given list, assigning that value to the variable names
and executes the body.
5.7 More with loops
This section will just cover some more in depth topics about the power of looping in Hassium.
5.7.1 Loop Trick - Infinite Loops
Some loops can execute forever. This is called an infinite loop. For a loop to be a truly infinite loop, the condition must always return true
no matter what. This can be a comparison of constants such as while (1 == 1)
or much simpler, while (true)
.
Try running this code:
func main () {
int a = 0;
while (true) {
println (a++);
}
}
This will output every number from 0 to 2,147,483,647, the maximum value a Hassium integer can hold.
5.7.2 Loops - break
By default, loops exit when their condition is met. But a loop can also exit prematurely using the break
statement. This can be used for special cases when a loop should be aborted or for leaving infinite loops.
Test out the break function with the following code.
func main () {
int num = 0;
while (true) {
println (++num);
if (num == 6) {
break;
}
}
println ("All done.");
}
Output:
0
1
2
3
4
5
6
All done.
Inside of the while (true)
body there is an if
statement checking if the number has reached 6
. If it has, the break
statement is ran, and the loop terminates.
5.7.3 Loops - continue
In looping, the continue
statement can be used to skip over the body of the loop, but still keep looping. This can be used for special conditions inside iterative loops.
Take the following example of a loop that counts from -5
to 5
, dividing the number 10
by that number.
func main () {
for (int i = -5; i <= 5; i++) {
println (10 / i);
}
}
Output:
-2
-2.5
-3.33333333333333
-5
-10
▒
10
5
3.33333333333333
2.5
2
The number in the middle space between -10
and 10
is a null
, this is because Hassium tried to divide the number 10
by 0
, which is an impossible operation. To work around this we can test if i
is 0
, and if so, skip it.
func main () {
for (int i = -5; i <= 5; i++) {
if (i == 0) {
continue;
}
println (10 / i);
}
}
Output:
-2
-2.5
-3.33333333333333
-5
-10
10
5
3.33333333333333
2.5
2
When the variable i
was 0
, Hassium skipped over the body of the loop and kept going.
5.8 - The Switch Statement
The switch
statement is a way of chaining if
and else
statements together. An initial value is given, and that value is checked against each case
inside of the switch
statement. If the values are equal, the body of the case
statement will execute. If no case
statements execute, the default
case will execute.
Let's write a program that accepts input from the user for a switch
statement. Depending on the number entered, a different letter will output.
func main () {
print ("Enter a number between 1 and 6: ");
string num = input ();
switch (num) {
case "1" {
println ("a");
}
case "2" {
println ("b");
}
case "3" {
println ("c");
}
}
}
5.9 - The Ternary Operator
Unlike the unary operators which have one operand and the binary operators that have two operands, the ternary operator has three operands. The ternary operator (represented as ?:) is similar to an if
statement in practice. The first operand is a conditional expression. If this expression evaluates to true
, the value second operand will be used, otherwise the value of the third operand will be used. The syntax of the ternary operator is <expression> ? <expression1> : <expression2>
.
Let's write a program to test out this unique operator.
func main () {
printf ("Enter the secret phrase: ");
string response = input () == "123456" ? "Correct login!" : "Incorrect!";
println (response);
}
Sample run 1:
Enter the secret phrase: 123456
Correct login!
Sample run 2:
Enter the secret phrase: something else
Incorrect!
Chapter 5 - Exercises
Exercise 5.1
Write a for
loop that displays the numbers from 100
to 0
.
Exercise 5.2
Create an infinite loop that displays a prompt >
, takes in keyboard input, and displays it back to the user. The loop should terminate when the user enters STOP
.
Sample run:
> apple
apple
> banana
banana
> STOP