Sitemap
Gideon Oludeyi

Gideon Oludeyi

Passionate about learning and teaching

Python Basics: Logical Operations

Boolean operators — Part 2

7 min readNov 3, 2022

--

Press enter or click to view image in full size
Photo by Fran Jacquier on Unsplash

In the previous article, we saw how Booleans enable us to make decisions depending on some given value: wear a sweater if the outdoor temperature is below 0°C. You can start to see how this might enable our programs to exhibit more complex behaviors.

Have you ever opened your favorite social media app, only to be faced with a login page? Depending on whether you were previously logged in, you might immediately see a list of posts for you to browse, or may be redirected back to a login page.

This functionality could be implemented using Boolean variable is_logged_in that indicates whether the user is already authenticated with the app. However, the computation required to determine this value of is_logged_in, is more complicated than comparing two numbers.

Logical Operators

By introducing a new type of Boolean operators, we can define more interesting and useful conditions. By composing simpler conditions together, we can build more complex conditions. This type of Boolean operations are called Logical Operations.

Recall that relational operators (e.g. < — less than) receive two numbers to produce a Boolean result (True or False). Similar to how addition combines a pair of numbers into a single number, relational operations combine a pair of numbers into a single Boolean value.

1 < 2 # True

Logical operators, on the other hand, combine Boolean inputs into a single Boolean value. If you remember from high-school math, you can think of relational operators as functions with a domain of real numbers and range of Booleans, while logical operators as functions with a domain of Booleans and range of Booleans.

There are 3 logical operators in Python: and or and not. In Boolean algebra, these operators are known as Conjunction, Disjunction, and Negation respectively.

AND Operator

The and operator receives two Booleans inputs and evaluates to True only if both inputs are True, otherwise it evaluates to False.

+-------+-------+---------+
| A | B | A and B |
+-------+-------+---------+
| True | True | True |
| False | True | False |
| True | False | False |
| False | False | False |
+-------+-------+---------+

Note: this table is called a truth table which generates the result of the operation for every combination of Boolean inputs A and B.

OR Operator

The or operator receives two Boolean inputs and evaluates to True if at least one of the inputs is True, otherwise it evaluates to False.

+-------+-------+--------+
| A | B | A or B |
+-------+-------+--------+
| True | True | True |
| False | True | True |
| True | False | True |
| False | False | False |
+-------+-------+--------+

Note: OR is not the opposite of AND

NOT Operator

The not operator receives one Boolean input and evaluates to the opposite. In other words, it negates the input. You can think of it as multiplication by -1, but for Booleans.

+-------+-------+
| A | not A |
+-------+-------+
| True | False |
| False | True |
+-------+-------+

Notable Boolean Laws

There are some interesting Boolean expressions you may come across when dealing with logical operations.

Double Negation

If you have an expression not (not A) where A is a Boolean value, then the result is simply A. This simply means the opposite of the opposite is the original. Similar to how multiplying a number by -1 twice, gives you the original number.

+-------+-------+-------------+
| A | not A | not (not A) |
+-------+-------+-------------+
| True | False | True |
| False | True | False |
+-------+-------+-------------+

Note how A and not (not A) are the same for any possible Boolean value. This means that anywhere you see a not (not A), you can safely replace it with A and it will function exactly the same way.

AND Annihilator

If you have an expression A and F, where F always evaluates to False, then the result is always False, regardless of the value of A.

+-------+-------+---------+
| A | F | A and F |
+-------+-------+---------+
| True | False | False |
| False | False | False |
+-------+-------+---------+

OR Annihilator

If you have an expression A or T, where T always evaluates to True, then the result is always True, regardless of the value of A.

+-------+------+--------+
| A | T | A or T |
+-------+------+--------+
| True | True | True |
| False | True | True |
+-------+------+--------+

Note: there are several more of these laws if you’re interested, and I personally find De Morgan’s Laws the most useful for simplifying complicated expressions.

Example (User Registration)

With the help of logical operators, we can compose simple conditions together to produce more complex conditions.

Suppose we want to build an app that allows for users to signup, and there are two options for creating an account: Email/Password, or Continue with Google.

At the final step of the signup process, we want to ensure that the app has been provided valid information before creating the user’s account.

Get Gideon Oludeyi’s stories in your inbox

Join Medium for free to get updates from this writer.

For the Email/Password option, the email should be valid, and the password should be at least 8 characters long.

For the Continue with Google option, the user should already be logged in to Google on their device, so they can immediately register with the click of a button.

Suppose we have these 4 variables: email_is_valid, password_length, clicked_continue_with_google, already_logged_in_to_google.

The variable, email_is_valid tells the program whether the email provided by the user is valid.

The password_length variable represents the number of characters in the user’s password. We’ll need some way of comparing whether it is long enough (can you think of an operation that will help us?)

The already_logged_in_to_google variable tells the program whether the user has already logged in to Google on the device in the past.

The clicked_continue_with_google variable tells the program whether the user wants to use Google for registration. Some users may want to use a different email from their Google account.

The final variable, should_create_account, derived from these variables, should be True if the program has valid information to create an account.

Let’s work our way backwards starting from should_create_account.

We know there are only 2 possible ways a user can register with the app: either by Email/Password, OR Google. So let’s have a Boolean variable for these 2 cases.

Press enter or click to view image in full size
Signup Options

Notice our use of OR in explaining how the signup options relate to should_create_account.

Press enter or click to view image in full size
Final Boolean expression

This means we should create the user’s account if they decide to signup with Email/Password, OR signup with Google.

Email/Password

Let’s tackle each of these options one at a time, starting with use_email_and_password.

We know that a user wants to register with email and password if they provide a valid email AND a password greater-than or equal to 8 characters.

Press enter or click to view image in full size
Email/Password Option

Notice the similarity between how we are describing the behavior with words, and the actual Python implementation.

Continue with Google

For the use_google option, we know that a user can register using their Google account if they clicked the Continue with Google button AND are already logged in to Google on their device.

Press enter or click to view image in full size
Continue with Google Option

Signup Validation

Putting it all together, we get the following:

Press enter or click to view image in full size
All together (signup validation)

I could have skipped the intermediate use_* variables, and gone straight to the final expression, but I personally think it is not as clear.

Press enter or click to view image in full size
Concise form (signup validation)

The variables names use_email_and_password and use_google tell you what each expression is doing, whereas this form is not immediately clear.

We started with 4 variables (one of which was a number), and like building blocks, we composed them together to produce a final Boolean expression that validates the user’s registration form.

Bonus (Unique email constraint)

We were not able to showcase the not operator in this example, but it is still an important operator. For example, we could enforce that the provided email be unique by modifying use_email_and_password to the following:

Press enter or click to view image in full size
Unique email constraint

Now a new user won’t be able to register with an email that has already been used.

Operator Precedence

Like other Python operators, logical operators have an order of precedence to determine in what order the operators will be evaluated.

Precedence  
------------
()
not
and
or

Example(s)

Press enter or click to view image in full size
Order of Precedence (Example 1)
Press enter or click to view image in full size
Order of Precedence (Example 2)

Conclusion

In this article we learned how logical operators enable us to manipulate Boolean values, composing them together to build more complex and useful conditions for decision making. Based on 4 simple variables, we were able to build a Boolean expression that determines whether an app user is eligible for registration on the app.

Armed with this knowledge, next time we’ll be learning about Conditional Statements and how they enable computer programs to change behavior depending on the conditions we specify.

--

Gideon Oludeyi
Gideon Oludeyi

Written by Gideon Oludeyi

Passionate about learning and teaching