You have now some experience formulating conditions and using them to solve real problems. As to more complex problems, what you often need is to assemble your condition out of two or more partial conditions. This is what you will study in this chapter.
Yes or No
Your first use of compound conditions will be to check that the user input belongs to one of the allowed alternatives.
Task
You will write a program that checks whether the user entered either yes or no. All other inputs will be considered incorrect (see Figures 17-1 and 17-2).
Figure 17-1 Acceptable answer but sad
Figure 17-2 Yes!
Solution
Here’s the code:
static void Main(string[] args)
{
// Input
Console.Write("Do you love me? ");
string input = Console.ReadLine();
// Evaluating
string inputInSmall = input.ToLower();
if (inputInSmall == "yes" || inputInSmall == "no")
{
Console.WriteLine("OK.");
}
else
{
Console.WriteLine("Say it straight!");
}
// Waiting for Enter
Console.ReadLine();
}
Discussion
Note the following:
To disregard the difference in case, you convert the input to lowercase letters.
The condition used is a compound condition. It consists of two partial conditions connected using the conditional OR operator, which is typed as || (two vertical lines).
The condition is fulfilled (and the if branch is executed) if at least one of the partial conditions is fulfilled. This means the user entered either yes or no. In this case, the alternatives are mutually exclusive. However, you will encounter cases when both conditions can be fulfilled simultaneously.
The condition is not fulfilled (and the else branch is executed) if neither the first nor the second partial condition is fulfilled. In other words, the user entered something besides yes or no .
Username and Password
Now you will look at partial conditions that should always be fulfilled simultaneously.
Task
You will write a program that checks whether the user entered the correct username (Orwell) and at the same time the correct password (Catalonia). The username is case-insensitive, meaning it can be lowercase and uppercase (see Figures 17-3 and 17-4).
Figure 17-3 Correct username but incorrect password
Figure 17-4 Correct username and password
Solution
Here is the code:
static void Main(string[] args)
{
// Correct values
string correctUsername = "Orwell";
string correctPassword = "Catalonia";
// Inputs
Console.Write("User name: ");
string enteredUserName = Console.ReadLine();
Console.Write("Password: ");
string enteredPassword = Console.ReadLine();
// Evaluating
if (enteredUserName.ToLower() == correctUsername.ToLower() &&
enteredPassword == correctPassword)
{
Console.WriteLine("Thanks for your books!");
}
else
{
Console.WriteLine("Could not log you in.");
}
// Waiting for Enter
Console.ReadLine();
}
Discussion
Note the following:
The condition used is a compound condition again. Its partial conditions are connected using the conditional AND operator, which is typed as && (two ampersands).
The condition is fulfilled (and the if branch is executed) if both partial conditions are fulfilled simultaneously. This means the user has to enter both the correct username and the correct password.
To not fulfill the condition (and thus execute the else branch), it is enough to not fulfill either one of the partial conditions .
Two Users
You can even combine several AND and OR operators to get a really complex compound condition. Take a look!
Task
You will modify the previous task to allow two possible users to log in. Both will have their own passwords.
Solution
Here is the code:
static void Main(string[] args)
{
// Correct values
string correctUsername1 = "Orwell";
string correctPassword1 = "Catalonia";
string correctUsername2 = "Blair";
string correctPassword2 = "1984";
// Inputs
Console.Write("User name: ");
string enteredUsername = Console.ReadLine();
Console.Write("Password: ");
string enteredPassword = Console.ReadLine();
// Evalulating
if (enteredUsername.ToLower() == correctUsername1.ToLower() &&
enteredPassword == correctPassword1 ||
enteredUsername.ToLower() == correctUsername2.ToLower() &&
enteredPassword == correctPassword2)
{
Console.WriteLine("Thanks for your books!");
}
else
{
Console.WriteLine("Could not log you in.");
}
// Waiting for Enter
Console.ReadLine();
}
Discussion
Note the following:
You can combine both conditional operators: AND with OR.
Fulfillment of the complete condition requires the user to enter the correct first username and the correct first password or the correct second username and the correct second password.
The condition intentionally uses a higher priority (precedence) for the AND operator compared to the OR operator. Specifically, both potential users are evaluated first, and the partial results are ORed afterward.
If you need a different evaluation order, just use parentheses (round brackets) similarly to mathematics.
Precalculation of Conditions
The compound condition in the previous exercise is already quite complex. To understand this, you must concentrate on it. In similar situations, it may be better to precalculate (calculate in advance) partial conditions. This is what I am going to show you now.
Task
The task is the same as the previous one, but the solution will be different.
Solution
Here is the code:
static void Main(string[] args)
{
// Correct values
string correctUsername1 = "Orwell";
string correctPassword1 = "Catalonia";
string correctUsername2 = "Blair";
string correctPassword2 = "1984";
// Inputs
Console.Write("User name: ");
string enteredUsername = Console.ReadLine();
Console.Write("Password: ");
string enteredPassword = Console.ReadLine();
// Evaluating
bool user1ok = enteredUsername.ToLower() == correctUsername1.ToLower() &&
enteredPassword == correctPassword1;
bool user2ok = enteredUsername.ToLower() == correctUsername2.ToLower() &&
enteredPassword == correctPassword2;
if (user1ok || user2ok)
{
Console.WriteLine("Thanks for your books!");
}
else
{
Console.WriteLine("Could not log you in.");
}
// Waiting for Enter
Console.ReadLine();
}
Discussion
Note the following:
You check both users one after another. The main condition can then be written in a clear and concise way.
Partial conditions are precalculated into variables of type bool. When a condition is fulfilled, the corresponding variable has its value set to true.
Yes or No Reversed
You learned about reversing conditions already in Chapter 15. In that chapter, the condition was simple. Now you will reverse a compound condition, which is a bit trickier and requires greater care.
Task
You will return to the “Yes or No” project from the beginning of this chapter once again. For the purpose of practicing compound conditions, think about how you would reverse the original condition to swap the if and else branches.
Solution
Here is the code:
static void Main(string[] args)
{
// Input
Console.Write("Do you love me? ");
string input = Console.ReadLine();
// Evaluating
string inputInSmall = input.ToLower();
if (inputInSmall != "yes" && inputInSmall != "no")
{
Console.WriteLine("Say it straight!");
}
else
{
Console.WriteLine("OK.");
}
// Waiting for Enter
Console.ReadLine();
}
Discussion
Note the following:
Instead of checking the correct input, you now check the incorrect one.
The input is incorrect when it neither equals yes nor no.
Reversing the condition caused the OR operator to change into the AND operator. It also caused the equalities to change into inequalities.
Grade Check
Now I would like to turn your attention to a frequent test of a number belonging to a specified set, or a specified range. The following two tasks concern this.
Task
The user enters a grade of a student. The program will check then whether the entered number is in the set of possible values 1, 2, 3, 4, or 5 (see Figure 17-5 and Figure 17-6).
Figure 17-5 Within the range
Figure 17-6 Not within the range
Solution
The condition can be formulated enumerating the individual alternatives. For the sake of simplicity, I do not check for possible non-numeric input. You can handle this yourself using try-catch as usual.
Here is the code:
static void Main(string[] args)
{
// Input
Console.Write("Enter a grade: ");
string input = Console.ReadLine();
int grade = Convert.ToInt32(input);
// Evaluating
if (grade == 1 ||
grade == 2 ||
grade == 3 ||
grade == 4 ||
grade == 5)
{
Console.WriteLine("Input OK.");
}
else
{
Console.WriteLine("Incorrect input.");
}
// Waiting for Enter
Console.ReadLine();
}
Better Range Check
The allowed numbers (possible grades) actually constitute a range of 1 to 5 (a continuous range without gaps). In such a case, you can use a better way to check whether a number belongs to a specific range or not.
Task
The task is to solve the previous exercise using a range check.
Solution
A number belongs to a range given by its lower and upper bounds when it is greater than or equal to the lower bound and at the same time it is less than or equal to the upper bound.
Here is the code:
static void Main(string[] args)
{
// Input
Console.Write("Enter a grade: ");
string input = Console.ReadLine();
int grade = Convert.ToInt32(input);
// Evaluating
if (grade >= 1 && grade <= 5)
{
Console.WriteLine("Input OK.");
}
else
{
Console.WriteLine("Incorrect input.");
}
// Waiting for Enter
Console.ReadLine();
}
Summary
This chapter introduced you to the topic of compound conditions. You learned that the if statement condition can be compounded by several partial conditions joined together using conditional AND and conditional OR operators.
In C#, the AND operator is written as &&, and it evaluates to true when both partial conditions are fulfilled. On the other hand, the OR operator is written as ||, and it evaluates to true when at least one of the partial conditions is fulfilled.
You also saw a larger number of partial conditions combined into a single one. In this case, the question of operator precedence is important. With no parentheses, the AND is always evaluated before the OR. Note, however, that such conditions can become rather complex and difficult to read. It is advisable to calculate parts of the whole condition separately in advance and store them temporarily in bool-typed variables.
I also tried to bring your attention to the problem of reversing compound conditions, which requires extra care and concentration to do it right. Specifically, you learned that when reversing, the ANDs are toggled into ORs (and vice versa), and equalities change into inequalities (and vice versa).
Finally, I showed you how to check whether a number belongs either to a specified set or to a specified range. In the latter case, you perform simultaneous tests against lower and upper bounds of the range.