• No results found

Conditional Statements

In document Java (Page 30-44)

As well as arithmetic, input and output, there are only two other basic features a program can have:

1. Comparing values and doing different actions for different data 2. Repeating actions

This section is about the first of these.

Suppose we need a program which will input a number, and then output a warning message if it is greater than 100.

That description uses the word if – and we can write it using an if statement

Scanner scanner = new Scanner(System.in);

double number;

System.out.println(“Enter a number”);

number = scanner.nextDouble();

if (number > 100.0)

System.out.println("Too big");

Try this. Run it twice – firstly entering a number less than 100, then greater than 100.

Exercise

Alter this so you only get a message if the number is greater than 1000.

Syntax

Syntax means grammar rules.

An if statement is like this:

if ( <some condition> )

<what to do if the condition is true>

The <some condition> is an expression which evaluates to true or false. If it is true, the statements in the curly brackets are executed. If it is not, nothing happens and we just move on to what comes next.

Example

Suppose we want a program which gives a discount of 10% if the purchase is over £100:

Scanner scanner = new Scanner(System.in);

double purchase;

discount=purchase*0.10;

purchase=purchase-discount;

System.out.println("After discount this is £"+purchase);

This sets the discount to zero before the ‘if’. This means if the purchase is not over 100, the discount is zero, but if it is, it is 10%.

Exercise Try this out.

Change it so you get a 20% discount.

Tracing an if

Tracing a program fragment might help to understand ifs. For example:

int x;

int y;

Scanner myScanner = new Scanner(System.in);

x=myScanner.nextInt();

y=1;

if (x>10) y=2;

System.out.println(y)

Suppose the user inputs 12:

Memory Program Comment

x ? y ?

int x;

int y;

Scanner myScanner = new Scanner(System.in);

x=myScanner.nextInt();

Scanner myScanner = new Scanner(System.in);

x=myScanner.nextInt();

Scanner myScanner = new Scanner(System.in);

x=myScanner.nextInt();

Scanner myScanner = new Scanner(System.in);

x=myScanner.nextInt();

if (x>10) y=2;

System.out.println(y);

Conditional as flowchart

This is another way of looking at ifs, as shown at the side.

ifs, semi-colons and blocks

Do NOT put a semi-colon at the end of an if header - this is WRONG:

if (x>4);

y=10;

As a result of Java syntax, this is allowable. So unfortunately the compiler will not tell you it is wrong - but it is. The ; ends the statement, so the if stops there - and y=10; is executed either way. In effect it says if x is greater than 4, do nothing.

Then just make y=10.

Often you want to do several things if the condition is true . A block will do this. This is just several statements enclosed in curly brackets. For example

if (x>4) {

y=10;

z=2;

}

A block does not need a semi-colon after it.

Else

We often want to do something if a condition is true, and something else if it is not. The if..else structure does this:

if (something) do option one else

do option two

For example, suppose we want to accept a number only if it is greater than 10. We want to tell the user whether it was accepted of not:

..

x=myScanner.nextInt() if (x>10)

System.out.println("Accepted");

else

System.out.println("Not accepted");

Exercise

Write a program which inputs an integer. If the value inputted is greater than 50, output "Accepted".

Otherwise output the message "Too small".

Indentation

Indentation means setting code in from the left margin by amounts which show the code structure.

For example:

if (x>100) { ..

..

} else { ..

..

}

This helps to make things clearer, especially when we come to have ifs inside ifs and loops inside loops. Many IDE editors will do this for you - right-click and choose Format.

Compound conditions

Suppose we want to require a value to be between 5 and 10. One way to do this would be to first check if it was more than 5, then less than 10, with two ifs:

if (x>5) if(x<10)

System.out.println("OK");

In this structure, the statement inside the first if is itself an if. This is OK - an if can contain any type of statement.

But we can do the two tests together, like this:

if (x>5 && x<10)

System.out.println("OK");

The && means 'and' - so it reads if x is greater than 5 and x is less than 10..

The following is WRONG:

if (x>5 && <10)

System.out.println("OK");

You can say 'x is greater than 5 and less than 10' in English, but not in Java.

The symbol for 'or' is ||. So

if (x<5 || x<10)

System.out.println("OK");

says OK if x is less than 5 or greater than 10.

Equality and assignment

To test if two values are equal, use ==

if (x==5)

if (x=5)

System.out.println("OK");

x=5 is an assignment - it tells the system to make x 5. It should be x==5, which asks whether x is 5.

The symbol ! means NOT, so != mans not equal to:

if (x!=5)

System.out.println("OK");

accepts anything except 5.

You need to be careful with edge values. For example

if (!(x > 10))

System.out.println("OK");

means 'if x is not greater than 10'. So it accepts 10, or less.

Exercise

Write a program which accepts numbers up to 5 inclusive, and over 9, outputting 'OK', and outputting 'Out of range' otherwise.

Algorithms

