Welcome to Lesson 8!

Learning Objectives
By the end of today's class, you should know...
  • How do you compare strings?
  • How to make decisions when there are multiple alternatives?
  • What is the proper ordering of if statements when order of the statements matter?

Announcements

  • Midterm 1 next class
    • Study over your old quizzes, in-class review activities and homework
    • On material through if statements 
    • Midterm review posted as homework tonight (practice quiz)
    • Material from Lesson 2 through Lesson 7
  • No in-class quiz. Instead, do practice quiz tonight as midterm review. Linked from Assignment 8 page.
  • Assignment 8 due one week from today (Mon, February 12) to allow time to study for the midterm.
  • Don't forget Lab 5 due Friday!


Review Activity

With a partner, answer the following questions:

1. Write one line of code to declare a String variable (name of your choice) and assign it the value $.

2. Write one line of code to declare a char variable (name of your choice) and assign it the value of $.

3. What does the following output to the console:

string info = "Why hello, I'm Emily!";

cout << info.length() << ": " << info.substr(1,1) << info.substr(11, 1) << info.substr(14,3);

4. Write an if statement to check if the value stored in the variable age is equal to 5. If so, print out the age.

5. With a partner, identify and correct the 2 mistakes in the code below:


int guess;

cout << "Enter a guess: ";

cin >> guess;


if (guess = 7) {

    cout << “Correct!”;

} else (guess != 7) {

    cout << “Incorrect!”;

}


Comparing Characters and Strings
  • Character data can be evaluated using relational operators as well
  • Comparing characters works because C++ stores characters as numbers using ASCII codes
  • Note that letters nearer to the start of the alphabet have lower numerical values
  • Thus a numerical comparison can decide the alphabetical order of characters

Example Program Comparing Characters

1
2
3
4
5
6
7
8
9
10
11
12
#include<iostream>
using namespace std;

int main() {
    cout << boolalpha; // output true or false
    cout << "'A' < 'B': " << ('A' < 'B') << endl;
    cout << "'A' > 'B': " << ('A' > 'B') << endl;
    cout << "'A' <= 'Z': " << ('A' <= 'Z') << endl;
    cout << "'X' >= 'Y': " << ('X' >= 'Y') << endl;
    cout << "'X' == 'X': " << ('X' == 'X') << endl;
    cout << "'X' != 'X': " << ('X' != 'X') << endl;
}

Comparing Strings

  • We can compare strings using relational operators as well
  • C++ compares two strings using lexicographical order (a.k.a. alphabetic order)
  • For example, "car" is less than "cat":
    car
    cat
  • Also, "car" is less than "card"
    car
    card

Example Program Comparing Strings

1
2
3
4
5
6
7
8
9
10
11
#include<iostream>
using namespace std;

int main() {
    string s1, s2;
    cout << "Enter two strings: ";
    cin >> s1 >> s2;
    cout << boolalpha; // output true or false
    cout << s1 << " <= " << s2 << " : " << (s1 <= s2) << endl;
    cout << s1 << " > " << s2<< " : " << (s1 > s2) << endl;
}

Activity 8.1: Let's Alphabetize! (10 pts)

  • Open up Eclipse and create a new C++ project Alphabetize with a file called alphabetize.cpp.
  • Our program will take in two string inputs from the user, compare then and the output the two strings in alphabetical order.
  • At the top of your program, declare a string variables called word1.
string word1;
  • Now declare a second string variable called word2.
  • Next, write a cout statement welcoming your user to the program and letting them know that this program will alphabetize two words.
cout << "Welcome! Give me two words and I will return them to you in alphabetical order!\n";
  • Run your program to make sure it is giving you the output you expected.
  • Let's prompt the user for the first word and store the result as word1.
cout << "Please enter the first word: ";
cin >> word1;

  • Do the same for the second word.
  • Now, let's create an if-else statement to determine the ordering of the two words. And, then output the result to our user. The if-else statement will need to use string comparison as discussed above.

  • The code that you have written could be a useful part of a larger program. 
  • Both partners should submit to Canvas when finished.

