© Radek Vystavěl 2017

Radek Vystavěl, C# Programming for Absolute Beginners, https://doi.org/10.1007/978-1-4842-3318-4_19

19. Advanced Conditions

Radek Vystavěl

(1)Ondřjov, Czech Republic

The third part of this book concludes with several tasks concerning conditional execution that may be considered advanced. First you will study the conditional operator, then you will write a program containing several complex conditions, and finally you will learn about an important maxim: when you want to test something, you must be sure it exists.

Conditional Operator

In many cases, the if-else construction can be replaced with the conditional operator, which results in one of the two values depending on whether a condition is or is not fulfilled. If you know the IF function of Excel, you will find the conditional operator familiar.

Task

You will solve the former “Head and Tail” task (from Chapter 16) using the conditional operator (see Figure 19-1).

A458464_1_En_19_Fig1_HTML.jpg
Figure 19-1 Using the conditional operator

Solution

Here’s the code:

static void Main(string[] args)
{
    // Random number generator
    Random randomNumbers = new Random();


    // Random number 0/1 and its transformation
    int randomNumber = randomNumbers.Next(0, 1 + 1);
    string message = randomNumber == 0 ? "Head tossed" : "Tail tossed";
    Console.WriteLine(message);


    // Waiting for Enter
    Console.ReadLine();
}

Discussion

The conditional operator (?:) syntax looks like this:

  • condition ? yesValue : noValue

The result of such an expression is as follows:

  • yesValue if the condition holds (is fulfilled)

  • noValue otherwise

The Program

In this case, the condition is an equality test of the randomNumber variable against zero. If it is true, the message variable is assigned the “Head tossed” text. Otherwise, it is assigned the “Tail tossed” text.

Terminology

The conditional operator is also called a ternary operator since it is the only operator that accepts three operands (values it works with): a condition, a yesValue, and a noValue.

Summary Evaluation

Now you will exercise more complex conditions in a realistic situation.

Task

The task is to write a program for summary evaluation of a student (see Figure 19-2). The user enters grades from four subjects (in the range 1 to 5, with 1 being the best). The user also specifies whether the student being considered had some unexcused absences or not. The program then gives a summary evaluation, which is a kind of overall score.

  • Excellent

  • Good

  • Failed

A458464_1_En_19_Fig2_HTML.jpg
Figure 19-2 Summary evaluation of a student

Details

I emphasized in Chapter 18 that to be able to program anything, you need to exactly understand the task being solved. In the current exercise, you need to specify the exact criteria for summary evaluation.

A student has an Excellent evaluation when

  • The arithmetic average of all the grades is not higher than 1.5

  • The student does not have any grade worse than 2

  • The student does not have any unexcused absences

The student is considered Failed when at least one of her grades is 5.

In all other cases, the summary evaluation is Good.

You can probably guess now that the program is not going to be trivial.

Solution

Here’s the code:

static void Main(string[] args)
{
    // 1. PREPARATIONS
    string errorMessage = "Incorrect input";
    int mathematics, informationTechnology, science, english;
    bool hasUnexcusedAbsences;


    // 2. INPUTS
    try
    {
        Console.WriteLine("Enter grades from individual subjects:");


        Console.Write("Mathematics: ");
        string input = Console.ReadLine();
        mathematics = Convert.ToInt32(input);
        if (mathematics < 1 || mathematics > 5)
        {
            Console.WriteLine(errorMessage);
            return;
        }


        Console.Write("Information technology: ");
        input = Console.ReadLine();
        informationTechnology = Convert.ToInt32(input);
        if (informationTechnology < 1 || informationTechnology > 5)
        {
            Console.WriteLine(errorMessage);
            return;
        }


        Console.Write("Science: ");
        input = Console.ReadLine();
        science = Convert.ToInt32(input);
        if (science < 1 || science > 5)
        {
            Console.WriteLine(errorMessage);
            return;
        }


        Console.Write("English: ");
        input = Console.ReadLine();
        english = Convert.ToInt32(input);
        if (english < 1 || english > 5)
        {
            Console.WriteLine(errorMessage);
            return;
        }


        Console.Write("Any unexcused absences? (yes/no): ");
        input = Console.ReadLine();
        input = input.ToLower(); // not distinguishing upper/lower
        if (input != "yes" && input != "no")
        {
            Console.WriteLine(errorMessage);
            return;
        }
        hasUnexcusedAbsences = input == "yes";
    }
    catch (Exception)
    {
        Console.WriteLine(errorMessage);
        return;
    }


    // 3. EVALUATION
    // You need arithmetic average of all the grades
    double average = (mathematics + informationTechnology + science + english) / 4.0;
    string message;


    // Testing all conditions for excellence
    if (average < 1.5001 &&
        mathematics <= 2 && informationTechnology <= 2 &&
        science <= 2 && english <= 2 &&
        !hasUnexcusedAbsences)
    {
        message = "Excellent";
    }
    else
    {
        // Here you know the result is not excellent, so testing the other two possibilities
        if (mathematics == 5 || informationTechnology == 5 ||
            science == 5 || english == 5)
        {
            message = "Failed";
        }
        else
        {
            message = "Good";
        }
    }


    // 4. OUTPUT
    Console.WriteLine("Summary evaluation: " + message);


    // Waiting for Enter
    Console.ReadLine();
}