Suppose we need some code to input two integers, and then outputs them in order of size, largest first. So input 26, 20 outputs 26 20. Input 3,4 outputs 4,3:

import java.util.Scanner;

public class Main {

public static void main(String[] args) { int x;

int y;

Scanner myScanner = new Scanner(System.in);

x = myScanner.nextInt();

y = myScanner.nextInt();

if (x > y) {

System.out.println(x + " " + y);

} else {

System.out.println(y + " " + x);

} } }

This is easy - we compare x and y, and if x is bigger, output x then y, otherwise y then x.

This is a simple algorithm.

An algorithm is a method or recipe or solution to a problem, as a series of simple logical steps. A program is an implementation of an algorithm in a particular language.

For clever programming, finding the correct algorithm is more significant that actually writing the program. Fortunately optimal algorithms for many standard tasks have been invented, and sometimes even coded into languages.

Not so easy..

Suppose we need to input three numbers and output them in order, biggest first. How would you do that? Before you read on, decide what algorithm you would use, and program it.

One algorithm would be 1. Find the biggest, and output it.

2. Find the middle and output it.

3. Find the smallest, and output it.

Finding the middle one is not easy. If the numbers are x y z, then x is the middle if the order is y x z or z x y.

so we need to test if y is greater than x and x is greater than z, or z is greater than x and x is greater than y.

int x, y, z;

Scanner myScanner = new Scanner(System.in);

x = myScanner.nextInt();

This is getting tricky. We have included comments like

// find biggest

to help keep track of what we are doing. Try this method.

Is it the best way? It uses 9 comparisons. If we've found the biggest and the middle, we should not have to find the smallest - which suggests it is not.

An alternative algorithm is to simply test the 6 possibilities, which are x y z

int x, y, z;

Scanner myScanner = new Scanner(System.in);

x = myScanner.nextInt();

y = myScanner.nextInt();

z = myScanner.nextInt();

if (x > y && y > z) {

System.out.println(x + " " + y + " " + z);

}

if (x > z && z > y) {

System.out.println(x + " " + z + " " + y);

}

if (y > x && x > z) {

System.out.println(y + " " + x + " " + z);

}

if (y > z && z > x) {

System.out.println(y + " " + z + " " + x);

}

if (z > x && x > y) {

System.out.println(z + " " + x + " " + y);

}

if (z > y && y > x) {

System.out.println(z + " " + y + " " + x);

}

Exercise

Try this way. Do you think this is more efficient that the first? Could it be further improved?

Was your method more efficient?

What happens if two numbers are equal?

Loops

Suppose we want to add up the first twelve integers. This does it:

int total=0;

This works, but it's a lot of typing. Suppose we needed to add up the first 12000 integers? This method would be impractical.

The code above has almost the same statement total+=?; twelve times. What we need is a way to execute the same statement several times.

We could use the statement total+=n; and change the value of the variable n. This would need to be 1, then 2, then 3, up to 12. Here it is

Study this code carefully. We have a new kind of statement - a while loop.

1. There is a loop header, while (n<13)

2. This is followed by the loop body - a block { } containing two statements: total+=n; and n++;

3. The loop body is repeatedly executed, so long as the condition (n<13) is true.

4. The index n is initialised to be 1.

The loop body is repeated. The first time, n is 1, so the first statement in teh loop body is in effect total+=1;. The second statement, n++; increase n to be 2.

So on the next repeat, it does total+=2; and n is increased to 3.

On the third repeat it does total+=3;

This will continue up to and including n=12, when it does total+=12; and n increases to 13.

But then the condition to continue, n<13, is no longer true, so the loop terminates.

How could we modify this to add up integers from 1 to 20? Just change the condition:

int total = 0;

Add up the numbers from 10 to 20? Change the initialisation:

int total = 0;

Display the total as we go along? Have the output inside the loop body:

int total = 0;

int n;

n = 1;

while (n < 1001) { total += n;

System.out.println("n = "+n+" total = "+total);

n+=2;

}

while loops

1. The condition must be in round brackets, like (n<13)

2. The condition can be any boolean expression, such as (n<13 && x!=5) 3. There should be no semi-colon at the end of the loop header

4. If there is just one statement in the loop body, it does not need to be a block - such as

while (n<10) n++;

5. You might have an endless loop, such as

while (true) total += n;

In this case, you would need to use the IDE to cancel the process, or use Task Manager in Windows.

do..while loop

int total=0;

In most situations the choice of while or do..while is arbitrary. The only difference is that do..while will execute at least once. In a while, if the condition is false the first time in, the loop body will never be executed.

Exercise

Write a program which adds up the even numbers from 2 to 10 inclusive and outputs the total.

Test that it gives the correct answer

Change it so it adds the even numbers from 2 to 10000.

Programming with loops example

We often need some ingenuity to solve a programming problem with a loop. A key stage is to recognise that a task involves repeating something, so a loop is needed.

Suppose we need to separate, and print separately, the digits of a number. So given 1234, it should output

1 2 3 4

We need to do this for each digit - so we are repeating something and need a loop. Do we know how many times to repeat? The number could be 1234 (4 times) or 54321 (5 times) or whatever, so it is not a fixed number of repeats.

How to separate the digits? Use integer division by 10, and modulo. For example, if the number is n=1234, then

n%10 is 4, the lowest digit, and

n/10 is 123. So change n to this, and loop. So we have an outline:

given the number n while..

digit = n%10, and output it n = n/10

When should the loop end? n will get smaller. On the last output, n is less than 10. Then it is zero. So our code is

int n = 1234;

while (n > 0) {

int digit = n % 10;

System.out.println(digit);

n /= 10;

}

We have declared and assigned the variable digit inside the loop. This is OK.

This is not quite right - the output is least significant digit first, when we wanted most sgnificant first.

This is easily fixed using an array, which we will meet later.

for loops

The most common loop in Java is the for loop. This has a loop header and body like this:

for (...) { // loop body }

Here is an example, to add up the numbers 1 to 5:

int number;

int total;

total = 0;

for (int c = 1; c < 6; c++) { number = c;

total = total + number;

}

System.out.println(total);

The loop header has three parts, separated by semi-colons. It goes for ( start; loop so long as; change after each repeat )

So in our example, we start with c=1, we repeat so long as c is less than 6, and after each repetition, it increases c by 1. In other words, c goes 1 2 3 4 and 5. The loop body is repeated for each of these. So the first time it says number = 1, then number = 2, then number = 3, then - you've got it.

Exercise

Modify this program so it adds up the numbers 1 to 1000. Is it correct? If you cannot remember how to work it out, google 'arithmetic progression'

Note that in the loop start:

int c=1;

we both initialise c to be 1, and declare it. We do not have to declare it here (it could have been declared with the other variables) but it can be, and often is. If it is, it can only be used in the loop body ('its scope is restricted to the loop')

Another example

This program outputs 100 down to 0 in steps of 2:

for (int c = 100; c > -1; c=c-2) { System.out.println(c);

}

If the loop body has just one statement in it, you do not need the block (the curly braces). As with an if, a semi-colon at the end of the header is WRONG. This is WRONG

Exercise

Write loops which will output 1. 0 1 2 3 4 5 6 7 8 9 10 2. 10 8 6 4 2 0

3. 5 4 3 2 1 0 -1 -2 -3 -4 -5

4. Write a loop which will calculate the total of 1+2+3+4+5..., stopping when the total exceeds 100.

5. Write a program which first inputs an integer n, then calculates and outputs 1X2X3X4X..n (which is called n! or n factorial)

Nested loops

The statements in a loop body can be any type, including loops themselves. Look at the following program:

for (int c = 1; c < 6; c++) for (int d = 1; d<6; d++) System.out.println(c+" "+d);

What do you think it will output?

Try it - can you explain what it does?

Exercise

1. Write a program which will output the 5 times table, like this 1 X 5 = 5

2 X 5 = 10 3 X 5 = 15 ..

12 X 5 = 60

2. Extend this so it outputs all the multiplication tables, one after the other, from the 2 to the 12 times table.

break and continue

These are two new types of statements which can be used in loops (and conditionals).

You use continue; part way through a loop body. It misses out the rest of the loop body, and repeats.

You would usually use it with an if, like

while(...)

break is similar, but it breaks out of the loop completely. So you might say:

while (true)

You can break out of a loop, but not out of an if. This was a famous bug which crashed AT&T in 1990.

Testing

Beware of bugs in the above code; I have only proved it correct, not tried it.

- Donald E. Knuth

Testing means checking a program works by trying to run it.

You should write program code in small sections, and test each small section before you write more.

Testing is a major aspect of software engineering. In Java, the JUnit framework is a formal way of testing code. Since testing may take a long time, the process is sometimes automated.

However the beginner programmer needs to test code in an informal manner. To test, you need to know what the output should be - otherwise you cannot tell if it works. For example, we might have some code to convert Centigrade temperaturs to Fahrenheit:

int centi = 17;

int fahr = centi*9/5 + 32;

System.out.println(fahr);

If we run this, it outputs 62. However that does not help unless we know what the correct answer is.

In fact it is 62.6. Why is our code wrong? The correct answer is not an int, but we have used that as the type. The correction is simple:

double centi = 17;

double fahr = centi*9/5 + 32;

System.out.println(fahr);

Sometimes thought is needed to work out how to test something - a testing strategy. For example, you might be working on code to write data into a file, and read it back. You might write both the writing and reading code at the same time. How to test it? If it does not work, is the writing wrong, or the reading? The solution is to look at the file directly, say in a text editor. If it is wrong, the writing code has the error. If it is correct, the reading code is wrong.

In document Java (Page 30-44)