Solving Problems with Decisions

advertisement
Solving Problems that
involve decisions
Topics
Normal execution order
Conditional statements
Relational operators & Boolean expressions
Enumerations
Objectives
At the completion of this topic, students should be able to:
Describe the normal flow of control through a C# program
Correctly use if statements in a C# program
Explain how to use relational operators to write a Boolean expression
and use them correctly in a C# program
Correctly use if/else statements in a C# program
Correctly use blocks in if/else statements
Correctly use a switch statement in a C# program
Describe enumerations and use them in a C# program
Correctly use the logical operators to make complex Boolean expressions
The order in which statements in a program are
executed is called the flow of control.
Methods that we have written so far begin
with the first line in the method, and
continue line by line until control reaches
the end of the method.
Example of Sequential Flow
F
l
o
w
o
f
using System;
class Program
{
static void Main()
{
const int MINS_PER_HOUR = 60, SPLITTER = 100, PERCENT_BETTER = 1.25;;
int startTime, endTime;
int endTime;
// Prompt for input and get start time
Console.WriteLine("Enter in the start time for this trip in 24 hour clock time");
Console.Write("in the form hhmm: ");
startTime = int.Parse(Console.ReadLine());
c
o
n
t
r
o
l
// Prompt for input and get end time
Console.WriteLine("Enter in the end time for this trip in 24 hour clock time");
Console.Write("in the form hhmm: ");
endTime = int.Parse(Console.ReadLine());
// calculate the start and end time with minutes as integers
int startMmm = startTime / SPLITTER * MINS_PER_HOUR + startTime % SPLITTER;
int endMmm = endTime / SPLITTER * MINS_PER_HOUR + endTime % SPLITTER;
…etc
}
} // end of Main
There are many problems that cannot
be solved using methods that execute
in this line-by-line fashion from beginning
to end.
Some problems require the program to take
different actions, depending upon conditions
that exist in the program at the time.
Examples
A More Accurate GoodGuys Program
GoodGuy's Delivery service operates a fleet of delivery vehicles that
operate between Provo and Salt Lake City. With the I-15 construction
work scheduled for Utah County, Goodguys wants you to create a
program for them that will compute the new arrival times for deliveries.
Once the work on the interstate begins, GoodGuys estimates that their
delivery times will increase based on the following table:
midnight to 6:00am
6:01am to 9:30am
9:31am to 3:00am
3:01pm to 7:00pm
7:01pm to 10:00pm
10:01pm to midnight
no increase
30% increase
10% increase
30% increase
10% increase
no increase
The U.S. Widget company runs its
payroll program at the end of
every two week period.
If an employee gets paid by the hour,
that employee’s gross pay is equal to
hoursWorked * hourlyWage;
However, if an employee gets paid a
salary, that employee’s gross pay is
calculated differently
yearlySalary / 26.0;
In a computer chess game, the computer
might calculate its move in a number of
different ways, depending upon where all
of the various pieces on the chessboard.
How can you tell if a problem requires
a program that includes this kind of logic?
When the problem statement includes the word “if”
If this employee gets an hourly wage
If the King is in check
If today is a weekday
If the balance in the account is less than $1,000
Sometimes the problem statement will use the word “when”
When an employee gets an hourly wage
When the King is in check
When the day is a weekday
When the balance in the account is less than $1,000
GoodGuys
If the delivery truck
leaves between
midnight and 6:00am
6:01am and 9:30am
9:31am and 3:00am
3:01pm and 7:00pm
7:01pm and 10:00pm
10:01pm and midnight
Then the delivery
time increases by
0%
30%
10%
30%
10%
0%
These are all examples of Conditional Statements,
i.e. do something if a condition is true. In programming
we often take a different action based on whether or
not a condition is true.
Conditional statements are shown in an
activity diagram by using a diamond.
( balance < LIMIT )
balance <
LIMIT
?
Conditional statements are shown in an
activity diagram by using a diamond.
Arrows show the execution path that the program
takes when the statement is true and when it is false.
if ( balance < LIMIT )
balance <
LIMIT
?
false
true
Conditional statements are shown in an
activity diagram by using a diamond.
Arrows show the execution path that the program
takes when the statement is true and when it is false.
if ( balance < LIMIT )
The “if” statement
tests the condition.
balance <
LIMIT
?
false
true
The if Statement
The if statement allows us to execute a
statement only when the condition is true.
if ( balance < LIMIT )
balance = balance – CHARGE;
balance <
LIMIT
?
false
note how we have indented
the statement to be executed
when the condition is true. Although
the compiler doesn’t care about indentation,
it makes it easier to read the code.
true
balance =
balance – CHARGE;
The if Statement
The if statement allows us to execute a
statement only when the condition is true.
if ( balance < LIMIT )
{
balance = balance – CHARGE;
}
Use curly braces to clearly define what actions
Are taken when the condition is true
balance <
LIMIT
?
false
true
balance =
balance – CHARGE;
Problem Statement
Write a program that prompts the user to enter in his or her
age. Ifthe person is under 21, print a message that says
“Youth is a wonderful thing … enjoy it.”
Prompt user to
Enter in their
age
Store input
in the variable
age
age < 21
?
false
end
true
Print
“Youth is a …”
using System;
class Program
{
const int MINOR = 21;
static void Main()
{
int age = 0;
Console.Write("How old are you? ");
age = int.Parse(Console.ReadLine());
Notice how this block of code is
executed if the condition is true,
but the block is skipped if the
condition is false.
if (age < MINOR)
{
Console.WriteLine("Youth is a wonderful thing ... enjoy it.");
}
Console.WriteLine(“Goodbye!”);
Console.ReadLine();
}//End Main()
}//End class Program
The expression inside the if( … )
statement is called a Boolean expression,
because its value must be either true or false.
Relational Operators
relational operators are used to write Boolean expressions
Operator
==
!=
<
<=
>
>=
Meaning
equal
not equal
less than
less than or equal (not greater than)
greater than
greater than or equal (not less than)
Note: The precedence of relational operators
is lower than arithmetic operators, so arithmetic
operations are done first.
Warning: Don’t confuse = and ==
Note that the following expression
will not compile in C#…
if ( age = myNewAge)
{
...
}
This is an assignment,
not a comparison
The if/else statement
This construct allows us to do one thing if a condition
is true, and something else if the condition is false.
if (height > MAX)
adjustment = MAX – height;
else
adjustment = 0;
Console.WriteLine(adjustment);
true
height > MAX
?
false
adjustment
=0
adjustment =
MAX - height
Problem Statement
Write a program that prompts the user to enter in his or her
age. If the person is under 21, print a message that says
“Youth is a wonderful thing … enjoy it.”
Otherwise, print a message that says
“Old age is a state of mind.”
Prompt user to
Enter in their
age
Store input
in the variable
age
age < 21
?
true
Print
“Youth is a …”
false
Print
Old age is a…”
end
using System;
class Program
{
const int MINOR = 21;
static void Main()
{
int age;
Console.Write("How old are you? ");
age = int.Parse(Console.ReadLine());
if (age < MINOR)
{
Console.WriteLine("Youth is a wonderful thing ... enjoy it.");
}
else
{
Console.WriteLine("Old age is a state of mind...!");
}
Console.ReadLine();
}//End Main()
}//End class Program
Executing a Block of
Statements
Sometimes we want to execute more than one
statement when a condition is true ( or false ).
In C#, we can use a block of statements, delimited
by { and } anyplace where we would normally use a
single statement.
if ( a < b )
{
a = 0;
b = 0;
Console.WriteLine(“Sorry …”);
}
...
using System;
class Program
{
const int MINOR = 21;
static void Main()
{
int age;
Console.Write("How old are you? ");
age = int.Parse(Console.ReadLine());
if (age < MINOR)
{
Console.WriteLine("**********************************");
Console.WriteLine("* Youth is a wonderful thing *");
Console.WriteLine("*
Enjoy it!
*");
Console.WriteLine("**********************************");
}
else
{
Console.WriteLine("***********************************");
Console.WriteLine("*
Old age is a
*");
Console.WriteLine("*
state of mind...!
*");
Console.WriteLine("***********************************");
}
Console.ReadLine();
}//End Main()
}//End class Program
Nested if/else Statements
In C#, the statement to be executed as the
result of an if statement could be another if
statement.
In a nested if statement, an else clause is
always matched to the closest unmatched if.
using System;
class Program
{
static void Main()
{
int a, b, c, min = 0;
Console.WriteLine("Enter three integer values - each on a separate line.");
a = int.Parse(Console.ReadLine());
b = int.Parse(Console.ReadLine());
c = int.Parse(Console.ReadLine());
if (a < b)
if (a < c)
min = a;
else
min = c;
else
if (b < c)
min = b;
else
min = c;
keep track of which if an else goes with!
Console.WriteLine("The smallest value entered was {0}", min);
Console.ReadLine();
}//End Main()
}//End class Program
using System;
class Program
{
static void Main()
{
int a, b, c, min = 0;
Console.WriteLine("Enter three integer values - each on a separate line.");
a = int.Parse(Console.ReadLine());
b = int.Parse(Console.ReadLine());
c = int.Parse(Console.ReadLine());
if (a < b)
if (a < c)
min = a;
else
min = c;
else
if (b < c)
min = b;
else
min = c;
Hmmm … it’s hard without indenting code
Console.WriteLine("The smallest value entered was {0}", min);
Console.ReadLine();
}//End Main()
}//End class Program
using System;
class Program
{
static void Main()
{
int a, b, c, min = 0;
Console.WriteLine("Enter three integer values - each on a separate line.");
a = int.Parse(Console.ReadLine());
b = int.Parse(Console.ReadLine());
c = int.Parse(Console.ReadLine());
if (a < b)
if (a < c)
min = a;
else
Hmmm … it’s worse if you indent wrong
min = c;
else
if (b < c)
min = b;
else
min = c;
Console.WriteLine("The smallest value entered was {0}", min);
Console.ReadLine();
}//End Main()
}//End class Program
Another Example
char direction = ‘n’;
Console.WriteLine("Press a direction key(n, s, e, or w) and Enter");
direction = char.Parse(Console.ReadLine());
if (direction == 'n')
Console.WriteLine("You are now going North.");
else if (direction == 's')
Console.WriteLine("You are now going South.");
else if (direction == 'e')
Console.WriteLine("You are now going East.");
else if (direction == 'w')
Console.WriteLine("You are now going West.");
else
Console.WriteLine("You don't know where you are going!");
Console.ReadLine();
if (direction == 'n')
Console.WriteLine(“…going North.");
else
if (direction == 's')
Console.WriteLine(“…going South.");
else
if (direction == 'e')
Console.WriteLine(“…going East.");
else
if (direction == 'w')
Console.WriteLine(“…going West.");
else
Console.WriteLine("You don't know…!");
These are exactly
the same. The only
difference is how
the code is indented.
if (direction == 'n')
Console.WriteLine(“…going North.");
else if (direction == 's')
Console.WriteLine(“…going South.");
else if (direction == 'e')
Console.WriteLine(“…going East.");
else if (direction == 'w')
Console.WriteLine(“…going West.");
else
Console.WriteLine("You don't know…!");
if (direction == 'n')
Console.WriteLine(“…going North.");
else if (direction == 's')
Console.WriteLine(“…going South.");
else if (direction == 'e')
Console.WriteLine(“…going East.");
else if (direction == 'w')
Console.WriteLine(“…going West.");
What’s the
difference?
if (direction == 'n')
Console.WriteLine(“…going North.");
if (direction == 's')
Console.WriteLine(“…going South.");
if (direction == 'e')
Console.WriteLine(“…going East.");
if (direction == 'w')
Console.WriteLine(“…going West.");
if (direction == 'n')
Console.WriteLine(“…going North.");
else if (direction == 's')
Console.WriteLine(“…going South.");
else if (direction == 'e')
Console.WriteLine(“…going East.");
else if (direction == 'w')
Console.WriteLine(“…going West.");
Suppose that ‘n’
was entered.
if (direction == 'n')
Console.WriteLine(“…going North.");
if (direction == 's')
Console.WriteLine(“…going South.");
if (direction == 'e')
Console.WriteLine(“…going East.");
if (direction == 'w')
Console.WriteLine(“…going West.");
if (direction == 'n')
Console.WriteLine(“…going North.");
else if (direction == 's')
Console.WriteLine(“…going South.");
else if (direction == 'e')
Console.WriteLine(“…going East.");
else if (direction == 'w')
Console.WriteLine(“…going West.");
This statement is executed and
all of the others are skipped.
Suppose that ‘n’
was entered.
Suppose that ‘n’
was entered.
The first output statement is executed,
then each of the other if statements
is executed in turn. There is no else
clause to cause control to skip these.
if (direction == 'n')
Console.WriteLine(“…going North.");
if (direction == 's')
Console.WriteLine(“…going South.");
if (direction == 'e')
Console.WriteLine(“…going East.");
if (direction == 'w')
Console.WriteLine(“…going West.");
Dangling else clauses
An else is always matched to the closest unmatched if
Will this code do what you expect?
const int R_LIMIT = 40;
const int O_LIMIT = 20;
...
If an employee works more than 40 hours
a week, then make sure that they don’t
work more than 20 hours of overtime
if (regTime > R_LIMIT)
if (overTime > O_LIMIT)
Console.WriteLine(“Overtime hours exceed the limit.”);
else
Console.WriteLine(“no overtime worked.”);
Will this code do what you expect?
const int R_LIMIT = 40;
const int O_LIMIT = 20;
...
if (regTime > R_LIMIT)
if (overTime > O_LIMIT)
Console.WriteLine(“Overtime hours exceed the limit.”);
else
Console.WriteLine(“no overtime worked.”);
This else goes with
The second if statement
...
If regTime were 50 and overTime
were 10, the message “no overtime
worked” would be displayed.
The code should be written this way.
const int R_LIMIT = 40;
Const int O_LIMIT = 20;
...
if (regTime > R_LIMIT)
{
if (overTime > O_LIMIT)
Console.WriteLine(“Overtime hours exceed the limit.”);
}
else
Console.WriteLine(“no overtime worked.”);
Practice:
Write a program that takes a temperature in degrees
Celsius. Then output whether or not water is a solid,
liquid, or vapor at that temperature at sea level.
Example:
Input: -5
Output: Water is solid
Designing programs that
use conditional statements
1.
Carefully inspect the problem statement. If
word “if” is used or the word “when” is used
to describe different situations that might
exist, then the program probably will need
to use conditional statements.
2. After determining that several different situations
might exist, try to identify each unique situation.
Write down the condition that makes this situation
unique.
Carefully check that each condition is unique - there
should be no overlaps. Be sure that the boundary
conditions are correctly stated.
3. Write down exactly what the program should do
differently in each of the unique situations
that you have identified.
4. Formulate the if/else statements that reflect
this set of conditions. Make them as simple
as possible. Watch for dangling else’s.
Example
Slick Guys Used Car Sales gives their sales people a
commission, based on the value of the sale. If the sale
was made at or above the sticker price, the sales person
gets a 20% commission. If the sale was less than the full
sticker price, but greater than the blue book price, the
sales commission is 10%. If the sale price is equal to the
blue book price, the sales person gets a 5% commission.
Slick Guys never sells a car for less than the blue book price.
How many conditions are there?
What are the conditions?
4 Conditions
1. The sales price is GREATER than or EQUAL
to the sticker price.
2. The sales price is LESS than the sticker price
but GREATER than the blue book price.
3. The sales price EQUALS the blue book price.
4. The sales price cannot be less than blue book.
What do you do for each situation?
1. The sales price is GREATER than or EQUAL
to the sticker price.
Set commission = 20% of sales price
2. The sales price is LESS than the sticker price
but GREATER than the blue book price.
Set commission = 10% of sales price
3. The sales price EQUALS the blue book price.
Set commission = 5% of sales price
4. The sales price cannot be less than blue book
Message: Cannot sell for less than blue book
Boundary Conditions
5%
no sale
Blue Book Price
10%
20%
Sticker Price
Boundary Condition
5%
no sale
Blue Book Price
10%
20%
Sticker Price
Put your conditions in order … start with the most likely
is
true
sale >= sticker
?
commission
= 0.20
false
is
sale > bluebk
?
true
commission
= 0.10
true
commission
= 0.05
false
is
Sale = bluebk
?
false
No sale
is
true
sale >= bluebk
?
commission
= 0.10
What happens if you put
the conditions in the wrong
order?
false
is
true
sale > sticker
?
commission
= 0.20
false
is
sale = bluebk
?
false
No sale
true
commission
= 0.05
Suppose that
the sticker price = 20,000,
the blue book price = 19,000, and
the sale price = 21,000.
What will the commission be?
What should it be?
if ( salesPrice >= STICKER_PRICE)
commissionRate = 0.20;
else if ( salesPrice > BLUE_BOOK)
commissionRate = 0.10;
else if (salesPrice == BLUE_BOOK)
commissionRate == 0.05;
else
Console.WriteLine(“No Sale!”);
The Switch Statement
The switch statement allows a program to take
one of several different paths, based on the value
given to the switch statement.
switch ( numValues )
{
must be an integer or a character literal
case 0:
Console.WriteLine(“No values were entered”);
break;
without the break
case 1:
statement, you will get
Console.WriteLine(“One value was entered”); a compile error.
break;
case 2:
Console.WriteLine(“Two values were entered”);
if numValues is not
break;
0, 1, or 2, execution
goes here.
default:
Console.WriteLine(“Too many values were entered”);
break;
}
Enumerations
An enumeration type is a user defined data type whose
valid values are defined by a list of constants of type int.
enum DayOfWeek { SUN=0, MON=1, TUE=2, WED=3, THU=4, FRI=5, SAT=6 };
if values are not explicitly given, then the first constant is
assigned zero, and then each is incremented by one. So the
following is equivalent to the above example:
enum DayOfWeek { SUN, MON, TUE, WED, THU, FRI, SAT };
Enumerations are often used to label the cases in a switch statement:
enum Days { MON = 1, TUE = 2, WED = 3};
{
--switch ( (Days)whichDay )
{
case Days.MON:
Console.WriteLine("Today is Monday");
break;
case Days.TUE:
Console.WriteLine("Today is Tuesday");
break;
case Days.WED:
Console.WriteLine("Today is Wednesday");
break;
default:
Console.WriteLine("What day is it?");
break;
}
}
Console.ReadLine();
Handling Complex Conditions
Consider the following situation:
If it is Friday night and you have no homework
then go to the movies.
These two conditions can be
combined using logical operators.
Logical Operators
Operator
!
&&
||
Description
Example
logical NOT
logical AND
logical OR
!a
a && b
a || b
the results of logical operations are defined in truth tables
Logical NOT
a
!a
false
true
true
false
Logical AND
the evaluation of &&
is short circuited if a
is false.
a
b
a && b
false
false
false
false
true
false
true
false
false
true
true
true
Logical OR
the evaluation of ||
is short circuited if
a is true.
a
b
a || b
false
false
false
false
true
true
true
false
true
true
true
true
Consider the following situation:
If it is Friday night and you have no homework
then go to the movies.
if ( today == FRIDAY && homework == NO)
goToMovie( );
Simplifying complex relationships
using logical operators
Consider the following problem:
Given three values, x, y, and z, find out if
y lies in between x and z.
y <x
y>z
y > x and y < z
x
z
Consider the following problem:
Given three values, x, y, and z, find out if
y lies in between x and z.
y <x
y > x and y < z
y>z
z
x
We could write the conditions as follows:
if ( y > x)
if ( y < z)
Console.WriteLine(“\n the value of y lies between x and z.”);
else
Console.WriteLine( “\n the value of y does not lie between x and z.”);
else
Console.WriteLine( “\n the value of y does not lie between x and z.”);
Consider the following problem:
Given three values, x, y, and z, find out if
y lies in between x and z.
y <x
y>z
y > x and y < z
x
z
But the following is simpler and eliminates one else clause:
if ( y > x && y < z )
Console.WriteLine( “\n the value of y is between x and z.”);
else
Console.WriteLine( “\n the value of y is not between x and z.”);
Operator Precedence (again)
higher precedence
lower precedence
+
!
unary plus
unary minus
Not
*
/
%
multiplication
division
remainder
+
-
addition
subtraction
higher precedence
lower precedence
<
>
<=
>=
less than
greater than
less than or equal
greater than or equal
==
!=
equal
not equal
&&
and
||
or
=
+=
-=
*=
/=
%=
assignment
add and assign
subtract and assign
multiply and assign
divide and assign
modulo and assign
Comparing Characters
Characters in the ASCII standard are arranged so
that they compare in alphabetical order (collating sequence).
Lower case characters are not equal to their upper case
counterparts. As a matter of fact lower case characters are
greater in value than upper case characters.
The ASCII Code Table
cat
car
99 97 116
99 97 114
Cat
67 97 116
CAR
67 65
82
Comparing Real Numbers
Because of the way that real numbers are represented
in the computer, you cannot be guaranteed that two
real numbers are exactly equal to one another.
The best way to handle this situation is to subtract one
Real number from the other and see if the absolute value of
their difference is smaller than some tolerance value.
Testing to see if two floating point values are equal
const double EPS = 0.0001;
...
if ( (a – b) < EPS) )
Console.WriteLine(“\nThey are equal…”);
Practice
What is the value of the following, given that the value of count = 0,
and the value of limit = 10? We don’t know what x and y are.
(count == 0 ) && (limit < 20)
true
(count == 0 && limit < 20)
true
(limit > 20 || count < 5)
true
!(count == 12)
true
(count == 1 && x < y)
false
(count < 10 || x < y)
true
(limit / count > 7 && limit < 0)
divide by zero error!
(limit < 20 || limit / count > 7)
true
Not all problems requiring decisions will use the word
“if” or “when” in the problem description.
Learn to identify problems that may contain choices.
For example …
A triangle whose sides are all of equal
length is called an equilateral triangle.
A triangle with two equal sides is called
an isosceles triangle.
A triangle whose sides are all of different
lengths is called a scalene triangle.
Write a program that asks for the lengths
of the three sides of a triangle, and then
tells the user what kind of triangle it is.
Groups of four
* Design and code these programs
Practice
Problem: Allow the user to type in two integers.
Print out the value of the highest number. Numbers
may be negative. If they are equal, say so.
Practice
Obe Wan Kenobi is in charge of reviewing the applications
of this years candidates for Jedi Knight school. Candidates
must be at least 3’ high, but less than 8’. However, an
exception has been made for Federation pilots, who can be
of any height. Candidates under 3’ can go to Jr. Jedi Knight School.
Write a program that
* gets a candidate’s height
* asks if they are a federation pilot,
* Then prints one of the following messages, as appropriate:
- This candidate is accepted into Jedi Knight School
- This candidate is accepted into Jr. Jedi Knight School
- This candidate is not accepted.
Practice
The DeepPockets Savings Bank computes the monthly
interest rate on an account, based on the following:
Super Saver Account
5% interest on the balance
as long as it is more than
$5,000. Otherwise pay 3%.
Standard Account
Always pay 3% interest
on the balance.
Write a program that computes the interest on an account,
given the balance on the account and the type of account.
Practice
Write a tollbooth program that calculates the toll required
to use the highway, based on the class of vehicle.
Passenger cars $2.00
Busses
$3.00
Trucks
$5.00
Use a switch statement and an enumeration.
Download