Discussion

The following sections explain the program.

Grade Inputs

In this exercise, you thoroughly care about doing an input data check. A try-catch wraps the whole input section. You also need to check whether the grades belong in the 1 to 5 range.

Note that a grade less than 1 or greater than 5 signalizes an error. You use the || operator (“at least one”).

Program Termination

An erroneous input terminates the program immediately. You use the return statement here that terminates a subprogram in general. However, when used inside Main, it directly terminates the whole program.

Yes/No Input

To enter whether the student had some unexcused absences, the user enters either yes or no. The input difference from both yes and no signalizes an error. I use && operator (“at the same time”).

Before the check, you convert the input into lowercase so that it does not mind when the user uses capital letters.

What is interesting is the line containing both single and double equal signs (single for assignment, double for comparison):

hasUnexcusedAbsences = input == "yes";

The “work” of the == operator results in either a true or false value according to whether the equality holds. The resulting value is then assigned into the bool-typed hasUnexcusedAbsences variable .

Beware of Integer Division !

When calculating the grade average, you divide the sum by the value of 4.0, not by the value of 4. You do not want the computer to consider the slash as an integer division operator. That is why you are avoiding the division of int by int.

If you entered just 4, then the case of 1, 2, 2, 2 grades would be mistakenly evaluated as Excellent since the average would be calculated to a precise 1 instead of the correct 1.75!

Decimal Arithmetic

Why did you enter the check of the average as follows?

average < 1.5001

Why didn’t you use the following?

average <= 1.5

?

It was because decimal arithmetic does not have to be precise. Sometimes it is possible that the computer calculates something like 1.500000000001 instead of the correct 1.5. That is why you use a little bit greater number in the test.

Second Character Test

Many programs crash because a programmer forgot to test that something exists before accessing it. This task will be your first acquaintance with this frequent issue.

Task

I will show you how to test the second character of the entered text. Let’s say a product label has to always have a capital X in the second position (see Figure 19-3 and Figure 19-4).

A458464_1_En_19_Fig3_HTML.jpg
Figure 19-3 Testing the second character, correct
A458464_1_En_19_Fig4_HTML.jpg
Figure 19-4 Testing the second character, incorrect

Why is such a test so important that I have decided to get you acquainted with it? You need to test first whether the second character exists at all. This is what you will often meet; you will not be able to test something until you have found that something exists!

In this case, the program must not crash upon empty or too short input (see Figure 19-5).

A458464_1_En_19_Fig5_HTML.jpg
Figure 19-5 Incorrect label, not crashing

Solution

Here’s the code:

static void Main(string[] args)
{
    // Input
    Console.Write("Enter product label: ");
    string label = Console.ReadLine();


    // Evaluating
    if (label.Length >= 2 && label.Substring(1, 1) == "X")
    {
        Console.WriteLine("Label is OK");
    }
    else
    {
        Console.WriteLine("Incorrect label");
    }


    // Waiting for Enter
    Console.ReadLine();
}

Discussion

The following sections explain the program .

Getting the Character

You access the second character using the Substring method that generally pulls a specific part (substring) out of the given text. The method requires two parameters.

  • The position of the first character of the required substring. The position numbering starts with zero, so the second character position is 1.

  • The number of characters of the required substring. In this case, what you need is just a single character, which is why the second parameter is 1, too.

Existence Test

The test of whether a given character equals something has a hidden catch: the second character does not have to exist at all. This happens when the user enters zero or one character.

In such a case, the Substring(1,1) call would cause a runtime error.

This means you have to test first whether the text is at least two characters long. Only if this test passes can you access the second character.

There is a compound condition in the code, as shown here:

if (label.Length >= 2 && label.Substring(1, 1) == "X")

Its functioning relies upon the short-circuit evaluation of the && operator. If the first partial condition of an AND join does not hold, the second one is not evaluated at all, since it is useless. Even if it held, it would not change the overall result because the AND operator requires both parts to hold simultaneously.

In this case, when the length of a label is less than 2, then the Substring call, which would fail, is skipped, and the program does not crash!

Note that an analogous statement can be made about the || operator, too.

An Experiment

Try to omit the first partial condition (the length check). Then enter a single character as a user. The program would terminate with a runtime error. This way you will see that the first condition really is important.

Summary

In this chapter, you studied several examples of advanced conditions.

You started with the so-called conditional operator (?:), which is also called a ternary operator because it works with three values. Depending on fulfillment of the specified condition (the first value, before the question mark), the operator’s “work” results in either yesValue (the second value, between the question mark and the colon) or noValue (the third value, after the colon). The conditional operator is a suitable shortcut replacement for certain types of if-else situations.

The middle task of summary evaluation was a kind of recap of all the things you learned about conditional execution. There you have met various tests and many compound conditions, as well as negation with the ! operator.

The final task of testing the second character of some text has shown you the importance of testing that the second character exists at all before you explore what it is. There you used the short-circuit evaluation of conditions. If the result of a compound condition can be decided already after the first partial condition is evaluated, then the second partial condition is skipped altogether.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.225.255.187