Difference between revisions of "Chapter:Control flow"

From Juneday education
Jump to: navigation, search
(Questions and Answers: Style change)
m (Further reading)
 
Line 438: Line 438:
 
==Further reading==
 
==Further reading==
 
* [https://en.wikipedia.org/wiki/Control_flow Wikipedia has an article on control flow]
 
* [https://en.wikipedia.org/wiki/Control_flow Wikipedia has an article on control flow]
* [https://docs.oracle.com/javase/tutorial/java/nutsandbolts/flow.html Oracle has a tutorial on Java control flow] (Java)
+
* [https://docs.oracle.com/javase/tutorial/java/nutsandbolts/flow.html Oracle has a tutorial on Java control flow] (Java)
* [https://en.wikibooks.org/wiki/C_Programming/Control Wikibook on Program control] (C)
 
  
 
== Where to go next ==
 
== Where to go next ==

Latest revision as of 19:40, 9 June 2019

Control flow

Meta information about this chapter

Expand using link to the right to see the full content.

Introduction

Control flow is, of course, one of the central concepts in imperative programming. It is important that the students understand the concepts of branching and looping.

Purpose

The purpose of this chapter is to introduce the most basic control flow mechanisms in Java, so that the students can write more interesting programs.

The control flow constructs use blocks to group related code together, which is why we also introduce blocks in this chapter. Blocks are also used for defining classes and methods, which is why this will be useful also later on in the book/course.

Goal

The goal of this chapter is that the students can understand, explain and use:

  • the IF statement
  • the WHILE statement
  • the FOR statement
  • the concept of a BLOCK (of code)
    • scoping implications of blocks

It is also good if the student can choose between the FOR loop and the WHILE loop and motivate the choice.

Concepts

  • Block
  • IF (selection, branching)
  • WHILE (iteration, loop)
  • FOR (iteration, loop)

Instructions to the teacher

Our experience tells us that scoping is hard for many students and should therefore be given some attention when introducing blocks.

Another thing we have learned, is that it seems to work well to introduce the while loop before the for loop. It seems like the steps of the while loop:

  • declare variables used in test
  • while block start with the test
    • change the variables used in the test
  • end block

are pretty straight forward to the students. When later on introducing the for loop, you may present it as a more compact way to express the same thing: for (intitialization; test; change;) { block }.

However, expect the more diligent students to ask, "so how do I choose between the two?".

Our answer is that, on the one hand, they are indeed equivalent, but on the other hand, there are some subtle nuances which sets the two apart.

One rule of thumb can be: "If you know how many times you need to iterate, then use a for loop in order to make your statement clearer. If you don't know or can predict how many iterations are needed, use a while loop."

Another rule of thumb can be "If you don't need the loop variable to be in scope after the loop, you may use the for loop. If you need to use the loop variable also after the loop (and possibly even before), then use a while loop."

A related rule could be: "If you don't care about a loop variable, but rather want to iterate over some collection of objects - like a list or an array - then you may use a for-each-loop".

We have a section below about the for-each-loop (also known as "the enhanced for loop").

Lastly, we strongly suggest that you follow our style (also supported by many coding style guides) to always use curly braces around the body of IF, FOR, and, WHILE statements, even if they only have one single statement in their body. The only reason to leave out the curlies, in our opinion, is to show off that you know that you can leave them out. In our experience, it is begging for future problems (when more statements are added) and adds unnecessary complexity for the students. Heck, we think it is fine to tell them that they should always use curly braces (not exactly the same as the not so true claim that they must do so), in connection to IF, WHILE and FOR.

About leaving out curlies for control statements that have only one statement in their body, that is a rule which the students really don't need to learn at a beginners level. There's nothing wrong with showing them that it works, but if you do so, please tell them it is considered bad style. The rule might be confusing to students, because it only applies to certain constructs. You cannot, for instance, have a method without curlies, just because the method only has one single statement. Likewise, you cannot declare a class without curlies, just because it only has one statement.

Common problems

We'll get back to this point, at a later time. Promise!

Chapter videos

All videos in this chapter:

Lecture presentations (PDF):

See below for individual links (also slides) to the videos.

Block

Description

When we want to group together code, most often because it belongs together in some way, we use block (or code block). You Start a block with { and end it with }. All code in between is said to be the code block. The block could actually be empty but most often it contains one or more statements/instructions.

Note that variables declared inside a block of code are only visible (can only be used) inside the same block (or inside blocks declared inside the same block).

Videos and slides

Extra - Indentation

It is important that your code follow a familiar and standard style, so that people (including teachers) easily can read you code and quickly see the structure of it. An important part of the style is the way you indent your code.

Now that you know what a block of code is, you should spend some time and effort on making your code tidy. There are some style guides to follow when writing code in blocks.

First, your block starts with a left curly brace, {. This curly brace typically sits at the end of the line starting a block. All code inside the block, starts at a few spaces in. The block ends with a right curly brace, }, but that curly brace is left of the code inside the block. Let's look at some examples:

public class Carpet {  // <--- here's a start of a block
  
  int length;          // all statements in the block start at e.g. two spaces in
  double weight;
  String itemNumber;
  Color color;
  
} // <--- here's the end of the block

We will talk more about indentation at each sub section below.

Control flow introduction and if statement

Description

Let's start by a human example. If my shoelaces are not tied properly, I will tie them. This means I will only tie my shoelaces if they're not tied. With this simple example we want to show that we use if statements in our daily life all the time.

The IF-statement is a control flow construct that we can use if we want to execute a block of code only if a boolean expression is true. In its simplest form we write code with an if statement like this:

if (temperature>40) {
  System.out.println("Please, turn on the fan");
}

In this example we print "Please, turn on the fan" if the temperature (the value of the variable temperature) is higher than 40. If the temperature is less than (or equal) to 40 we do nothing.

A slightly more complex if statement:

if (temperature>40) {
  System.out.println("Please, turn on the fan");
} else {
  System.out.println("You do not need to turn on the fan");
}

We added code that is executed if the temperature is NOT higher than 40. We did this by adding else in the if statement.

Our final example will be:

if (temperature>40) {
  System.out.println("Please, turn the fan to MAX.");
} else if (temperature>30){
  System.out.println("Please, turn on the fan modestly");
} else {
  System.out.println("You do not need to turn on the air condition");
}

In this last example, we first check if the temperate is higher than 40. If it is, we output "Please, turn the fan to MAX." None of the other clauses of the if statement would execute. But if the temperature is NOT higher than 40 we continue and check if the temperature is higher then 30. If it is we output "Please, turn on the fan modestly" (and nothing else). If the temperature is not higher than 30 (or 40 for that matter) we output "You do not need to turn on the air condition".

Indentation for the IF statement

Note that the style for the if statement follows the style for blocks in general. In Java, we put the starting curly brace at the same line as the if header:

if ( printer.hasPaper() ) { // <--- here the if-block starts
  printJob.print();
} // here, the if-block ends

As you see, the end curly brace starts at the same column as the if statement header (under the "i" of "if").

Most editors will help you get the indentation right. In Atom, for instance, you can highlight all text in your Java-file and then go to the Edit menu, choose Lines sub menu, and then choose the Auto-indent menu option. In most cases, Atom will help you re-indent your whole file (the text you have highlighted).

But you should learn to get the indentation right from the start, since it will help you get successful as both a student and as a professional programmer. Most projects (or companies) adhere to some coding style standard. So details may vary. But you should always be consistent and follow one style consistently.

As a detail about the if-statement, we follow a style which mandates that there should be some spaces surrounding the if parentheses with the boolean expression. One space after the word "if" and one space before the opening curly brace for the block.

With the if-else the style looks like the following:

if ( printer.hasPaper() ) { // <--- here the if-block starts
  printJob.print();
} else { // else block starts here, on the same line as the closing curly for the if block
  printer.signal(Signals.OUT_OF_PAPER); // the statements in the else block are on the same column
}                                       // as those of the if block

If-else-if-else looks like the following:

if ( printer.hasLotsOfPaper() ) { // <--- here the if-block starts
  printJob.print();
} else if (printer.hasLowPaperStock() ) {  // else if block starts here, on the same line as the closing curly
  printer.signal(Signals.LOW_PAPER_STOCK); // the statements in the else-if block are on the same column as blocks above
} else {  // note where the curlies are, and also note the surrounding space
  printer.signal(Signals.OUT_OF_PAPER);
}

Videos and slides

while

Description

A while loop is a construct in a programming language that allows code to be repeated as long as a boolean expression is true.

An example:

1 int counter = 3;
2 while (counter > 0 ) {
3   System.out.println("Hi there!");
4   counter--; // decrease the value of counter so that we eventually will exit the loop
5 }

Let's go through the example:

  1. we declare and initialise (the first assignment) an integer variable, counter
  2. we start a while loop. This line means that we will keep looping/repeating as long as counter > 0. With the { we mark the beginning of the block to be executed for every loop.
  3. We simply output the text "Hi there!"
  4. The last thing we do in the block is the decrementing of counter so that the test will yeald false eventually
  5. End of the block of code to be executed in every loop

In the example above "Hi there!" will be printed 3 times. That is because we start with a value of 3 for counter and decrement it by one each iteration. The value will be, in order:

  1. 3 --- 3 > 0 is true
  2. 2 --- 2 > 0 is true
  3. 1 --- 1 > 0 is true
  4. 0 --- 0 > 0 is false - we won't enter the block here

Note that counter will finish at 0 and have the value 0 after the loop.

Indentation for the while-statement

The indentation of the while-statement, is pretty much the same as for a simple if-statement:

while ( printer.hasMorePaper() ) { // curly starts at the same line as the while-statement
  printer.print(printJob.nextPaper()); // statements in the block are indented
} // end-curly under the "w" of the while-statement

Note the space after "while" before the boolean expression, and before the start curly brace for the block.

Videos and slides

for

Description

The for statement (loop) is typically used when you know how many times you want to do something repeatedly. Think of programs that offers to repeat some boring task for you, and you, the user provides input for how many times the program should do it.

Then the program would read your input into a variable, and use that variable inside a for loop.

As with the while loop the for statement is used to loop (repeat) a block of code. The following code:

1 for (int i=0; i<3; i++) {
2   System.out.println("Hi there!");
3 }

outputs "Hi there!" three times. How? Let's go through the code:

  1. we start be declaring a for loop
    int i=0 means we declare a variable. This is done before we start looping
    i<3 means we will loop as long as i<3
    i++ means that for every loop we do i++ (as the last thing in the block)
    { defines the start of the block to be executed in each loop
  2. System.out.println("Hi there!"); outputs "Hi there!"
  3. } closes the block to be executed in each loop.

Slightly more formally we can say that a for statement looks like this:

1 for (INITIALIZATION; CONDITION; CHANGE) {
2     /* the code to execute for each loop */
3 }
  • INITIALIZATION declares a (local to the for block) variable and initializes it to some start value. This is executed only once.
  • CONDITION is the check of a boolean expression - typically a conditional expression involving the variable
  • CHANGE is what should happen with the variable every iteration - the change ensures that the condition will be false at some point so that the looping stops

Bonus for the students who run Bash inside a terminal!

Did you know that also Bash offers the for loop construct?

You might know that the command echo in bash is for printing out text to standard out (typically to the terminal you are working in).

Let's say you want - for some totally weird reason - print your user name to the screen ten times. You can use echo in a for loop directly in your terminal (running bash) like this:

for ((i=0; i < 10; i++))
do
  echo "$USER"
done

You may wonder what the $USER is, but that's just an environment variable Bash uses to store the current user's user name in.

Let's say that you want to print out the current time and date 10 times, once each second. You can use the date command to print the time and date. And you can use the sleep n command to sleep (do nothing) n seconds. So, what if we use a for loop to loop ten times, and in each loop iteration issue the date command, and then sleep 1?

This is what you can try:

for ((i=0; i < 10; i++))
do
  date
  sleep 1
done

If you'd like, you can do all that on one single command line in Bash:

for ((i=0; i < 10; i++)); do date; sleep 1; done

Again, it is typical to use a for loop, when you know how many times you want to repeat doing something, because the for loop makes that clear, as it has become an idiom (something that many people know by heart and often use).

Indentation for the for-statement

Here's the indentation of the for statement - same as for block, if, and while!

for (int i = 0; i < printJob.numberOfPapers(); i++) {
  printer.print(printJob.paper(i));
}

Note that blocks can be nested, as we said in the lecture on blocks! Here's a for-statement with a nested if-statement. See how the indentation level increases with each block:

for (int i = 0; i < printJob.numberOfPapers(); i++) {
  if ( printer.hasMorePapers() ) {
    printer.print(printJob.paper(i));
  } else {
    printer.signal(Signals.OUT_OF_PAPER);
    printJob.setCancelledAt(i);
  } // end if-else
}// end for

Videos and slides

for-each-loop

Since Java version 1.5 you can also, apart from the for loop, use the so called for-each-loop in references to Iterable objects (typically collections such as ArrayList):

for (Type item : iterableReferenceVariable) {
    // Do something to item
}

Let's look at the following example of a classic for loop:

List<String> someList = someMethodReturningAListOfStrings();
for (int item=0; item<someList.size(); i++) {
    String s = someList.get(item);
    System.out.println(s.toLowerCase());
}

The code above would print each String in the list with all letters in lower case. Now we should do a similar thing using the for each-loop. Before you look at the code below we would like you to take special notice of the following parts of the for loop above: String s, someList and System.out.println(s.toLowerCase()).

An example using a list of String references could look like this:

List<String> someList = someMethodReturningAListOfStrings();
for (String item : someList) {
    System.out.println(item.toLowerCase());
}

The code above would also print each String in the list with all letters in lower case. You can hopefully see some similarities in the for loop above (String s, someList and System.out.println(s.toLowerCase())).

Indentation for the for-each-loop

The enhanced for loop (popularly also known as the "for-each-loop"), follows the same pattern as block, if, while and for.

Note where we put the spaces. Spaces around stuff is not part of the indentation itself, of course, but it is part of the style and readability of the code.

for (Paper currentPaper : printJob.papers()) {
  printer.print(currentPaper);
}

Videos and slides

Misc

There are actually some more control flow constructs in Java:

  • do-while (iterate at least one time, do test at the end of the block)
  • try-catch-finally and throw (material for later lectures - not a control flow per se, but affects the control flow)
  • break and continue (adds special behavior to loops)
  • switch-case (a streamlined kind of multiple choice as alternative to long IF statements)

Summary

In this book, we use the Java programming language and the only available control flow statements in Java are:

Choice/decision making:

  • if-then
  • if-then-else
  • switch

Looping/iteration:

  • for
  • while
  • do-while
  • for-each-loop (a.k.a. enhanced for-loop) look on this page for a link to a lecture on this kind of loop!

Branching statements:

  • break
  • continue
  • return

Throwing an exception (see later chapter) could be considered a form of branching, but shouldn't be used as a form of flow control. Exceptions have another use, related to error handling.

This chapter focuses only on the following: if-then, if-then-else, for, while.


Questions and Answers

Q: “The for loop and the while loop seem to do the same thing. When should we use the one and when should we use the other?”
A: You may use the one you feel most comfortable with. If you want a hint of when to use for and when to use while, there is a recommendation that in situation when you know beforehand how many iterations you want, you should use the for loop. It could make the program easier to read and understand. When you don’t know how many iterations you want (for instance if your program is reading lines of text from a file and you don’t know how many lines there are in the file), it is probably more clear to use the while loop. When you read the code out loud, it could better match the way we think and speak. An example of reading out loud the line counting loop, could be “While we haven’t reached the end-of-file, read one more line and increase numberOfLines with one”. If we want to print ten copies of a document, we could use for and such a piece of programming could be read out loud like this, perhaps: “For every number between 0 and 9, print a copy and move the counter to the next number”.

As you see, reading out the for statement doesn’t really match the way we think or speak, but there is an alternative syntax for the for loop that we use when we have some kind of list. We’ll revisit the for loop when we have learned about lists, but as a teaser, we can say already that reading out the for loop when iterating over a list reads something like this: “For each element in theList, do something with that element and move on to the next element”.

Q: “Are there any other control flow mechanisms that you haven’t told us about?”
A: Actually, yes. There is a version of the while loop, called “do while”. It works almost like the while loop, but it always execute the statements in the block at least once, because it has the test of the condition at the end of the block.

do {
 swingAxeAgainstTree();
} while( tree.isStillStanding() );

The example above could be a simulation of cutting down a tree using an axe. We know that we must swing the axe against the tree at least once. And then we check to see if the tree is still standing. If it is, we repeat until the test fails (and and the tree is down).

To be honest, the do while construct is not very common, since in most situation (like when cutting down trees) there is no harm in doing the test first. That would be like first checking that the tree is standing before starting to swing the axe against it.

Another construct is the Switch statement. It is useful as an alternative to if-else-if statements when we know that there are many possible cases to test. It is quite common but not very hard to learn. We will not require that you know the switch statement but we encourage you to learn it anyway, as an exercise. You can read about it here: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html

Q: “Where in a Java program do we use the control flow things?”
A: Almost exclusively in methods and constructors. There are some exceptions to that rule (there are two special kinds of nameless blocks inside classes, but they are outside the scope of this course!) but if you want a rule it would be: Always inside a block, but never directly inside the block of a class (or inside the block of the friends of classes called interfaces and enums).

So you will never see an if statement, for instance, directly in the body of the class block. It is always inside a block that is inside the class block. Remember, the class block is one of the few blocks that can be the outermost blocks in a compilation unit (in a Java source code file).

Links

Further reading

Where to go next

Next page has the exercises for this chapter: Control_flow_-_Exercises

« PreviousBook TOCNext »