COMP 110 Prasun Dewan 1



Similar documents
16. Recursion. COMP 110 Prasun Dewan 1. Developing a Recursive Solution

CompSci 125 Lecture 08. Chapter 5: Conditional Statements Chapter 4: return Statement

Moving from CS 61A Scheme to CS 61B Java

Debugging. Common Semantic Errors ESE112. Java Library. It is highly unlikely that you will write code that will work on the first go

Conditions & Boolean Expressions

Conditional Statements Summer 2010 Margaret Reid-Miller

CS 141: Introduction to (Java) Programming: Exam 1 Jenny Orr Willamette University Fall 2013

Building Java Programs

2 SYSTEM DESCRIPTION TECHNIQUES

Pseudo code Tutorial and Exercises Teacher s Version

Writing Control Structures

Parsing Technology and its role in Legacy Modernization. A Metaware White Paper

Sudoku puzzles and how to solve them

6. Control Structures

Outline. Conditional Statements. Logical Data in C. Logical Expressions. Relational Examples. Relational Operators

Introduction to Python

Computer Programming C++ Classes and Objects 15 th Lecture

ECE 122. Engineering Problem Solving with Java

Selection Statements

Object-Oriented Design Lecture 4 CSU 370 Fall 2007 (Pucella) Tuesday, Sep 18, 2007

Translating to Java. Translation. Input. Many Level Translations. read, get, input, ask, request. Requirements Design Algorithm Java Machine Language

CASCADING IF-ELSE. Cascading if-else Semantics. What the computer executes: What is the truth value 1? 3. Execute path 1 What is the truth value 2?

Sample CSE8A midterm Multiple Choice (circle one)

C H A P T E R Regular Expressions regular expression

1.4 Compound Inequalities

AP Computer Science Java Subset

Chapter 5. Selection 5-1

CHAPTER 2. Logic. 1. Logic Definitions. Notation: Variables are used to represent propositions. The most common variables used are p, q, and r.

The Rules 1. One level of indentation per method 2. Don t use the ELSE keyword 3. Wrap all primitives and Strings

Lecture 3: Finding integer solutions to systems of linear equations

A binary search tree or BST is a binary tree that is either empty or in which the data element of each node has a key, and:

Software Engineering Techniques

Visual Basic Programming. An Introduction

=

JavaScript: Introduction to Scripting Pearson Education, Inc. All rights reserved.

Statements and Control Flow

Visual Logic Instructions and Assignments

Name: Class: Date: 9. The compiler ignores all comments they are there strictly for the convenience of anyone reading the program.

2) Write in detail the issues in the design of code generator.

Getting Started with the Internet Communications Engine

First Java Programs. V. Paúl Pauca. CSC 111D Fall, Department of Computer Science Wake Forest University. Introduction to Computer Science

Lecture 2 Notes: Flow of Control

We will learn the Python programming language. Why? Because it is easy to learn and many people write programs in Python so we can share.

Introduction to Java Applications Pearson Education, Inc. All rights reserved.

NUMBER SYSTEMS. William Stallings

JavaScript: Control Statements I

1 Introduction. 2 An Interpreter. 2.1 Handling Source Code

J a v a Quiz (Unit 3, Test 0 Practice)

While Loop. 6. Iteration

Chapter 2: Algorithm Discovery and Design. Invitation to Computer Science, C++ Version, Third Edition

NUMBER SYSTEMS APPENDIX D. You will learn about the following in this appendix:

Boolean Expressions 1. In C++, the number 0 (zero) is considered to be false, all other numbers are true.

VB.NET Programming Fundamentals

Writing an essay. This seems obvious - but it is surprising how many people don't really do this.

Chapter 8 Selection 8-1

UNIVERSITY OF CALIFORNIA Department of Electrical Engineering and Computer Sciences Computer Science Division. P. N. Hilfinger

Python Programming: An Introduction To Computer Science

Object Oriented Software Design

Unix Shell Scripts. Contents. 1 Introduction. Norman Matloff. July 30, Introduction 1. 2 Invoking Shell Scripts 2

Unit 1 Number Sense. In this unit, students will study repeating decimals, percents, fractions, decimals, and proportions.

Guide to Performance and Tuning: Query Performance and Sampled Selectivity

In mathematics, it is often important to get a handle on the error term of an approximation. For instance, people will write

Module 2 Stacks and Queues: Abstract Data Types

