From 5250a7fa3589ff7e59a524bb272ab1fbd3389f22 Mon Sep 17 00:00:00 2001 From: stadibo Date: Wed, 24 Jul 2019 09:54:12 +0300 Subject: [PATCH] Osa1.6 translated-ish --- data/osa-1/6-conditional-statements.md | 1520 ++++++++++++++++++++++++ data/osa-1/6-ehtolauseet.md | 1071 ----------------- 2 files changed, 1520 insertions(+), 1071 deletions(-) create mode 100644 data/osa-1/6-conditional-statements.md delete mode 100644 data/osa-1/6-ehtolauseet.md diff --git a/data/osa-1/6-conditional-statements.md b/data/osa-1/6-conditional-statements.md new file mode 100644 index 000000000..cf21c599e --- /dev/null +++ b/data/osa-1/6-conditional-statements.md @@ -0,0 +1,1520 @@ +--- +# path: "/osa-1/6-ehtolauseet" +# title: "Ehtolauseet ja vaihtoehtoinen toiminta" +path: "/osa-1/6-ehtolauseet" # NOTE: not translated +title: "Conditional statements and alternative operation" +--- + + + + + + + + +- You are familiar with the concept of a conditional statement and know how to create alternative operation in a program using conditional statements. +- You are familiar with common comparison operators and logical operations used in conditional statements. +- You know how to compare numbers as well as strings taking into account the equals-command for strings. +- You are familiar with the order of execution for a conditional statement, and you know that the parsing of a conditional statement stops at the first condition for which its statement evaluates to true. + + + + + + +Up until now, our programs have been linear, meaning the execution of the program has happened from top to bottom without any significant surprises or options. However, we usually want alternative functionality in our programs. In other words, functionality that is in one way or another, dependent on the state of the variables in the program. + + + +For the execution of a program to be able to branch based on e.g. input by a user, we need to use a conditional **statement**. The simplest conditional statement looks something like this. + + + +```java +System.out.println("Hello, world!"); +if (true) { + System.out.println("This code is unavoidable!"); +} +``` + + + +Hello, world! +This code is unavoidable! + + + + + +A conditional statement begins with the keyword `if`, followed by parentheses. Inside the parentheses we place an expression, which is evaluated when the conditional statement is reached. The result of the evaluation is a boolean value. Above, no evaluation was done. Instead a boolean value was explicitly used in the conditional statement. + + + + + +The parentheses are followed by a block, which is defined inside an opening- `{` and closing `}` curly bracket. The source code inside the block is executed in the case that the expression placed inside the parentheses evaluates to *true*. + + + +Let's look at an example where we compare numbers in the conditional statement. + + + +```java +int number = 11; +if (number > 10) { + System.out.println("The number was greater than 10"); +} +``` + + + +If the expression in the conditional statement evaluates to true, above "if the number contained in the variable is greater than 10", then the execution of the program progresses to the block defined by the conditional statement. On the other hand, if the expression evaluates to false, then the execution progresses to the statement after the closing curly bracket of the current conditional statement. + + + + NB! An `if` -statement is not followed by a semicolon, since the statement doesn't end after the conditional part. + + + + + + + +Write a program that asks the user for an integer and prints the string "Speeding ticket!" if the number is greater than 120. + + + +Input speed: +**15** + + + + + +Input speed: +**135** +Speeding ticket! + + + + + + + +## Code indentation and block statements + + + +Blocks is a term used to describe a section enclosed by a pair of curly brackets. The source file containing the program includes the string `public class`, which is followed by the name of the program and the opening curly bracket of the block. The block ends in a closing curly bracket. In the picture below the program block is highlighted. + +![An example of a block](../img/lohkoesimerkki-1.png) + + + +The recurring snippet `public static void main(String[] args)` in the programs starts its own block, and the source code within this block is executed when the program is run -- technically the snippet is the starting point of all programs. In the code above we actually have two blocks, as we can see from the picture below. + +![](../img/lohkoesimerkki-2.png) + + + +Blocks define structure in the program and constrain the program. There needs to always be a matching pair for a curly bracket: code missing a closing (or opening) curly bracket is invalid. + + + +A conditional statement also starts a new block. + + + +In addition to the definition of program structure and functionality blocks statements also factor into the readability of the program. The code inside a block is indented. For example, source code inside the block of a conditional statement is indented four spaces deeper than the `if`-command that started the conditional statement. Four spaces can also be achieved by using a tab character (the key to the left of 'q'). When the block is closed, aka we encounter a `}`-character, the indentation stops. The `}`-character is at the same level of indentation as the `if`-command that started the conditional statement. + + + +The example below is incorrectly indented. + + +```java +if (number > 10) { +number = 9; +} +``` + + + +The example below has the correct indentation. + + +```java +if (number > 10) { + number = 9; +} +``` + + + + + + +In the Java language code is indented by four spaces or a single tab at each block. Use either spaces or tabs for indentation, not both. In some cases the indentation might break if you use both at the same time. NetBeans can assist you in this matter by pressing the key combination "alt + shift + f" (macOS "control + shift + f"). + + + +In the future the code of the program needs to be indented correctly when submitting exercises. If the indentation is wrong, then the development environment does not accept the exercise solution. + + + + + + + +The exercise template contains a program demonstrating the use of conditional statements. However, the indentation is wrong. + + +Try to run the tests before doing anything. TMC shows the indentation errors differently compared to errors in program logic. + + +When you notice how indentation errors are shown, correct them. Now would be a good time to try out the automatic code indentation. + + + + + +## Comparison operators + + + + +* `>`greater than +* `>=`greater than or equal to +* `<`less than +* `<=` less than or equal to +* `==` equal to +* `!=` not equal to + + + +```java +int number = 55; + +if (number != 0) { + System.out.println("The number is not equal to 0"); +} + +if (number >= 1000) { + System.out.println("The number is at least 1000"); +} +``` + + + + +The number was not equal to 0 + + + + + + +Write a program, that prompts the user for an integer and prints the string "Orwell" if the number is exactly 1984. + + + +Give a number: +**1983** + + + + + +Give a number: +**1984** +Orwell + + + + + + + + + + +Write a program, that prompts the user for a year. If the user inputs a number that is smaller than 2015, then the program prints the string "Old!". + + + +Give a year: +**2017** + + + + + +Give a year: +**2013** +Old! + + + + + + + +## Else + + + +If the expression inside the parentheses of the conditional statement evaluates to false, then the execution of the code moves to the statement following the closing curly bracket of the current conditional statement. This is not always desired, and usually we want to create an alternative action for the case when the expression is false. + + + +This can be done with the help of the `else`-command, which is used along with the `if`-command. + + + +```java +int number = 4; + +if (number > 5) { + System.out.println("Your number is greater than five!"); +} else { + System.out.println("Your number is five or less!"); +} +``` + + + +Your number is five or less! + + + + + +If we have defined an `else`-branch for the conditional statement, then the block defined by the else-branch is run if the condition of the conditional statement is not true. The `else`-command is placed on the same line as the closing bracket of the block defined by the `if`-command. + + + + + +Write a program, that prompts the user for an integer and informs the user whether or not it is positive (greater than zero). + + + +Give a number: +**5** +The number is positive. + + + + + +Give a number: +**-2** +The number is not positive. + + + + + + + + + + +Write a program, which prompts the user for their age and tells them whether or not they are of legal age (18 years old or older). + + + +How old are you? +**12** +You are not of legal age! + + + + + +How old are you? +**32** +You are of legal age! + + + + + + + +## More alternatives: else if + + + +If there are multiple alternatives we use the `else if`-command. The command `else if` is like `else`, but with an additional condition. `else if` comes after the `if`-condition, and there can be multiple. + + +```java +int number = 3; + +if (number == 1) { + System.out.println("The number is one"); +} else if (number == 2) { + System.out.println("The given number is two"); +} else if (number == 3) { + System.out.println("The number must be three!"); +} else { + System.out.println("Something else!"); +} +``` + + + +The number must be three! + + + + + +Let's read out the example above: 'If the number is one, then print "The number is one", else if the number is two, then print "The given number is two", else if the number is three, then print "The number must be three!". Otherwise, print "Something else!"' + + +The visualization of the code above: + + + + + + + + + +Write a program, that prompts the user for two integers and prints the greater of the two. If the numbers are the same, then the program informs us about this as well. + + +Sample outputs: + + + +Give the first number: +**5** +Give the second number: +**3** +The greater number: 5 + + + + + +Give the first number: +**5** +Give the second number: +**8** +The greater number: 8 + + + + + +Give the first number; **5** +Give the second number: **5** +The numbers are equal! + + + + + + + +## Order of execution for comparisons + + + +The comparisons are executed top down. When execution reaches a conditional statement, for which its condition is true, its block is executed and the comparing stops. + + + +```java +int number = 5; + +if (number == 0) { + System.out.println("The number is zero."); +} else if (number > 0) { + System.out.println("The number is greater than zero."); +} else if (number > 2) { + System.out.println("The number is greater than two."); +} else { + System.out.println("The number is less than zero."); +} +``` + + + +The number is greater than zero. + + + + + +The example above prints the string "The number is greater than zero." even if the condition `number > 2` is true. The comparing stops at the first condition that evaluates to true. + + + + + + +The table seen below describes how the grade for a particular course is determined. Write a program, that gives a course grade according to the provided table. + + + + + + + + + + + + +| points | grade | +| ------------ | -------- | +| < 0 | impossible! | +| 0-49 | failed | +| 50-59 | 1 | +| 60-69 | 2 | +| 70-79 | 3 | +| 80-89 | 4 | +| 90-100 | 5 | +| > 100 | incredible! | + + +Sample outputs: + + + +Give points [0-100]: +**37** +Grade: failed + + + + + +Give points [0-100]: +**76** +Grade: 3 + + + + + +Give points [0-100]: +**95** +Grade: 5 + + + + + +Give points [0-100]: +**-3** +Grade: incredible! + + + + + + + + +## The expression of a conditional statement and the boolean variable + + + +After evaluation, the value of the expression placed inside the parentheses of the conditional statement should be of the boolean type. Variables of the `boolean` type get the value _true_ or _false_. + + + +```java +boolean isItTrue = true; +System.out.println("The value of the boolean variable is " + isItTrue); +``` + + + +The value of the boolean variable is true + + + +The conditional statement can also be done as follows: + + +```java +boolean isItTrue = true; +if (isItTrue) { + System.out.println("Pretty wild!"); +} +``` + + + +Pretty wild! + + + + +Comparison operators can also be used outside of conditions. In that case the resulting boolean value of the comparison is stored in a boolean variable for later use. + + + +```java +int first = 1; +int second = 3; +boolean isItGreater = first > second; +``` + + + +In the example above the boolean variable `isItGreater` now contains the boolean value _false_. We can extend the previous example by adding a conditional statement to it. + + + +```java +int first = 1; +int second = 3; +boolean isItLessThan = first < second; + +if (isItLessThan) { + System.out.println("1 is less than 3!"); +} +``` + +![](../img/drawings/boolean-muuttuja.png) + + + +The code in the image above has been executing for an amount of time, where the variables of the program have been initialized and given values. The variable `isItLessThan` has `true` as its value. Next in the execution is the comparison `if (isItLessThan)` -- the value for the variable `isItLessThan` is found in its container, and finally the program prints: + + + +1 is less than 3! + + + + + + + + + +The modulo operator is a less commonly used operator. However, it is very handy when we want to check the divisibility of a number. The symbol for the modulo operator is `%`. + + + +```java +int remainder = 7 % 2; +System.out.println(remainder); // prints 1 +System.out.println(5 % 3); // prints 2 +System.out.println(7 % 4); // prints 3 +System.out.println(8 % 4); // prints 0 +System.out.println(1 % 2); // prints 1 +``` + + + +If we want to know if the number given by the user is divisible by four hundred, then we check if the remainder is zero after taking the modulo of the number and four hundred. + + + +```java +Scanner reader = new Scanner(System.in); + +int number = Integer.valueOf(reader.nextLine()); +int remainder = number % 400; + +if (remainder == 0) { + System.out.println("The number " + number + " is divisible by four hundred."); +} else { + System.out.println("The number " + number + " is not divisible by four hundred."); +} +``` + + + +Because taking the remainder is an operation just like other computations, it can be placed as part of the expression in a conditional statement. + + + +```java +Scanner reader = new Scanner(System.in); + +int number = Integer.valueOf(reader.nextLine()); + +if (number % 400 == 0) { + System.out.println("The number " + number + " is divisible by four hundred."); +} else { + System.out.println("The number " + number + " is not divisible by four hundred."); +} +``` + + + + + + + + +Write a program, that prompts the user for a number and informs us whether it is even or odd. + + + +Give a number: +**2** +The number 2 is even. + + + + + +Give a number: +**7** +The number 7 is odd. + + + + + +Hint: The remainder when dividing by 2 tells us whether the number is even or not. We get the remainder using the `%`-operator. The exercise template contains additional instructions on how to do the checking using the remainder. + + + + +## Conditional statements and comparing strings + + + +Even though we can compare integers, floating point numbers, and boolean values using two equals signs (`variable1 == variable2`), we cannot compare the equality of strings using two equals signs. + + +You can try this with the following program: + + + +```java +Scanner reader = new Scanner(System.in); + +System.out.println("Enter the first string"); +String first = reader.nextLine(); +System.out.println("Enter the second string"); +String second = reader.nextLine(); + +if (first == second) { + System.out.println("The strings were the same!"); +} else { + System.out.println("The strings were different!"); +} +``` + + + +Enter the first string +**same** +Enter the second string +**same** +The strings were different! + + + + + +Enter the first string +**same** +Enter the second string +**different** +The strings were different! + + + + + +This is related to the internal workings of strings as well as how the comparison of variables is implemented in Java. In practice, the operation of the comparison is affected by how much data a variable can contain -- strings can contain a limitless amount of characters, whereas integers, floating point numbers, and boolean values only contain a single number or value. Variables that always contain only one number or value can be compared using an equals sign, while it does not work for variables containing more data. We will get back to this topic later in this course. + + +When comparing strings we use the `equals`-command, which is part of the functionality related to string variables. The command works in the following way: + + + + + +```java +Scanner reader = new Scanner(System.in); + +System.out.println("Enter a string"); +String input = reader.nextLine(); + +if (input.equals("a string")) { + System.out.println("Great! You read the instructions correctly."); +} else { + System.out.println("Missed the mark!"); +} +``` + + + +Enter a string +**ok!** +Missed the mark! + + + + + +Enter a string +**a string** +Great! You read the instructions correctly. + + + + + + +The equals-command is placed after the string variable by attaching it with a dot to the variable we want to compare. The command is given a parameter, which is the string that the variable will be compared against. If the string variable is being directly compared with a string, then the string can be placed inside the parentheses of the equals-command surrounded by quotation marks. Otherwise, the name of the string variable, which is to be compared with the string contained in the string variable, is placed inside the parentheses. + + + +In the example below the user is prompted for two strings. First, we check if the given strings are the same, after which we will check if the value for either of the given strings is "two strings". + + + +```java +Scanner reader = new Scanner(System.in); + +System.out.println("Input two strings"); +String first = lukija.nextLine(); +String second = lukija.nextLine(); + +if (first.equals(second)) { + System.out.println("The strings were the same!"); +} else { + System.out.println("The strings were different!"); +} + +if (first.equals("two strings")) { + System.out.println("Clever!"); +} + +if (second.equals("two strings")) { + System.out.println("Sneaky!"); +} +``` + + + +Input two strings +**hello** +**world** +The strings were different! + + + + + +Input two strings +**two strings** +**world** +The strings were different! +Clever! + + + + + +Input two strings +**same** +**same** +The strings were the same! + + + + + + + + + +Write a program, that prompts the user for a password. If the password is "Caput Draconis", then the program prints "Welcome!". Otherwise the program prints "Off with you!" + + + +Password? +**Wattlebird** +Off with you! + + + + + +Password? +**Caput Draconis** +Welcome! + + + + + + + + + + + +Write a program, that prompts the user for two strings. If the strings are the same, then the program prints "Same", otherwise it prints "Never mind". + + + + + +Enter the first string: +**hello** +Enter the second string: +**hello** +Same + + + + + +Enter the first string: +**hello** +Enter the second string: +**world** +Never mind + + + + + + + +## Logical operators + + +The expression of a conditional statement may consist of multiple parts, in which the logical operators **and** `&&`, **or** `||`, and **not** `!` are used. + +* An expression consisting of two expressions combined using the and-operator is true, if and only if both of the combined expressions evaluate to true. + +* An expression consisting of two expressions combined using the or-operator is true if either one, or both, of the combined expressions evaluate to true. + +* Logical operators are not used for changing the boolean value from true to false, or false to true. + + + +In the next example we combine two individual conditions using `&&`, aka the and-operator. The code is used to check if the number in the variable is greater than 4 and less than 11. In other words, within the range 5-10: + + + +```java +System.out.println("Is the number within the range 5-10: "); +int number = 7; + +if (number >= 4 && number <= 10) { + System.out.println("It is! :)"); +} else { + System.out.println("It is not :(") +} +``` + + + +Is the number within the range 5-10: +It is! :) + + + + + +In the next one we provide two conditions using `||`, aka the or-operator: is the number less than zero or greater than 100. The condition is fulfilled if the number fulfills either of the two conditions: + + + +```java +System.out.println("Is the number less than 0 or greater than 100"); +int number = 145; + +if (number < 0 || number > 100) { + System.out.println("It is! :)"); +} else { + System.out.println("It is not :(") +} +``` + + + +Is the number less than 0 or greater than 100 +It is! :) + + + + + + +In this example we flip the result of the expression `number > 4` using `!`, aka the not-operator. The not-operator is notated such that the expression to be flipped is surrounded by parentheses, and the not-operator is placed before the parentheses. + + + +```java +int number = 7; + +if (!(number > 4)) { + System.out.println("The number is not greater than 4."); +} else { + System.out.println("The number is greater than or equal to 4.") +} +``` + + + +The number is greater than or equal to 4. + + + + +Below is a table showing the operation of expressions containing logical operators. + +| number | number > 0 | number < 10 | number > 0 && number < 10 | !(number > 0 && number < 10) | number > 0 \|\| number < 10 | +| ----- | ----------- | ------------ | -------------------------- | ----------------------------- | ---------------------------- | +| -1 | false | true | false | true | true | +| 0 | false | true | false | true | true | +| 1 | true | true | true | false | true | +| 9 | true | true | true | false | true | +| 10 | true | false | false | true | true | + + + + + + + +Write a program that prompts the user to input their age and checks whether or not it is possible (at least 0 and at most 120). Only use a single `if`-command in your program. + + + +How old are you? **10** +OK + + + + + +How old are you? **55** +OK + + + + + +How old are you? **-3** +Impossible! + + + + + +How old are you? **150** +Impossible! + + + + + +TODO: quiz -- mitä tulostaa? (useampi osa) + + +## Execution order of conditional statements + + +Let's familiarize ourselves with the execution order of conditional statements through a classic programming exercise. + + + +_'Write a program that prompts the user for a number between one and one hundred, and prints that number. If the number is divisible by three, then print "Fizz" instead of the number. If the number is divisible by five, then print "Buzz" instead of the number. If the number is divisible by both three and five, then print "FizzBuzz" instead of the number.'_ + + + +The programmer begins solving the exercise by reading the exercise description, and by writing code according to the description. The conditions for execution are presented in a given order by the description, and the initial structure for the program is formed based on that order. The structure is formed based on the following steps: + + +* Write a program that prompts the user for a number and prints that number. + +* If the number is divisible by three, then print "Fizz" instead of the number. + +* If the number is divisible by five, then print "Buzz" instead of the number. + +* If the number is divisible by both three and five, then print "FizzBuzz" instead of the number. + + + +If-type conditions are easy to implement using `if - else if - else` -conditional statements. The code below was written based on the steps above, but it does not work correctly, which we can see from the example. + + + +```java +Scanner reader = new Scanner(System.in); + +int number = Integer.valueOf(reader.nextLine()); + +if (number % 3 == 0) { + System.out.println("Fizz"); +} else if (number % 5 == 0) { + System.out.println("Buzz"); +} else if (number % 3 == 0 && number % 5 == 0) { + System.out.println("FizzBuzz"); +} else { + System.out.println(number); +} +``` + + + +**3** +Fizz + + + + + + +**4** +4 + + + + + +**5** +Buzz + + + + + +**15** +Fizz + + + + + +The problem with the previous approach is that **the parsing of conditional statements stops at the first condition that is true**. E.g. for the number 15 the prints the string "Fizz", because the number is divisible by three (15 % 3 == 0). + + + +One approach for developing the above train of thought is to first find the **most demanding condition** and implement it. The other conditions would be implemented after it. In the example above, the condition "if the number is divisible by both three **and** five" requires two conditions to be met. Now the train of thought would be: + + +1. Write a program that reads input from the user. + +2. If the number is divisible by both three and five, then print "FizzBuzz" instead of the number. + +3. If the number is divisible by three, then print "Fizz" instead of the number. + +4. If the number is divisible by five, then print "Buzz" instead of the number. + +5. Otherwise the program prints the number given by the user. + + + +Now the problem seems to be solved. + + + +```java +Scanner reader = new Scanner(System.in); + +int number = Integer.valueOf(reader.nextLine()); + +if (number % 3 == 0 && number % 5 == 0) { + System.out.println("FizzBuzz"); +} else if (number % 3 == 0) { + System.out.println("Fizz"); +} else if (number % 5 == 0) { + System.out.println("Buzz"); +} else { + System.out.println(number); +} +``` + + + +**2** +2 + + + + + +**5** +Buzz + + + + + +**30** +FizzBuzz + + + + + + + + + +A year is a leap year if it is divisible by 4. However, if the year is divisible by 100, then it is a leap year only when it is also divisible by 400. + + +Write a program that reads a year from the user, and checks whether or not it is a leap year. + + + +Input a year: **2011** +The year is not a leap year. + + + + + +Input a year: **2012** +The year is a leap year. + + + + + +Input a year: **1800** +The year is not a leap year. + + + + + +Input a year: **2000** +The year is a leap year. + + + + +Hint 1: The divisibility by a particular number can be checked using the modulo operator, aka `%`, in the following way. + + + +```java +int number = 5; + +if (number % 5 == 0) { + System.out.println("The number is divisible by five!"); +} + +if (number % 6 != 0) { + System.out.println("The number is not divisible by six!") +} +``` + + + +The number is divisible by five! +The number is not divisible by six! + + + + + + +Hint 2: Think of the problem as a chain of if, else if, else if, ... -comparisons and start building the program from a case where you can be certain that the year is not a leap year. + + + +```java +Scanner reader = new Scanner(System.in); +int number = Integer.valueOf(reader.nextLine()); + +if (number % 4 != 0) { + System.out.println("The year is not a leap year."); +} else if (...) { + ... +} ... +``` + + + + + + + +[https://www.vero.fi/henkiloasiakkaat/omaisuus/lahja/](https://www.vero.fi/henkiloasiakkaat/omaisuus/lahja/): *Lahja tarkoittaa sitä, että omaisuus siirtyy toiselle henkilölle ilman korvausta. Lahjasta pitää maksaa lahjaveroa, jos samalta lahjanantajalta saatujen lahjojen arvo on kolmen vuoden aikana 5 000 euroa tai enemmän.* + +Kun lahja tulee lähimmiltä sukulaisilta, lahjaveron määrä määräytyy seuraavan taulukon mukaan (lähde [vero.fi](https://www.vero.fi/henkiloasiakkaat/omaisuus/lahja/lahjaverolaskuri/#lahjaverotaulukot)): + +| Lahja | Vero alarajalla | Veroprosentti ylimenevästä | +|-----------------------|------------------|-----------------------------| +| 5 000 -- 25 000 | 100 | 8 | +| 25 000 -- 55 000 | 1 700 | 10 | +| 55 000 -- 200 000 | 4 700 | 12 | +| 200 000 -- 1 000 000 | 22 100 | 15 | +| 1 000 000 -- | 142 100 | 17 | + +Esimerkiksi 6000 euron lahjasta tulee maksaa veroa 180 euroa (100 + (6000-5000) * 0.08), ja 75000 euron lahjasta tulee maksaa veroa 7100 euroa (4700 + (75000-55000) * 0.12). + +Tee ohjelma, joka laskee lahjaveron lähimmiltä sukulaisilta annetulle lahjalle. Alla on muutama esimerkki ohjelman toiminnasta. + + + +Lahjan suuruus? +**3500** +Ei veroa! + + + + + + +Lahjan suuruus? +**5000** +Vero: 100.0 + + + + + +Lahjan suuruus? +**27500** +Vero: 1950.0 + + + + + + diff --git a/data/osa-1/6-ehtolauseet.md b/data/osa-1/6-ehtolauseet.md deleted file mode 100644 index 7e303b81b..000000000 --- a/data/osa-1/6-ehtolauseet.md +++ /dev/null @@ -1,1071 +0,0 @@ ---- -path: "/osa-1/6-ehtolauseet" -title: "Ehtolauseet ja vaihtoehtoinen toiminta" ---- - - - -- Tunnet käsitteen ehtolause ja osaat luoda ohjelmaan vaihtoehtoista toimintaa ehtolauseen avulla. -- Tunnet ehtolauseissa tyypillisesti käytettävät vertailuoperaattorit ja loogiset operaatiot. -- Osaat vertailla sekä lukuja että merkkijonoja, muistaen merkkijonoihin liittyvän equals-komennon. -- Tunnet ehtolauseen suoritusjärjestyksen ja tiedät, että ehtolauseiden läpikäynti lopetetaan ensimmäiseen ehtoon, jonka lauseke evaluoituu todeksi. - - - - -Ohjelmamme ovat tähän mennessä olleet lineaarisia eli ohjelmien suoritus on tapahtunut ylhäältä alaspäin ilman suuria yllätyksiä tai vaihtoehtoja. Ohjelmiin halutaan kuitenkin usein vaihtoehtoista toiminnallisuutta, eli toiminnallisuutta joka riippuu tavalla tai toisella ohjelmassa olevien muuttujien tilasta. - -Jotta ohjelman suoritus voisi _haarautua_ esimerkiksi käyttäjän antaman syötteen perusteella, tarvitsemme käyttöömme **ehtolauseen**. Yksinkertaisin ehtolause on seuraavanlainen. - -```java -System.out.println("Hei maailma!"); -if (true) { - System.out.println("Et voi välttää tätä koodia!"); -} -``` - - - -Hei maailma! -Et voi välttää tätä koodia! - - - -Ehtolause alkaa avainsanalla `if`, jota seuraa sulut. Sulkujen sisälle asetetaan lauseke, joka evaluoidaan kun ehtolause saavutetaan. Evaluoinnin tulos on totuusarvo, yllä evaluointia ei tehty, vaan ehtolauseessa käytettiin suoraan totuusarvoa. - -Sulkuja seuraa lohko, joka määritellään avaavan aaltosulun `{` ja sulkevan aaltosulun `}` sisään. Lohkon sisällä oleva lähdekoodi mikäli sulkujen sisälle asetettu lauseke evaluoidaan todeksi (true). - -Tarkastellaan esimerkkiä, missä ehtolauseen lausekkeessa vertaillaan lukuja. - -```java -int luku = 11; -if (luku > 10) { - System.out.println("Luku oli suurempi kuin 10"); -} -``` - -Jos ehtolauseen lauseke evaluoidaan todeksi, yllä "jos muuttujassa luku oleva arvo on suurempi kuin 10", ohjelman suoritus siirtyy ehtolauseen määrittelemään lohkoon. Jos taas lauseke on epätotta, ohjelman suoritus siirtyy ehtolauseeseen liittyvän lohkon päättävän aaltosulun jälkeiseen lauseeseen. - -Huomaa, että `if` -lauseen perään ei tule puolipistettä, sillä lause ei lopu ehto-osan jälkeen. - - - -Tee ohjelma, joka kysyy käyttäjältä kokonaisluvun ja tulostaa merkkijonon "Ylinopeussakko!" jos luku on suurempi kuin 120. - - - -Kerro nopeus: -**15** - - - - - -Kerro nopeus: -**135** -Ylinopeussakko! - - - - - - -## Ohjelmakoodin sisennyksestä ja lohkoista - -Lohkolla tarkoitetaan aaltosulkujen rajaamaa aluetta. Ohjelman sisältävä lähdekooditiedosto sisältää merkkijonon `public class`, jota seuraa ohjelman nimi ja lohkon avaava aaltosulku. Lohko päättyy sulkevaan aaltosulkuun. Alla olevassa kuvassa on näytettynä värjättynä ohjelman lohko. - -![Esimerkki lohkoista](../img/lohkoesimerkki-1.png) - -Ohjelmissa toistuva rimpsu `public static void main(String[] args)` aloittaa oman lohkon, jonka sisällä oleva lähdekoodi suoritetaan kun ohjelma käynnistetään -- rimpsu on oikeastaan jokaisen ohjelman aloituskohta. Yllä olevassa esimerkissä on todellisuudessa kaksi lohkoa, kuten alla olevasta kuvasta huomaamme. - -![](../img/lohkoesimerkki-2.png) - -Lohkot määrittelevät ohjelman rakennetta ja rajaavat ohjelmaa. Aaltosuluille tulee aina löytyä pari: koodi, josta josta puuttuu lohkon päättävä (tai aloittava) aaltosulku, on virheellinen. - -Myös ehtolause aloittaa lohkon. - -Lohkoihin liittyy ohjelman rakenteen ja toiminnan määrittelyn lisäksi luettavuuteen liittyvä seikka. Lohkojen sisällä oleva koodi sisennetään. Esimerkiksi ehtolauseeseen liittyvän lohkon sisältämä lähdekoodi sisennetään neljä välilyöntiä sisemmälle kuin ehtolauseen aloittava `if`-komento. Neljä merkkiä saa myös tabulaattorimerkillä (q:n vasemmalla puolella oleva näppäin). Kun lohko sulkeutuu, eli tulee `}`-merkki, sisennys loppuu. `}`-merkki on samalla tasolla kuin ehtolauseen aloittanut `if`-komento. - -Alla oleva esimerkki on sisennetty väärin. - -```java -if (luku > 10) { -luku = 9; -} -``` - -Alla oleva esimerkki on sisennetty oikein. - -```java -if (luku > 10) { - luku = 9; -} -``` - - - -Javassa koodia sisennetään neljän välilyönnin tai yhden tabulaattorin verran jokaisen lohkon kohdalla. Käytä sisentämiseen joko välilyöntejä tai tabulaattoreita. Joissakin tapauksissa sisennys saattaa hajota mikäli käytät molempia. NetBeans auttaa tässä kun painat kirjainyhdistelmää "alt + shift + f" (macOS "control + shift + f"). - -Jatkossa ohjelmakoodi tulee sisentää oikein myös tehtävissä. Jos sisennys on väärin, ei ohjelmointiympäristö hyväksy tehtävää. - - - - - -Tehtäväpohjassa on ehtolauseen käyttöä demonstroiva ohjelma. Ohjelma on kuitenkin sisennetty väärin. - -Kokeile ajaa testit ennen kuin teet mitään. TMC näyttää sisennysvirheet eri lailla kuin ohjelmalogiikassa olevat virheet. - -Kun huomaat, miten sisennysvirheet merkitään, korjaa virheet. Opettele käyttämään automaattista ohjelmakoodin sisentämistä jo nyt. - - - - - -## Vertailuoperaattorit - -Vertailuoperaattoreita ovat seuraavat: - -* `>`suurempi kuin -* `>=`suurempi tai yhtä suuri kuin -* `<`pienempi kuin -* `<=` pienempi tai yhtä suuri kuin -* `==` yhtä suuri kuin -* `!=` erisuuri kuin - -```java -int luku = 55; - -if (luku != 0) { - System.out.println("Luku oli erisuuri kuin 0"); -} - -if (luku >= 1000) { - System.out.println("Luku oli vähintään 1000"); -} -``` - - - -Luku oli erisuuri kuin 0 - - - - - -Tee ohjelma, joka kysyy käyttäjältä kokonaisluvun ja tulostaa merkkijonon "Orwell" jos luku on täsmälleen 1984. - - - -Anna luku: -**1983** - - - - - -Anna luku: -**1984** -Orwell - - - - - - - - -Tee ohjelma, joka kysyy käyttäjältä vuosilukua. Jos käyttäjä syöttää luvun, joka on pienempi kuin 2015, ohjelma tulostaa merkkijonon "Wanha!". - - - -Anna vuosiluku: -**2017** - - - - - -Anna vuosiluku: -**2013** -Wanha! - - - - - - -## Muulloin eli else - -Jos ehtolauseen sulkujen sisällä oleva lauseke evaluoituu epätodeksi, ohjelmakoodin suoritus siirtyy ehtolauseen lohkon lopettavan aaltosulun seuraavaan lauseeseen. Tämä ei aina ole toivottua, vaan usein halutaan luoda vaihtoehtoinen toiminta tilanteeseen, missä ehtolauseen lauseke on epätotta. - -Tämä onnistuu `if`-komennon yhteydessä käytettävän `else`-komennon avulla. - -```java -int luku = 4; - -if (luku > 5) { - System.out.println("Lukusi on suurempi kuin viisi!"); -} else { - System.out.println("Lukusi on viisi tai alle!"); -} -``` - - - -Lukusi on viisi tai alle! - - - -Jos ehtolauseeseen on määritelty `else`-haara, suoritetaan else-haaran määrittelemä lohko jos ehtolauseen ehto ei ole totta. Komento `else` tulee samalle riville `if`-komennon määrittelemän lohkon lopettavan aaltosulun kanssa. - - - - -Tee ohjelma, joka kysyy käyttäjältä kokonaisluvun ja kertoo, onko se positiivinen (eli suurempi kuin nolla) vai ei. - - - -Anna luku: -**5** -Luku on positiivinen. - - - - - -Anna luku: -**-2** -Luku ei ole positiivinen. - - - - - - - - -Tee ohjelma, joka kysyy käyttäjän ikää ja kertoo, onko tämä täysi-ikäinen (eli 18-vuotias tai vanhempi). - - - -Kuinka vanha olet? -**12** -Et ole täysi-ikäinen! - - - - - -Kuinka vanha olet? -**32** -Olet täysi-ikäinen! - - - - - - -## Lisää vaihtoehtoja: else if - -Jos vaihtoehtoja on useampia käytetään `else if`-komentoa. Komento `else if` on kuin `else`, mutta lisäehdolla. `else if` tulee `if`-ehdon jälkeen, ja niitä voi olla useita. - -```java -int luku = 3; - -if (luku == 1) { - System.out.println("Luku on yksi"); -} else if (luku == 2) { - System.out.println("Lukuna on kaksi"); -} else if (luku == 3) { - System.out.println("Kolme lienee lukuna!"); -} else { - System.out.println("Jotain muuta!"); -} -``` - - - -Kolme lienee lukuna! - - - -Luetaan yllä oleva esimerkki: 'Jos luku on yksi, tulosta "Luku on yksi", muuten jos luku on kaksi, tulosta "Lukuna on kaksi", muuten jos lukuna on kolme, tulosta "Kolme lienee lukuna!". Muulloin, tulosta "Jotain muuta!"'. - -Yllä olevan ohjelman askeleittainen visualisointi: - - - - - - -Tee ohjelma, joka kysyy käyttäjältä kaksi kokonaislukua ja tulostaa niistä suuremman. Jos luvut ovat yhtä suuret, ohjelma huomaa myös tämän. - -Esimerkkitulostuksia: - - - -Anna ensimmäinen luku: -**5** -Anna toinen luku: -**3** -Suurempi luku: 5 - - - - - -Anna ensimmäinen luku: -**5** -Anna toinen luku: -**8** -Suurempi luku: 8 - - - - - -Anna ensimmäinen luku: **5** -Anna toinen luku: **5** -Luvut ovat yhtä suuret! - - - - - - -## Vertailujen suoritusjärjestys - -Vertailut suoritetaan järjestyksessä ylhäältä alaspäin. Kun suorituksessa päästään ehtolauseeseen, jonka ehto on totta, suoritetaan lohko ja lopetetaan vertailu. - -```java -int luku = 5; - -if (luku == 0) { - System.out.println("Luku on nolla."); -} else if (luku > 0) { - System.out.println("Luku on suurempi kuin nolla."); -} else if (luku > 2) { - System.out.println("Luku on suurempi kuin kaksi."); -} else { - System.out.println("Luku on pienempi kuin nolla."); -} -``` - - - -Luku on suurempi kuin nolla. - - - -Yllä oleva esimerkki tulostaa merkkijonon "Luku on suurempi kuin nolla." vaikka myös ehto `luku > 2` on totta. Vertailu lopetetaan ensimmäiseen valintakäskyyn, jonka ehto on totta. - - - - -Alla oleva taulukko kuvaa erään kurssin arvosanan muodostumista. Tee ohjelma, joka ilmoittaa kurssiarvosanan annetun taulukon mukaisesti. - -| pistemäärä | arvosana | -| ------------ | -------- | -| < 0 | mahdotonta! | -| 0-49 | hylätty | -| 50-59 | 1 | -| 60-69 | 2 | -| 70-79 | 3 | -| 80-89 | 4 | -| 90-100 | 5 | -| > 100 | uskomatonta! | - -Esimerkkitulostuksia: - - - -Anna pisteet [0-100]: -**37** -Arvosana: hylätty - - - - - -Anna pisteet [0-100]: -**76** -Arvosana: 3 - - - - - -Anna pisteet [0-100]: -**95** -Arvosana: 5 - - - - - -Anna pisteet [0-100]: -**-3** -Arvosana: mahdotonta! - - - - - - - -## Ehtolauseen lauseke ja totuusarvomuuttuja - -Ehtolauseen sulkuihin asetettavan arvon tulee olla lausekkeen evaluoinnin jälkeen totuusarvotyyppinen. Totuusarvomuuttujan tyyppi on `boolean` ja arvo _true_ tai _false_. - -```java -boolean onkoTotta = true; -System.out.println("Totuusarvomuuttujan arvo on " + onkoTotta); -``` - - - -Totuusarvomuuttujan arvo on true - - - -Ehtolauseen voi suorittaa myös seuraavasti: - -```java -boolean onkoTotta = true; -if (onkoTotta) { - System.out.println("Aika vinhaa!"); -} -``` - - - -Aika vinhaa! - - - -Vertailuoperaattoreita voi käyttää myös ehtojen ulkopuolella. Tällöin vertailun tuloksena saatu totuusarvo asetetaan talteen totuusarvomuuttujaan myöhempää käyttöä varten. - -```java -int eka = 1; -int toka = 3; -boolean onkoSuurempi = eka > toka; -``` - -Yllä olevassa esimerkissä totuusarvomuuttuja `onkoSuurempi` sisältää nyt totuusarvon _false_. Yllä olevaa esimerkkiä voi myös jatkaa ja ottaa siihen mukaan ehtolauseen. - -```java -int eka = 1; -int toka = 3; -boolean onkoPienempi = eka < toka; - -if (onkoPienempi) { - System.out.println("1 on pienempi kuin 3!"); -} -``` - -![](../img/drawings/boolean-muuttuja.png) - -Yllä olevassa kuvassa ohjelmakoodia on suoritettu niin pitkään, että ohjelman muuttujat on luotu ja niihin on asetettu arvot. Muuttujassa `onkoPienempi` on arvona `true`. Seuraavana suoritetaan vertailu `if (onkoPienempi)` -- muuttujaan `onkoPienempi` liittyvä arvo löytyy sen lokerosta, ja lopulta ohjelma tulostaa: - - - -1 on pienempi kuin 3! - - - - - - -Jakojäännös on hieman harvemmin käytetty operaatio, joka on kuitenkin varsin näppärä kun halutaan tarkistaa esimerkiksi luvun jaollisuutta. Jakojäännösoperaation merkki on `%`. - -```java -int jakojaannos = 7 % 2; -System.out.println(jakojaannos); // tulostaa 1 -System.out.println(5 % 3); // tulostaa 2 -System.out.println(7 % 4); // tulostaa 3 -System.out.println(8 % 4); // tulostaa 0 -System.out.println(1 % 2); // tulostaa 1 -``` - -Jos haluamme tietää onko käyttäjän syöttämä luku jaollinen neljälläsadalla, tarkastamme onko syötetyn luvun jakojäännös neljänsadan suhteen nolla. - -```java -Scanner lukija = new Scanner(System.in); - -int luku = Integer.valueOf(lukija.nextLine()); -int jakojaannos = luku % 400; - -if (jakojaannos == 0) { - System.out.println("Luku " + luku + " on jaollinen neljälläsadalla."); -} else { - System.out.println("Luku " + luku + " ei ole jaollinen neljälläsadalla."); -} -``` - -Koska jakojäännös on samanlainen operaatio kuin muutkin laskut, voi sen asettaa osaksi valintakäskyä. - -```java -Scanner lukija = new Scanner(System.in); - -int luku = Integer.valueOf(lukija.nextLine()); - -if (luku % 400 == 0) { - System.out.println("Luku " + luku + " on jaollinen neljälläsadalla."); -} else { - System.out.println("Luku " + luku + " ei ole jaollinen neljälläsadalla."); -} -``` - - - - - - -Tee ohjelma, joka kysyy käyttäjältä luvun ja ilmoittaa, onko syötetty luku parillinen vai pariton. - - - -Anna luku: -**2** -Luku 2 on parillinen. - - - - - -Anna luku: -**7** -Luku 7 on pariton. - - - -Vihje: Luvun jakojäännös 2:lla kertoo, onko luku parillinen vai pariton. Jakojäännös taas saadaan `%`-operaattorilla, tehtäväpohjassa on lisää ohjeita miten parittomuustarkastus hoituu jakojäännöksen avulla. - - - -## Ehtolauseet ja merkkijonojen vertailu - -Siinä missä kokonaislukujen, liukulukujen, ja totuusarvojen samuutta voi verrata kahdella yhtäsuuruusmerkillä (`muuttuja1 == muuttuja2`), ei merkkijonojen samuuden vertailu kahdella yhtäsuuruusmerkillä onnistu. - -Voit kokeilla tätä seuraavalla ohjelmalla: - -```java -Scanner lukija = new Scanner(System.in); - -System.out.println("Syötä ensimmäinen merkkijono"); -String eka = lukija.nextLine(); -System.out.println("Syötä toinen merkkijono"); -String toka = lukija.nextLine(); - -if (eka == toka) { - System.out.println("Merkkijonot olivat samat!"); -} else { - System.out.println("Merkkijonot olivat eri!"); -} -``` - - - -Syötä ensimmäinen merkkijono -**sama** -Syötä toinen merkkijono -**sama** -Merkkijonot olivat eri! - - - - - -Syötä ensimmäinen merkkijono -**sama** -Syötä toinen merkkijono -**eri** -Merkkijonot olivat eri! - - - -Tämä liittyy merkkijonojen sisäiseen toimintaan sekä siihen, miten muuttujien vertailu on Javassa toteutettu. Käytännössä vertailun toimintaan vaikuttaa se, kuinka paljon tietoa muuttuja voi sisältää -- merkkijonot voivat sisältää äärettömän määrän merkkejä, kun taas kokonaisluvut, liukuluvut ja totuusarvot sisältävät aina yhden luvun tai arvon. Muuttujia, jotka sisältävät aina vain yhden luvun tai arvon voi verrata yhtäsuuruusmerkillä, kun taas enemmän tietoa sisältävillä muuttujille tällainen vertailu ei toimi. Palaamme tähän tarkemmin myöhemmin tällä kurssilla. - -Merkkijonojen vertailussa käytetään merkkijonomuuttujiin liittyvää `equals`-komentoa. Komento toimii seuraavalla tavalla: - -```java -Scanner lukija = new Scanner(System.in); - -System.out.println("Syötä merkkijono"); -String syote = lukija.nextLine(); - -if (syote.equals("merkkijono")) { - System.out.println("Luit ohjeet oikein, hyvä!"); -} else { - System.out.println("Metsään meni!"); -} -``` - - - -Syötä merkkijono -**ok!** -Metsään meni! - - - - - -Syötä merkkijono -**merkkijono** -Luit ohjeet oikein, hyvä! - - - -Komento equals kirjoitetaan merkkijonomuuttujan jälkeen siten, että se kiinnitetään pisteellä vertailtavaan muuttujaan. Komennolle annetaan parametrina merkkijono, johon muuttujaa vertaillaan. Mikäli merkkijonomuuttujaa vertaillaan suoraan merkkijonoon, voi merkkijonon asettaa hipsuilla merkittynä equals-komennon sulkujen sisään. Muulloin sulkujen sisään asetetaan sen merkkijonomuuttujan nimi, johon merkkijonomuuttujan sisältämää merkkijonoa verrataan. - -Alla olevassa esimerkissä luetaan käyttäjältä kaksi merkkijonoa. Ensin tarkastetaan ovatko syötetyt merkkijonot samat, jonka jälkeen tarkastetaan onko syötettyjen merkkijonojen arvo "kaksi merkkijonoa". - -```java -Scanner lukija = new Scanner(System.in); - -System.out.println("Syötä kaksi merkkijonoa"); -String eka = lukija.nextLine(); -String toka = lukija.nextLine(); - -if (eka.equals(toka)) { - System.out.println("Merkkijonot olivat samat!"); -} else { - System.out.println("Merkkijonot olivat eri!"); -} - -if (eka.equals("kaksi merkkijonoa")) { - System.out.println("Nokkelaa!"); -} - -if (toka.equals("kaksi merkkijonoa")) { - System.out.println("Ovelaa!"); -} -``` - - - -Syötä kaksi merkkijonoa -**hei** -**maailma** -Merkkijonot olivat eri! - - - - - -Syötä kaksi merkkijonoa -**kaksi merkkijonoa** -**maailma** -Merkkijonot olivat eri! -Nokkelaa! - - - - - -Syötä kaksi merkkijonoa -**samat** -**samat** -Merkkijonot olivat samat! - - - - - - -Tee ohjelma, joka kysyy käyttäjältä tunnussanaa. Mikäli tunnussana on "Caput Draconis", ohjelma tulostaa "Tervetuloa!". Muulloin ohjelman tulostus on "Hus siitä!". - - - -Tunnussana? -**Wattlebird** -Hus siitä! - - - - - -Tunnussana? -**Caput Draconis** -Tervetuloa! - - - - - - - - -Tee ohjelma, joka kysyy käyttäjältä kahta merkkijonoa. Mikäli merkkijonot ovat samat, ohjelma tulostaa "Samat sanat", muulloin ohjelma tulostaa "Ei sitten". - - - -Syötä ensimmäinen merkkijono: -**hei** -Syötä toinen merkkijono: -**hei** -Samat sanat - - - - - -Syötä ensimmäinen merkkijono: -**hei** -Syötä toinen merkkijono: -**maailma** -Ei sitten - - - - - - -## Loogiset operaatiot - - -Ehtolauseen lauseke voi koostua useammasta osasta, joissa käytetään loogisia operaatioita **ja** `&&`, **tai** `||`, sekä **ei** `!`. - -* Kahdesta lausekkeesta koostuva lauseke, joka yhdistetään ja-operaatiolla, on totta jos ja vain jos yhdistettävistä lausekkeista molemmat evaluoituvat todeksi. -* Kahdesta lausekkeesta koostuva lauseke, joka yhdistetään tai-operaatiolla, on totta jos jompikumpi tai molemmat yhdistettävistä lausekkeista evaluoituvat todeksi. -* Loogista operaatiota ei käytetään totuusarvon muuntamiseen truesta falseksi tai falsesta trueksi. - -Seuraavassa yhdistetään `&&`:lla eli ja-operaatiolla kaksi yksittäistä ehtoa. Koodilla tarkistetaan, onko muuttujassa oleva luku suurempi kuin 4 ja pienempi kuin 11, eli siis välillä 5-10: - - -```java -System.out.println("Onkohan luku väliltä 5-10: "); -int luku = 7; - -if (luku >= 4 && luku <= 10) { - System.out.println("On! :)"); -} else { - System.out.println("Ei ollut :(") -} -``` - - - -Onkohan luku väliltä 5-10: -On! :) - - - -Seuraavassa annetaan `||`:n eli tai-operaation avulla kaksi vaihtoehtoa, onko luku pienempi kuin 0 tai suurempi kuin 100. Ehto toteutuu jos luku täyttää jommankumman ehdon: - -```java -System.out.println("Onkohan luku pienempi kuin 0 tai suurempi kuin 100"); -int luku = 145; - -if (luku < 0 || luku > 100) { - System.out.println("On! :)"); -} else { - System.out.println("Ei ollut :(") -} -``` - - - -Onkohan luku pienempi kuin 0 tai suurempi kuin 100 -On! :) - - - - -Seuraavassa käännetään `!` ei-operaatiolla lausekkeen `luku > 4` tulos. Ei-operaatio merkitään lauseketta ennen niin, että käännettävä lauseke rajataan suluilla, ja ei-operaatio lisätään sulkuja ennen. - -```java -int luku = 7; - -if (!(luku > 4)) { - System.out.println("Luku ei ole suurempi kuin 4."); -} else { - System.out.println("Luku on suurempi tai yhtäsuuri kuin 4.") -} -``` - - - -Luku on suurempi tai yhtäsuuri kuin 4. - - - -Alla on kuvattuna lausekkeiden toimintaa kun lausekkeissa on loogisia operaatioita. - - -| luku | luku > 0 | luku < 10 | luku > 0 && luku < 10 | !(luku > 0 && luku < 10) | luku > 0 \|\| luku < 10 | -| ----- | --------- | ---------- | ---------------------- | ------------------------- | ---------------------- | -| -1 | false | true | false | true | true | -| 0 | false | true | false | true | true | -| 1 | true | true | true | false | true | -| 9 | true | true | true | false | true | -| 10 | true | false | false | true | true | - - - - -Tee ohjelma, joka kysyy käyttäjän iän ja tarkistaa, että se on mahdollinen (ainakin 0 ja korkeintaan 120). Käytä ohjelmassa vain yhtä `if`-komentoa. - - - -Kuinka vanha olet? **10** -OK - - - - - -Kuinka vanha olet? **55** -OK - - - - - -Kuinka vanha olet? **-3** -Mahdotonta! - - - - - -Kuinka vanha olet? **150** -Mahdotonta! - - - - - -TODO: quiz -- mitä tulostaa? (useampi osa) - -## Ehtolauseiden suoritusjärjestys - -Tutustutaan ehtolauseiden suoritusjärjestykseen klassisen ohjelmointiongelman kautta. - -_'Kirjoita ohjelma, joka kysyy käyttäjältä lukua yhden ja sadan väliltä ja tulostaa luvun. Jos luku on kolmella jaollinen, luvun sijaan tulostetaan "Fizz". Jos luku on viidellä jaollinen, luvun sijaan tulostetaan "Buzz". Jos luku on sekä kolmella että viidellä jaollinen, luvun sijaan tulostetaan "FizzBuzz"'._ - -Ohjelmoija lähtee ratkaisemaan tehtävää lukemalla ongelmakuvauksen, ja luomalla ohjelmakoodia ongelmakuvausta seuraten. Koska ohjelman suoritusehdot esitellään ongelmassa annetussa järjestyksessä, muodostuu ohjelman rakenne järjestyksen perusteella. Ohjelman rakenne muodostuu seuraavien askelten perusteella: - -* Tee ohjelma, joka lukee luvun käyttäjältä ja tulostaa sen. -* Jos luku on jaollinen kolmella, tulosta luvun sijaan merkkijono "Fizz". -* Jos luku on jaollinen viidellä, tulosta luvun sijaan merkkijono "Buzz". -* Jos luku on jaollinen kolmella ja viidellä, tulosta luvun sijan merkkijono "FizzBuzz". - -Jos-tyyppiset ehdot on helppo toteuttaa `if - else if - else` -valintakäskyjen avulla. Alla oleva koodi on toteutettu yllä olevien askelten perusteella, mutta se ei kuitenkaan toimi oikein, kuten alla olevista esimerkeistä huomataan. - -```java -Scanner lukija = new Scanner(System.in); - -int luku = Integer.valueOf(lukija.nextLine()); - -if (luku % 3 == 0) { - System.out.println("Fizz"); -} else if (luku % 5 == 0) { - System.out.println("Buzz"); -} else if (luku % 3 == 0 && luku % 5 == 0) { - System.out.println("FizzBuzz"); -} else { - System.out.println(luku); -} -``` - - - -**3** -Fizz - - - - - - -**4** -4 - - - - - -**5** -Buzz - - - - - -**15** -Fizz - - - -Edellisessä lähestymistavassa ongelmana on se, että **ehtolauseiden läpikäynti lopetetaan ensimmäiseen ehtoon, jonka arvo on totta**. Esimerkiksi luvulla 15 tulostetaan merkkijono "Fizz", sillä luku on kolmella jaollinen (15 % 3 == 0). - -Yksi lähestymistapa yllä olevan ajatusketjun kehittämiseen on ensin etsiä **vaativin ehto** ja toteuttaa se. Tämän jälkeen toteutettaisiin muut ehdot. Yllä olevassa esimerkissä ehto "jos luku on jaollinen kolmella **ja** viidellä" vaatii kahden tapauksen toteutumista. Nyt ajatusketju olisi muotoa. - -1. Tee ohjelma, joka lukee luvun käyttäjältä. -2. Jos luku on jaollinen kolmella ja viidellä, tulosta luvun sijan merkkijono "FizzBuzz". -3. Jos luku on jaollinen kolmella, tulosta luvun sijaan merkkijono "Fizz". -4. Jos luku on jaollinen viidellä, tulosta luvun sijaan merkkijono "Buzz". -5. Muulloin ohjelma tulostaa käyttäjältä luetun luvun. - - -Nyt ongelmakin tuntuu ratkeavan. - -```java -Scanner lukija = new Scanner(System.in); - -int luku = Integer.valueOf(lukija.nextLine()); - -if (luku % 3 == 0 && luku % 5 == 0) { - System.out.println("FizzBuzz"); -} else if (luku % 3 == 0) { - System.out.println("Fizz"); -} else if (luku % 5 == 0) { - System.out.println("Buzz"); -} else { - System.out.println(luku); -} -``` - - - -**2** -2 - - - - - -**5** -Buzz - - - - - -**30** -FizzBuzz - - - - - - -Vuosi on karkausvuosi, jos se on jaollinen 4:llä. Kuitenkin jos vuosi on jaollinen 100:lla, se on karkausvuosi vain silloin, kun se on jaollinen myös 400:lla. - -Tee ohjelma, joka lukee käyttäjältä vuosiluvun, ja tarkistaa, onko vuosi karkausvuosi. - - - -Anna vuosi: **2011** -Vuosi ei ole karkausvuosi. - - - - - -Anna vuosi: **2012** -Vuosi on karkausvuosi. - - - - - -Anna vuosi: **1800** -Vuosi ei ole karkausvuosi. - - - - - -Anna vuosi: **2000** -Vuosi on karkausvuosi. - - - -Vihje 1: Jollain luvulla jaollisuuden voi tarkastaa jakojäännösoperaation `%` avulla seuraavasti. - -```java -int luku = 5; - -if (luku % 5 == 0) { - System.out.println("Luku on viidellä jaollinen!"); -} - -if (luku % 6 != 0) { - System.out.println("Luku ei ole kuudella jaollinen!") -} -``` - - - -Luku on viidellä jaollinen! -Luku ei ole kuudella jaollinen! - - - -Vihje 2: mieti ongelmaa if, else if, else if, ... -vertailujen ketjuna ja aloita ohjelman rakentaminen tilanteesta, missä voit olla varma, että ohjelma ei ole karkausvuosi. - - -```java -Scanner lukija = new Scanner(System.in); -int luku = Integer.valueOf(lukija.nextLine()); - -if (luku % 4 != 0) { - System.out.println("Vuosi ei ole karkausvuosi."); -} else if (...) { - ... -} ... -``` - - - - - - -[https://www.vero.fi/henkiloasiakkaat/omaisuus/lahja/](https://www.vero.fi/henkiloasiakkaat/omaisuus/lahja/): *Lahja tarkoittaa sitä, että omaisuus siirtyy toiselle henkilölle ilman korvausta. Lahjasta pitää maksaa lahjaveroa, jos samalta lahjanantajalta saatujen lahjojen arvo on kolmen vuoden aikana 5 000 euroa tai enemmän.* - -Kun lahja tulee lähimmiltä sukulaisilta, lahjaveron määrä määräytyy seuraavan taulukon mukaan (lähde [vero.fi](https://www.vero.fi/henkiloasiakkaat/omaisuus/lahja/lahjaverolaskuri/#lahjaverotaulukot)): - -| Lahja | Vero alarajalla | Veroprosentti ylimenevästä | -|-----------------------|------------------|-----------------------------| -| 5 000 -- 25 000 | 100 | 8 | -| 25 000 -- 55 000 | 1 700 | 10 | -| 55 000 -- 200 000 | 4 700 | 12 | -| 200 000 -- 1 000 000 | 22 100 | 15 | -| 1 000 000 -- | 142 100 | 17 | - -Esimerkiksi 6000 euron lahjasta tulee maksaa veroa 180 euroa (100 + (6000-5000) * 0.08), ja 75000 euron lahjasta tulee maksaa veroa 7100 euroa (4700 + (75000-55000) * 0.12). - -Tee ohjelma, joka laskee lahjaveron lähimmiltä sukulaisilta annetulle lahjalle. Alla on muutama esimerkki ohjelman toiminnasta. - - - -Lahjan suuruus? -**3500** -Ei veroa! - - - - - - -Lahjan suuruus? -**5000** -Vero: 100.0 - - - - - -Lahjan suuruus? -**27500** -Vero: 1950.0 - - - - - -