Chapter 3: Logic and Decision Making
Written by Andrei Guevorkian on 2023-10-05. Illustrated by Dengyijia Liu
In our everyday lives, we make countless decisions based on conditions: if it rains, take an umbrella; if it's cold, wear a jacket. Similarly, in programming, decision-making is a crucial aspect, enabling the program to react differently to different inputs or situations.
Table of Contents
Introducing Pseudocode and Decision-Making in Programs
From Math to Everyday Decisions
A Brief Review of Transistors
Imagine a tiny switch, so small that millions of them could fit on the tip of your finger. This is a transistor. It's a device that can either allow an electric current to flow through it (like turning on a light) or stop it entirely (like turning the light off).
A transistor.
In essence, a transistor has two primary states:
- On: This is when it allows electricity to pass through. We can liken this to opening a faucet and letting water flow.
- Off: This is when it prevents electricity from flowing, similar to closing a faucet to stop the water.
The Binary Nature of Transistors
The fact that a transistor has only two states introduces us to a fundamental concept: "binary." In the realm of computers, binary refers to the system of representing values using only two symbols, usually 0 and 1. In the case of our transistor, "on" can be thought of as "1", and "off" as "0".
Note: The term 'binary' focuses on two states. In contrast, "unary" describes one state, "ternary" represents three states, and "quadrinary" means four states. However, computers primarily use binary logic because of the inherent on/off nature of electrical circuits and transistors.
Connecting Transistors to Programming: Boolean Values
When you start programming, you'll encounter a concept called "boolean values." Named after George Boole, a 19th-century mathematician, booleans in programming have just two values: "True" and "False".
Do you see the parallel? Just as a transistor can be "on" (1) or "off" (0), a boolean value can be True
(equivalent to 1) or False
(equivalent to 0).
To grasp the significance of booleans, think about how we evaluate statements in our daily life. For instance, the statement "The sky is blue" can be true during a clear day, but false during the night. Similarly, in programming, boolean values emerge from evaluating conditions or statements.
Note: A statement is a sentence or expression that can be evaluated as either true or false, but not both. In programming, statements provide a way to represent facts or conditions that the computer can then use to make decisions.
Take the example "5 is greater than 4". When a computer processes this statement, it evaluates the condition and concludes it to be True
. In contrast, the statement "6 is greater than 4 and less than 3" is contradictory, and thus, it evaluates to False
.
Programming uses this true or false logic for decision-making, fundamentally connecting the physical world of transistors with the logical realm of booleans.
Introducing Pseudocode and Decision-Making in Programs
Pseudocode is a method to design and represent algorithms without the strict structure of a particular programming language. It allows programmers to focus on logic and flow, without worrying about the syntax of any specific programming language.
Before writing some pseudocode, there are a few topics we should cover first.
Comparison Operators
Before delving into the pseudocode, let's familiarize ourselves with some basic comparison operators used in decision-making:
- > : Greater than.
5 > 3
results inTrue
.2 > 8
results inFalse
.
- < : Less than.
2 < 4
results inTrue
.6 < 3
results inFalse
.
- == : Equal to.
7 == 7
results inTrue
.5 == 8
results inFalse
.
- != : Not equal to.
5 != 8
results inTrue
.7 != 7
results inFalse
.
- <= : Less than or equal to.
4 <= 5
results inTrue
.7 <= 7
results inTrue
.9 <= 6
results inFalse
.
- >= : Greater than or equal to.
6 >= 3
results inTrue
.8 >= 8
results inTrue
.4 >= 10
results inFalse
.
Note: We use
==
to check for equality in most programming languages instead of=
. The reason for this will become clear in the next chapter, where we will see=
used for something else. For now, remember to use==
when making comparisons.
These operators help us compare values and determine the relationship between them. They're fundamental to setting up conditions in our code.
Logical Operators
Beyond simple comparisons, we often need to check multiple conditions at once or invert the logic of a condition. This is where logical operators come in. The three primary logical operators are AND
, OR
, and NOT
.
AND
: Both conditions must result inTrue
for the overall statement to result inTrue
.- The statement
5 > 3 AND 6 > 4
results inTrue
because both individual conditions result inTrue
. - However,
5 > 3 AND 6 < 4
isFalse
because even though the first condition isTrue
, the second isFalse
.
- The statement
OR
: At least one condition must result inTrue
for the overall statement to beTrue
.- The statement
5 > 3 OR 6 < 4
isTrue
because at least one of the conditions (the first one) isTrue
. 2 < 1 OR 3 < 2
isFalse
because both individual conditions areFalse
.
- The statement
NOT
: Inverts the truth value of the condition.- A statement such as
5 > 3
isTrue
. UsingNOT
inverts this, making the statementNOT(5 > 3)
result inFalse
. - Conversely, the statement
2 > 3
which isFalse
, thereforeNOT(2 > 3)
will beTrue
.
- A statement such as
These operators allow for more complex conditions and evaluations. For instance, imagine you're programming a system that checks if a user is allowed to view a specific piece of content. You might have conditions like:
- The user must be logged in AND the user must have a premium subscription.
- The content must be available in the user's region OR the user has a "global pass".
Using logical operators like AND, OR and NOT helps us set up complex conditions for making decisions in our programs. They allow us to mirror real-life decision-making in our code.
From Math to Everyday Decisions
Until now, our examples have primarily focused on numbers. However, programming isn't confined to mathematical operations. Often, the conditions we evaluate are abstract, representing real-world scenarios. The logical structure remains consistent, regardless of whether you're comparing numbers or determining whether it's raining.
For instance, raining
might be a variable in our program representing whether it's raining or not. If it's raining, raining
is True
; if not, raining
is False
. Another variable, temperature
, could represent the current temperature.
Explanation of variables: Think of these variables as containers. Instead of holding a fixed value, like a constant temperature of 25°C, variables can vary; they can hold different values at different times. For instance,
temperature
could be25°C
today and23°C
tomorrow. Similarly, today the variableraining
might beTrue
, but tomorrow it could beFalse
.
When programming real-world applications, we use variables like raining
or temperature
to symbolize and manage real-world data. Our decision-making constructs and logical operators interact with these variables in the same way they would with regular numbers.
Important: In programming, a "construct" is a fundamental piece or feature of the language that serves as a building block. Constructs provide a way to introduce structure, repetition, decision-making, and more into our code. For decision-making, common constructs are
if
,else
, andelse if
(sometimes written aselif
). They are very intuitive and you will see them in action in the Activities section below.
This dynamic nature of variables lets our programs react and make decisions based on the current situation or data, whether that data represents numbers, weather conditions, user inputs, or any other conceivable scenario.
With this understanding, we can now delve into real-world problems like deciding whether to hold an outdoor event based on the weather forecast.
Activities
We will be answering these questions using pseudocode. You are not expected to be able to answer these on yor own just yet.
Activity #1
Write a program that evaluates a number to determine if it's positive, negative, or zero.
Possible Answer #1
We start by taking an input (from the user, for example):
INPUT number
Next, we must decide what to do based on the number's value. This is where the if .. then:
construct comes in.
If the number is greater than zero, we can say it's positive:
if number > 0 then:
PRINT "The number is positive."
In programming, the term "print" refers to displaying text or other data on the screen, rather than producing a physical copy with a printer. It's a command used to output information to the user.
But what if it's not? We need another check, and that's where else if
proves useful. It's like saying, "if the previous conditions weren't met, then check this one".
If the number is less than zero, it's negative:
else if number < 0 then:
PRINT "The number is negative."
Lastly, if the number isn't positive or negative, it must be zero. That's where else
comes in. It's our catch-all for "if none of the above conditions are met, do this":
else:
PRINT "The number is zero."
And, to neatly conclude our decision-making constructs, we use:
END if
Putting it all together, we have
INPUT number
if number > 0 then:
PRINT "The number is positive."
else if number < 0 then:
PRINT "The number is negative."
else:
PRINT "The number is zero."
END if
By outlining logic in pseudocode, transitioning to actual coding in any programming language becomes a smoother process, as the core logic remains consistent.
Possible Answer #2
There are often multiple ways to solve a problem, with the solution varying based on how conditions are evaluated and in what order. Without going into all the steps, here is the final pseudocode:
INPUT number
if number == 0 then:
PRINT "The number is zero."
else if number > 0 then:
PRINT "The number is positive."
else:
PRINT "The number is negative."
END if
In this approach, we first check if number
equals 0. If not, we then determine if number
is greater than 0. Finally, the else statement handles any remaining scenarios, which in this case, are when number
is less than 0.
Activity #2
Suppose you're organizing an outdoor event. You'll proceed if:
- The forecast does not predict rain.
- The temperature is between 18°C and 30°C.
Write corresponding pseudocode for such a program.
Answer
Evaluating Rain Forecast:
We want to check if it's "not raining". Here's how we can understand the NOT raining
condition:
- The
raining
variable would beTrue
if it's raining andFalse
if it isn't. - Using
NOT
in front ofraining
inverts its truth value. So, ifraining
isTrue
,NOT raining
becomesFalse
, and vice versa. - For our event to proceed, we want it to be the case where it's not raining, so we're looking for the scenario where
NOT raining
isTrue
.
In pseudocode:
if NOT raining:
Evaluating Temperature: We want the temperature to be between 18°C and 30°C. In other words, we want the following condition to be True:
temperature >= 18 AND temperature <= 30
Combining both conditions, our complete decision-making pseudocode becomes:
if NOT raining AND (temperature >= 18 AND temperature <= 30) then:
proceed_with_event
else:
reschedule_event
END if
By breaking down our conditions in this way, we ensure that the event only proceeds if it's not raining and the temperature is within our desired range.
Questions
Question 1
You're creating an automatic plant watering system. The plant should be watered if:
- The soil is dry.
- It's daytime.
Write pseudocode to determine whether the plant should be watered or not.
Question 2
You're building an alarm system for your home. The alarm should sound if:
- A window or door is opened.
- The system is armed.
Write pseudocode for this scenario.
Question 3
Design a program that categorizes a student's grade. The program should:
- Display "Excellent" for scores 90 and above.
- Display "Good" for scores between 70 and 89.
- Display "Average" for scores between 50 and 69.
- Display "Fail" for scores below 50.
Write the corresponding pseudocode to determine and display the student's category based on the score.