CODE WITH MARTIN

7. Logic


What Is Logic?

Everything up to now that we have written with Python has not involved any decision making. We've declared variables, we've made functions, this is all very "do this" and "do that". Logic describes the tools in Python we have to be able to compare data and make decisions based on the result of comparing things. To make decisions in code, we have to compare things to each other.

This is easily the most difficult section of learning programming. Don't worry about being able to fully understand this section from day 1 of reading it. I promise things will become more clear with every hour of practice with programming, and as always, I'll try my best to keep things as simple as possible.

Comparison Operators

Let's imagine we have two variables named 'x' and 'y', they are both integers. Here are some ways we can compare the two variables to each other logically:

The answer to any of these questions would result in either a True or False result depending on the values of x and y. When Python evaluates logic, the end result is always either a True or False result.

Let's turn some of those questions above in to code, let's go:

x = 10
y = 10

print(x == y)   # Equal to 
print(x != y)   # Not equal to
print(x > y)    # Greater than
print(x >= y)   # Greater than or equal to
print(x < y)    # Less than
print(x <= y)   # Less than or equal to

Try changing the values of the variables 'x' and 'y' and see how this changes the output in the terminal.

The characters in between the x and y variables such as '==' and '>' are known as comparison operators. Python evaluates the comparison between the two variables either side of the operator which results in a True or False outcome, which is then passed as an argument to the print statements.

We can stack comparisons together. Sometimes you want to express many bits of logic all at once. Python reserves the words 'and', 'or' and 'not' for use in stacked comparisons. For example:

eggs_stock = 5
bread_stock = 10
milk_stock = 200
onion_stock = 5

is_stock_low = eggs_stock < 5 or bread_stock < 5 or milk_stock < 100 or onion_stock < 10

print(is_stock_low)

Using the 'or' means that any of the comparisons in the list of comparisons on line 6 can be true to have an end result of true, which we store in the 'is_stock_low' variable. If we change the 'or' to 'and', we would change the meaning to be that all comparisons must be true for the 'is_stock_low' to become true.

The use of the 'not' keyword flips the comparison result. For example:

eggs_stock = 5
						
is_stock_low = not eggs_stock < 5
						
print(is_stock_low)

In this code example, the 'is_stock_low' variable is only set to 'True' if 'eggs_stock' variable is NOT less than 5.

It can be very easy to make hard to read code when logic is stacked and the logic becomes complicated. A way to reduce this is breaking up the comparisons in to separate variables with good names.

Booleans

The values True and False are what we call a boolean, or bool for short. It is in fact its own variable type. Try assigning the result of a comparison statement and print the type of the variable, like this:

x = 10
y = 10
						
result = x == y
print(type(result))

Python reserves the words True and False as values for a boolean variable. For example:

state = True
print(state)

The variable 'state' is created as a bool type because we assigned the boolean value True. Assigning False would also make the variable a bool.

Booleans are good for storing facts. When you want to represent something as being true, or false, you should use a bool. Here are some examples:

email_sending_enabled = True
today_is_weekend = True
account_banned = True

If Statements

We've now seen how we can compare variables to each other and produce a true or false result. Now we can learn to use the Python 'if' statement to only execute some code when something is true. Here's a very simple if statement:

x = 10
y = 20

if x < y:
    print("Its true, x really is less than y.")

Starting with the 'if' on line 4, we have a comparison 'x < 20' directly after and a colon ':' at the end of the line. The answer to this 'less than' comparison is true given the values set on lines 1 and 2. The indented line 5 will execute because the condition is true on line 4. You can place as many indented lines as you like inside this if statement and they all will only execute when the if condition is true.

Another part that we can add to an if statement is some code that runs only when the condition in the if statement is false. Here's our same code with an else statement attatched to the if:

x = 10
y = 20

if x < y:
    print("Its true, x really is less than y.")
else:
    print("Its false, x is not less than y.")

Line 6 shows another part to an if statement, called the 'else'. Notice how this is not indented, but the statements on line 7 are. Else statements only run if the condition in the if statement is false. The indented statement on line 7 will only run if we change the value of the 'x' variable to be greater than or equal to the 'y' variable. Give it a try.

If statements support one more keyword that let us test for more conditions if our first condition fails to be true. The keyword is 'elif', short for 'else if'. Here's an example:

x = 10
y = 20
						
if x < y:
    print("Its true, x really is less than y.")
elif x == y:
    print("x has the same value as y.")
else:
    print("All conditions failed.")

To break this down, our first condition is in the if statement on line 4. If this is true, only line 5 will execute and the rest of the code in this if statement will be ignored.

If the condition on line 4 is NOT true, then Python will consider the next condition test on line 6. If this happens to be true, only line 7 will execute.

Finally, if neither the condition on line 4 or 6 is true, the 'else' statement on line 8 is used, so only the statement on line 9 is executed.

A real life example of this is if you were shopping for something. You might say "Only get the cheese crisps, but if they dont have any, get the sweet chilli, and if they dont either of those, just get the plain salted ones.". This is an example of saying "if", "elif", and "else" in code.

If you find that you only have one statement to run with an if statement, you can place all of the code on one line, like this:

x = 10
y = 20
				
if x < y: print("x is less than y.")

Nested If Statements

It's possible to stack multiple blocks of if statements together as long as the indentation flows with the if blocks. We call this 'nested if statements'. Let's see an example:

balance = 100
item_cost = 50
						
if balance > 0:
    print("You have funds in your account.")
    if item_cost > balance:
        print("You cannot afford to purchase the item.")
    else:
        print("You can afford to purchase the item.")
else:
    print("You have no funds in your account.")

Notice how on line 7 and 9, we are using more indentation. You can just remember that when you write things like functions and if statements and you encounter the colon character ':', this is an indication that your next lines are going to be indented further than the line you're currently indenting. So line 6 is already indented by 4 spaces, and the next line 7 has to be indented under the if statement so that becomes indented by 8 spaces. It's easy to read once you get the hang of it with practice.

Try not to get too deep with if statement nesting. There will come a time where you might have a lot of if statements all nested inside each other. There is always a different way of writing logic when that happens to reduce the need of nesting. Nesting becomes harmful when it gets too deep because code becomes harder to maintain and understand.

What We Learned