Making Decisions Continued
  • Sometimes, you will need to make a decision in our code that involves more than 2 possible outcomes.
  • In this case we will use nested if statements.
  • These nested if statements will follow this format:
if (test) {
    //statements for the if
} else if (test) {
    //statements for the else if
}
    //additional else ifs when needed
else {
    //statements for the else
}



Nesting in the else Clause

  • When nesting if statements in the else clause, the computer can make only one selection
  • As soon as a condition is found to be true, the rest of the selections are ignored
  • The following code shows an example of a nested else if statement
  • For example:
    if (guess < 7)
    {
        cout << "Your guess is too low.\n";
    }
    else if (guess > 7)
    {
        cout << "Your guess is too high.\n";
    }
    else
    {
        cout << "*** Correct! ***\n";
    }
    
  • The trick in understanding this type of logic is to remember:
    • You start at the top
    • The computer makes only one selection
    • Once the selection is made and processes, the computer skips the rest of the options

Example Showing a Nested else if Statement

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;

int main() {
    int guess = 0;
    cout << "I'm thinking of a number between"
         << " 1 and 10.\nCan you guess it?\n\n"
         << "Enter your guess: ";
    cin >> guess;

    if (guess < 7) {
        cout << "Your guess is too low.\n";
    } else if (guess > 7) {
        cout << "Your guess is too high.\n";
    } else {
        cout << "*** Correct! ***\n";
    }

    return 0;
}

Programming Style: Indentation of if-else-if Statements

  • Note the alignment of the nested statements below:
    if (guess < 7)
    {
        cout << "Your guess is too low.\n";
    }
    else
    {
        if (guess > 7)
        {
            cout << "Your guess is too high.\n";
        }
        else
        {
            cout << "*** Correct! ***\n";
        }
    }
    
  • The above style is WRONG
  • Instead, we use:
    if (guess < 7)
    {
        cout << "Your guess is too low.\n";
    }
    else if (guess > 7)
    {
        cout << "Your guess is too high.\n";
    }
    else
    {
        cout << "*** Correct! ***\n";
    }
    
  • This shows more clearly that we are making a single choice among multiple alternatives
  • Also, it prevents indentations from cascading to the right as we add more selections

Multiple Alternatives

  • By using collections of if-else statements, a program can distinguish between multiple alternatives

Choosing Between Alternatives

  • This program has five alternatives to choose from:
    1. "penny"
    2. "nickel"
    3. "dime"
    4. "quarter"
    5. erroneous input
  • Note that the order that the alternatives are checked is unimportant
  • We can follow the alternatives in the flowchart shown below

Flowchart of Multiple Alternative for Converting Coins to Values

Image showing flow of control for coin program

  • For example, consider the following example where a user enters the name of a coin, and the program displays the value:

    Program Converting Coin Names to Values

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    #include <iostream>
    using namespace std;
    
    int main() {
        cout << "Enter coin name: ";
        string name;
        cin >> name;
        double value = 0;
    
        if (name == "penny") {
            value = 0.01;
        } else if (name == "nickel") {
            value = 0.05;
        } else if (name == "dime") {
            value = 0.10;
        } else if (name == "quarter") {
          value = 0.25;
        } else {
            cout << name << " is not a valid coin name\n";
        }
        cout << "Value = " << value << "\n";
    
        return 0;
    }

Activity 8.2: Grades (10 pts)

We want to write a program to calculate a student's letter grade according to the following table:

Numerical GradeLetter Grade
greater than or equal to 90A
less than 90 but greater than or equal to 80B
less than 80 but greater than or equal to 70C
less than 70 but greater than or equal to 60D
less than 60F
  • Find a partner for pair programming.
  • Open a new project in Eclipse called Grader with a file named grader.cpp. Change the comments to include your name, your partner's name and your section info.
  • Add code to get user input into a variable named score of type double. When you run the program after adding this code, the output should look like:
    Enter a score: 95.7
    

    Make sure you declare the variable with a compatible data type. Note that the underlined numbers above shows what the user enters and is not part of your code

  • First we will look at a series of if statements and see that if statements alone are not enough to solve this problem. Copy the following into your program after the input statements:
    string grade;
    if (score >= 90)
    {
       grade = "A";
    }
    if (score >= 80)
    {
       grade = "B";
    }
    if (score >= 70)
    {
       grade = "C";
    }
    if (score >= 60)
    {
       grade = "D";
    }
    if (score < 60)
    {
       grade = "F";
    }
        cout << grade << endl;

    Compile and run your modified program. There is a logic problem with this code. Each test condition needs to work over a range of values rather than with a single value.

  • Perhaps the most elegant solution to this problem is to nest an if statement in the else clause of the preceding if. Modify the series of if statements to include an else clause as shown below:

          string grade;
    if (score > = 90)
    {
        grade = "A";
    }
    else if (score >= 80)
    {
        grade = "B";
    }
    //you fill in the statements here
    else
    {
        grade = "F";
    }
    cout << grade << endl;


  • We are nesting if statements in the else clause. Nesting in the else clause makes each test condition of the if statement exclusive of the others because each test condition eliminates all the preceding conditions.
  • Compile and run your modified program to make sure you made the changes correctly. When you run the program, the output should look like:
    Enter a score: 80
    B
    

    Run your program a few times with different score to verify that any score displays the correct letter grade.

  • When finished, both partners should upload the program to Canvas.


When Order Matters

  • In some cases, the order of the tests is important
  • For example, look at the following program from the textbook that displays a description of the likely impact of an earthquake based on its magnitude on the Richter scale

Program Showing Multiple Alternatives Where Order Matters

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
using namespace std;

int main() {
    cout << "Enter a magnitude on the Richter scale: ";
    double richter;
    cin >> richter;

    if (richter >= 8.0) {
        cout << "Most structures fall\n";
    } else if (richter >= 7.0) {
        cout << "Many buildings destroyed\n";
    } else if (richter >= 6.0) {
        cout << "Many buildings considerably damaged, "
             << "some collapse\n";
    } else if (richter >= 4.5) {
        cout << "Damage to poorly constructed buildings\n";
    } else if (richter >= 3.5) {
        cout << "Felt by many people, no destruction\n";
    } else if (richter >= 0) {
        cout << "Generally not felt by people\n";
    } else {
        cout << "Negative numbers are not valid\n";
    }

    return 0;
}

Order Is Important

  • Note that the order of the tests is important to ensure that the right results are printed
  • If we rearranged the order of the if-else statements, we would get the wrong results
  • For example, if we reversed the order of the tests:
    if (richter >= 0) { // tests in wrong order
        cout << "Generally not felt by people\n";
    } else if (richter >= 3.5) {
        cout << "Felt by many people, no destruction\n";
    } else if (richter >= 4.5) {
        cout << "Damage to poorly constructed buildings\n";
    } else if (richter >= 6.0) {
        cout << "Many buildings considerably damaged, "
             << "some collapse\n";
    } else if (richter >= 7.0) {
        cout << "Many buildings destroyed\n";
    } else if (richter >= 8.0) {
        cout << "Most structures fall\n";
    } else {
        cout << "Negative numbers are not valid\n";
    }
    
  • This does not work because all values meet the first condition
  • Every other test will never be attempted

Importance of Using if-else-if Structure

  • Note that we cannot remove the else portion of the structure like shown below:
    if (richter >= 8.0) { // Does not use else
        cout << "Most structures fall\n";
    }
    if (richter >= 7.0) {
        cout << "Many buildings destroyed\n";
    }
    if (richter >= 6.0) {
        cout << "Many buildings considerably damaged, "
             << "some collapse\n";
    }
    if (richter >= 4.5) {
        cout << "Damage to poorly constructed buildings\n";
    }
    if (richter >= 3.5) {
        cout << "Felt by many people, no destruction\n";
    }
    if (richter >= 0) {
        cout << "Generally not felt by people\n";
    }
    if (richter < 0) {
        cout << "Negative numbers are not valid\n";
    }
    
  • The conditions must be exclusive and we need the else-if conditions to ensure exclusivity
  • Independent if statements may cause a single input to print several messages



Wrap Up
  • Find a partner and answer the questions from today's learning objectives

Upcoming Assignments