Mathematical Induction

Basic Java Constructs and Data Types Nuts and Bolts. Looking into Specific Differences and Enhancements in Java compared to C

Discrete Mathematics and Probability Theory Fall 2009 Satish Rao, David Tse Note 2

CALCULATIONS & STATISTICS

Programming Languages

Concepts and terminology in the Simula Programming Language

CS 2112 Spring Instructions. Assignment 3 Data Structures and Web Filtering. 0.1 Grading. 0.2 Partners. 0.3 Restrictions

public static void main(string[] args) { System.out.println("hello, world"); } }

CS 106 Introduction to Computer Science I

C++ INTERVIEW QUESTIONS

Iteration CHAPTER 6. Topic Summary

Sources: On the Web: Slides will be available on:

Chapter 8: Bags and Sets

Part I. Multiple Choice Questions (2 points each):

INTRUSION PREVENTION AND EXPERT SYSTEMS

The last three chapters introduced three major proof techniques: direct,

COMP 250 Fall 2012 lecture 2 binary representations Sept. 11, 2012

Java Interview Questions and Answers

Lecture 4: Writing shell scripts

Handout 1. Introduction to Java programming language. Java primitive types and operations. Reading keyboard Input using class Scanner.

Outline. Written Communication Conveying Scientific Information Effectively. Objective of (Scientific) Writing

Not agree with bug 3, precision actually was. 8,5 not set in the code. Not agree with bug 3, precision actually was

MATLAB Programming. Problem 1: Sequential

NP-Completeness and Cook s Theorem

Designing with Exceptions. CSE219, Computer Science III Stony Brook University

IF The customer should receive priority service THEN Call within 4 hours PCAI 16.4

language 1 (source) compiler language 2 (target) Figure 1: Compiling a program

A Little Set Theory (Never Hurt Anybody)

Mobile App Design Project #1 Java Boot Camp: Design Model for Chutes and Ladders Board Game

Subversion workflow guide

Capabilities of a Java Test Execution Framework by Erick Griffin

Automata and Computability. Solutions to Exercises

Chapter 14: Boolean Expressions Bradley Kjell (Revised 10/08/08)

CS104: Data Structures and Object-Oriented Design (Fall 2013) October 24, 2013: Priority Queues Scribes: CS 104 Teaching Team

Aim To help students prepare for the Academic Reading component of the IELTS exam.

Lecture Notes on Binary Search Trees

Transcription:

COMP 110 Prasun Dewan 1 12. Conditionals Real-life algorithms seldom do the same thing each time they are executed. For instance, our plan for studying this chapter may be to read it in the park, if it is a sunny day, and in the library, otherwise. Similarly, the execution of most non-trivial programs depends on the results of tests. We will study new statements, called conditionals, that allow us to write such programs. They allow us to break away from the straight-line execution of the programs we have seen so far (where statements are executed one after the other along a linear execution path); in particular, they allow branching in the execution path. Because of the real-life analogy, using conditionals is relatively straightforward. The main challenge is to use them elegantly; therefore, we will also learn several general rules on their usage. if- statement Suppose we need a procedure, printpassfailstatus, that takes a numeric score as an argument, and prints the string PASS or FAIL based on whether the score is above the pass cutoff. Thus, assuming the cutoff is 50, the call printpassfailstatus(95) should print: and: should print: PASS printpassfailstatus(30) FAIL In order to write this method, we need a mechanism that allows the execution of different statements based on some condition. The if- statement, illustrated below, is one mechanism for supporting such conditional execution: public static void printpassfailstatus(int score) { if (score < PASS_CUTOFF) System.out.println("FAIL"); System.out.println("PASS"); 1 Copyright Prasun Dewan, 2000.

Figure 1. if- statement In general, the statement has the syntax: if (<boolean expression>) <statement1>; <statement2>; (Note that parentheses are required around <boolean expression>). What this statement depends on <boolean expression>. If <boolean expression> evaluates to true, it executes <statement1>, otherwise it executes <statement2>. <statement 1> is called the then part or then branch; <statement 2> is called the part or branch ; and <boolean expression> is called the condition of the if-. Thus, in the method above, the if- tests the boolean expression: score < PASS_CUTOFF. In case this expression returns true, the statement branches to the then part: System.out.println("FAILED"); Otherwise the statement branches to the part: System.out.println("PASSED"); When the method is called with the argument, 30, the boolean expression evaluates to true, resulting in the then part being executed; and when it is called with the argument 30, it evaluates to false, resulting in the part being executed. Reading if- Novice programmers sometimes add a redundant test in the condition of an if-: if (score < PASS_CUTOFF == true) This expression perhaps reads better in English if we read: if (<boolean expression>)

as it is written. However, it should be really read as: if (<boolean expression>) is true because, as mentioned above, the if- evaluates the value of its condition and executes the then-part if the value is true. Thus, the above if- should be read as: if (score < PASS_CUTOFF == true) is true Now it does not read well. It is equivalent but more long-winded than saying: if (score < PASS_CUTOFF ) is true In general, avoid testing a boolean expression for equality or inequality with the true and false values. Boolean Expression vs. if- Let us consider a variation of the method above that, instead of printing a string, returns a boolean value to indicate the pass/fail status. We might be tempted to structure this function like the procedure: public static boolean hasfailed(int score) { if (score < PASS_CUTOFF) return true; return false; The if- we use here is similar to the one we used in the previous example except that its then and parts return the false and true values, rather than printing the strings FAILED and PASSED, respectively. There is a simpler way to write this function: public static boolean hasfailed(int score) { return (score < PASS_CUTOFF); The function returns true if the boolean expression score < PASS_CUTOFF is true and false otherwise, which is exactly what our previous version did. It is easy to detect that the if above is unnecessary if we read it as: if (score < PASS_CUTOFF) is true return true; return false; The statement is essentially returning the value of its condition. Since an if- can implement more general logic than a boolean expression, we are often tempted to use them for all logic. Therefore,

once you have written an if-, check if a simple boolean expression would have sufficed instead. If all the then and branches do is compute the true (false) and false (true) values, respectively, then get rid of the if- and use (the negation of the) condition as the computed value. Compound Statement What if we wanted to perform more than one statement in the then or branch? Java lets us create a compound statement by enclosing a series of statements within the delimiters { and, as shown below: public void fancyprintgrade(int score) { if (score < PASS_CUTOFF ) { System.out.println("FAILED"); { System.out.println("PASSED"); System.out.println("Congratulations!"); As far as the if- is concerned, there is only one statement in the then or the part. The statement happens to be a compound statement containing a list of statements. We have actually already seen examples of a compound statement the body of a method and the try and catch block. We will see later the use of the compound statement in other constructs. A compound statement is also called a statement list, statement block or simply block. Putting the delimiters ({ and ) of a compound statement on their own lines takes too much space; therefore the convention is to put them on the lines containing the if and keywords, as shown below: public void fancyprintgrade(int score) { if (score < PASS_CUTOFF) { System.out.println("FAILED"); { System.out.println("PASSED"); System.out.println("Congratulations!");

Code Duplication Again It is possible to write a better implementation of the procedure above: public void factoredfancyprintgrade(int score) { if (score < PASS_CUTOFF) { System.out.println("FAILED"); { System.out.println("PASSED"); System.out.println("Congratulations!"); While the previous implementation indicates the exact set of steps to be taken in each case, it repeats code in the two branches. It is preferable to share code that must be executed in both branches, for the reasons we saw earlier. Less Typing: We have to type less. With today s cut and paste features, this is not the major advantage, however, as we saw before. Clarity: We can clearly identify the code that is executed in both cases. Otherwise we would have to explicitly compare the two branches to see what code is executed in both cases. For instance, in the example above, we would have to count the number of * s to se if the same number of them are being printed in the two cases. Change: Suppose we wanted to change the number of * s that must be printed in both cases. In the non-sharing approach, we would have to duplicate the changes in both branches. It is easy to forget to change one of them or change them differently. So the sharing approach is more resilient to program changes. The general principle, which we saw earlier, is to avoid duplication of code in a program. In the context of an if-, it implies that we should share code in the then and branches. We will later see the application of this principle to other statements. if Statement Sometimes we wish to take no action in an branch. In this case, the if statement can be used instead of the if- statement. It has the syntax: Example: if (<boolean expression>) <statement>; if (score == MAX_SCORE) System.out.println ("Perfect Score! Congratulations!");

Figure 2. if statement Figure 3. Nesting in the parts We can always use an if- statement instead of an if statement by putting nothing (the "null" statement) in the part: if (score == MAX_SCORE) System.out.println ("Perfect Score! Congratulations!"); ; But the if statement is more elegant when the is a null statement. Beginning programmers, used mainly to the if- statement and unfamiliar with the null statement, tend to sometimes put a spurious assignment in the part: if (score == MAX_SCORE) System.out.println ("Perfect Score! Congratulations!"); score = score; Like the previous solution, this is correct but even less elegant! We shall refer to if- and if statements as conditionals, because their execution depends on some condition. An if- statement is used to choose between the execution of two statements based on

the condition; while an if statement is used to determine whether a statement should be executed based on the condition. Nested Conditionals Consider the following function, which takes returns a letter grade based on the argument score: public static char tolettergrade(int score) { return 'A'; if (score >= B_CUTOFF) return 'B'; if (score >= C_CUTOFF) return 'C'; if (score >= D_CUTOFF) return 'D'; return 'F'; The use of the if statement here might seem at odds with the syntax we gave: if (<boolean expression>) <statement1> <statement2> In fact, you might think of it as a special kind of statement in which the keywords if replace the keyword. But actually, it is simply a sequence of nested conditionals, that is, if- statements whose or then branches contains other conditionals (Figure 3). The following format clarifies this: return 'A'; if (score >= B_CUTOFF) return 'B'; if (score >= C_CUTOFF) return 'C'; if (score >= D_CUTOFF) return 'D'; return 'F'; Since this format takes more space, we prefer the previous one, in which we used the same indentation for the enclosing and enclosed conditionals. then vs. Branching We could have written this function in other several other ways. In the implementation above, all the branching (nesting) occurs in the parts of the if- statements (Figure 3). This is because we

started our comparisons with the highest cutoff, A_CUTOFF. If we started our comparisons with the lowest one, D_CUTOFF, all the branching would occur in the then parts. if (score >= D_CUTOFF) if (score >= C_CUTOFF) if (score >= B_CUTOFF) return 'A'; return 'B'; // score < B_CUTOFF return 'C'; // score < C_CUTOFF return 'D'; // score < D_CUTOFF return 'F'; However, this implementation is more awkward to read since the parts of the inner if- statements get separated from their conditions. In fact, we need comments to remind ourselves of the correspondence between these part and their conditions. Therefore, it is better to nest the branches rather than the then branches. Linear Vs Balanced Branching Both solutions, the branching is linear, that is, it occurs on one side (then or ) of the decision tree, with the other side not containing any conditional. If we started our comparisons, not with the extreme values, A_CUTOFF and D_CUTOFF, but instead with a value in between, we would get a more balanced branching: if (score >= B_CUTOFF) return 'A'; return 'B'; // score < B_CUTOFF if (score < C_CUTOFF) if (score < D_CUTOFF) return 'F'; return 'D'; // score >= C_CUTOFF return 'C'; Again, some parts get separated from their conditions in this solution. Moreover, the solution is confusing because sometimes we check if a value is greater than a cutoff and sometimes if it is less. In summary, choose linear branching over balanced branching; and branching on the side over branching on the then side.

Nested Vs Non-nested Solution We could have done the problem without nested conditionals, as shown below: result = 'A'; if ((score < A_CUTOFF) && (score >= B_CUTOFF)) result = 'B'; if ((score < B_CUTOFF) && (score >= C_CUTOFF)) result = 'C'; if ((score < C_CUTOFF) && (score >= D_CUTOFF)) result = 'D'; if (score < D_CUTOFF) result = F'; return result; The problem with this alternative is that there are two tests in the second, third, and fourth ifs, while there is only one test in the previous version for each if. Thus the previous version is more efficient - it will run faster. Moreover, you had to write less too! The second solution essentially violates the principle of avoiding redundant computation. Multiple & Early Returns As the various nested implementations of the function tolettergrade how, it is possible for a function to have more than one return statement. When there are multiple alternative paths through a function, it is usual to have a return at the end of each path. It is also possible to have an early return, that is, a return in the middle of a path. When Java encounters a return statement, it terminates execution of the method, ignoring any statements that follow it. An early return can be a useful feature, as illustrated by the following alternative solution to the letter grade problem. It uses independent if statements without doing redundant computation: return 'A'; if (score >= B_CUTOFF) return 'B'; if (score >= C_CUTOFF) return 'C'; if (score >= D_CUTOFF) return 'D'; return F'; This solution works because the then part of each of the if statements is a return statement, telling the method to ignore the following statements in the program. When we execute an if statement in this solution, we know that the condition of the previous if statement was false, which is equivalent to putting it in the part of the preceding if statement. Thus, this program is equivalent to our first solution:

return 'A'; if (score >= B_CUTOFF) return 'B'; if (score >= C_CUTOFF) return 'C'; if (score >= D_CUTOFF) return 'D'; return F'; It is somewhat preferable than the first solution since it requires a bit less typing. In summary, a nested if then statement with multiple returns can sometimes be elegantly replaced by a series of if statements with early returns. Explicit return in a Procedure Java allows us to do an early return from a procedure also: public void printlettergrade(int score) { if (score < 0) { System.out.println ("Illegal score"); return; System.out.println( Letter Grade: + tolettergrade(score )); In a procedure, the return keyword does not take an argument, because no value is to be returned. It is usual to have early returns in a procedure for various error conditions. In the absence of early returns, the normal (error-free) processing of the procedure would be in an part of an if-: public void printlettergrade(int score) { if (score < 0) { System.out.println ("Illegal score"); return; System.out.println( Letter Grade: + tolettergrade(score )); This solution requires an extra level of indentation, which is a significant disadvantage because the screen real-estate tends to be limited. Dangling Else Problem Consider the following nested if statement: if (score >= B_CUTOFF)

System.out.println ("excellent!"); System.out.println ("bad"); Which if statement does the statement match with? If you typed this text using the J++ 6.0 editor, this is how it would be automatically formatted. This may lead you to believe that it matches the outer if statement. But you could manually format it as: if (score >= B_CUTOFF) System.out.println ("excellent!"); System.out.println ("bad"); Now it looks as if it matches the inner if statement. Our syntax rule of an if- statement allows for both interpretations. This ambiguity is called the dangling problem. It is resolved by making an match the closest if. So, in this example, the second interpretation is the correct one. The possibility for confusion here is another reason for not nesting in a then branch. Summary An if- conditional is used to choose between the execution of two statements based on the value of a boolean expression. An if conditional is used to determine whether a statement should be executed based on the value of a boolean expression. A conditional can nest other conditionals to create an arbitrary number of alternative execution paths within a method. In a nested conditional, branching in the part is preferred to branching in the then part or balanced branching. An part matches the closest then part. A nested if-then conditional with multiple returns can sometimes be elegantly replaced by a series of if statements with early returns. An if- statement can sometimes be elegantly and efficiently replaced by a boolean expression. Avoid testing a boolean expression for equality or inequality with the true and false values.

Exercises 1. Write a more concise version of the following function: public static boolean haspassed(int score) { if (score < PASS_CUTOFF) return false; return true; 2. The following code fragment has repeated code in the two branches of the if- statement. Write an equivalent function that does not have repeated code. public void fancyprintgrade(int score) { if (score < PASS_CUTOFF == true) { System.out.println("FAILED"); System.out.println("Need to take the course again."); { System.out.println("PASSED"); System.out.println("Congratulations!"); 3. Write a procedure, internetlogin to simulate process of manually logging in to an internet provider. The procedure takes as arguments the expected name and password of the user. It prompts the user for a name and password and checks the values input are consistent with the expected values. It then prompts the user for a command, and if the string ppp is entered, it outputs the string Connection Succeeded, and returns to its caller. In case the wrong user name, password, or command are entered, it gives an error message indicating the erroneous input, and returns to its caller. The following window illustrates two possible interactions during calls to internetlogin( John Smith, open sesame ). Write the procedure using: a) branching in the parts of nested if- statements. b) branching in the then parts of nested if- statements. c) a series of if statements with early returns. d) a single, non-nested, if- statement that calls an auxiliary boolean function, readandcheckinput that takes as arguments the kind of user input ( Name, Password, Command ) and the expected value for the entry, prompts the user for the input, reads the input, and returns true or false based on whether the actual user input is the same as the expected value.

Check for string equality by invoking the equals method on a string, rather than using the Java == operator. Thus, to check that a string s1 is the same as string s2, evaluate s1.equals(s2) rather than s1==s2. See chapter 17 for the difference between == and equals. 4. Extend the temperature driver class of Chapter 7, Question 4. to allow the user to enter the three temperatures in centigrade or Fahrenheit, depending on what the user chooses at the beginning of the interaction, as shown below: