Just creating data is not enough, what makes computers useful is that we can modify them and perform certain actions on them. For such purposes, Python offers numerous operators. Since Python is a high-level language that was designed to be easily understood, much of its syntax resembles the English language and mathematics. As such, following is a list of common Arithmetic operators (I will not be covering all the operators, such as Bitwise operators), many of which can be easily interpreted in the context of mathematics:
# Addition: Adds the operands
print(2 + 3)
# Subtraction: Subtracts the latter operand from the former
print(3 - 2)
# Multiplication: Multiplies the operands
print(2 * 3)
# Division: Divides the former operand by the latter
print(10 / 2)
# Floor division: Only returns the integer part of the quotient, and discards the remainder
print(7 // 3)
# Modulus: Only returns the remainder
print(15 % 7)
# Exponentiation: Raises the former operand to the power of the latter
print(4 ** 3)
These arithmetic operators follow the standard
BODMAS. The brilliant among you may realise that multiplication &
division and addition & subtraction are the same; Python knows that
too. In cases when two operators share the same priority in the
order of operations, the operations will be carried out from
left-to-right. A few of these functions can be performed on
non-numeric types as well; mostly the sequence types. Experiment and
find out which combinations work. You can also multiply the sequence
types with a number. E.g, "Yo! " * 3 returns "Yo! Yo!
Yo!". If you want to modify the value of a variable using its
previous value with any arithmetic operators, you can make
use of the assignment operators.
x: int = 5
print(x)
x: int += 2 # This is the same as x = x + 2
print(x)
# There is another operator called the walrus operator that defines a variable and returns the value at the same time
print(y: int := 5) # This is the same as y = 5; print(y)
print(type(name: str := "Shashank")) # This is the same as name = "Shashank"; print(type(name))
#Afterwards, the variables can be used as normal
print(f"{name} has {y} flowers")
Comparison operators are used to compare two values on both
sides of the operator. They return True if the
expression is true/correct and False if the expression
is false/wrong. The concept of "returning something" will be better
understood later in the course.
# Equal: True if both operands are equal
print(2 == 6-2)
# Not equal: True if both operands are not equal
print(1 != 2)
# Greater than: True if the former operand is greater than the latter
print(7 > 4)
# Greater than or equal to: True if the former operand is greater than or equal to the latter
print(37 >= 37)
# Lesser than: True if the former operand is lesser than the latter
print(4 < 7)
# Lesser than or equal to: True if the former operand is lesser than or equal to the latter
print(4 <= 4)
And then we have the Logical operators, which are like logic gates in circuits. They combine (two) comparison operators and return a boolean.
# The operations are arranged in decreasing order of precedence
# Not: True if the operand is False, and vice-versa
print(not 0 > 7)
# And: True if both operands evaluate to True
print(2 == 2 and 3 > 2)
# Or: True if at least one of the operands evaluates to True
print(1 != 0 or 9 < 7 or 3 > 3)
Finally, we have the Identity operators and the Membership operators.
x = 777; y = x
# Is: True if two values point to the same object in memory
print(x is y)
# Is not: True if two values do not point to the same object in memory
print(x is not 100)
# In: True if the value is present in the sequence
print(1 in [1, 2, 3, 4])
# Not in: True if the value is not present in the sequence
print(8 not in {1, 2, 3, 4})
Now wait a minute! Why the heck would I use is and
not is when I can use == or
!=? Good question. is checks whether two
values
point to the same address in the computer's memory whereas
== checks whether the two values
have the same value. You can use the id() to
see the memory address of an object.
foo = 456 # Variable foo has the value 456
bar = foo # Variable bar now points to the same address as foo and has the value 456; it is an alias
print(foo is bar)
print(f"foo is bar because the address of foo is {id(foo)} and the address of bar is {id(bar)}, which are the same")
monty = int("456") # Variable monty has the value 456, but it is not an alias of foo
print(foo is monty)
print(f"foo is not monty because the address of foo is {id(foo)} and the address of bar is {id(monty)}, which are not same")
print(foo == monty) # However, foo and monty have the same value, so they are equal
Now here is the thing, try the above code but with a value ≥-5 &
≤256, and you will be surprised. This is because Python "interns"
numbers in that range or strings less than 4096 characters, which
means, it decides to save memory and power by allocating the same
address to all objects with that value. Now, instead of using
int("456"), just use the number directly and you will
be surprised again. Interning was only supposed to happen till 256,
what's this! The Python interpreter optimises memory usage by also
allocating the same address to some objects if they are in the same
context. Try to run it in a REPL interface, where each line is
executed separately and the scope of the objects is not known, and
you should get False for foo is 456. So, a simple rule
of thumb is, use == when you have to compare values and
is when you have to see if they are the same object.
If we wish to perform certain actions based on some condition, we
can use the conditional statements, i.e, if,
elif and else. A simple way to understand
this is "If something is True, do action A; if not/else, do action
B"
status = True
if status:
print("Action A took place")
else:
print("Action B took place")
Notice the indentation, that is the space before the two
print statements. This is very crucial in Python, not only for good
looks and easy readability, but Python relies on it to understand
context, i.e., what belongs where. Try to run the above without
them. Common practice is to place 4 spaces (or a tab), but any
number of spaces can be used, as long as you are consistent. The
code under the if statement will only run if the expression after
the if returns True, so, you need not use True or False
directly but some conditional operators or logic operators. The else
and the elif statements are optional. The code under the
else statement will only run if the
if statement is not executed. Multiple
if can be use together. elif is simply a
way to have specific
else
statements as you will see.
num = input("Enter a number: ")
if num % 2 == 0: # This checks if the remainder when divided by 2 is 0 or not. If it is, the expression returns True
print(f"{num} is even")
else: # This runs only if the above expression returns False
print(f"{num} is odd")
print(f"Your number was {num}") # This will run no matter what
Here is an example to understand elif:
from math import sqrt # Import the square root function from the math module
num = input("Enter a number: ")
num = int(num) # Convert the input to an integer
if num % 2 == 0 or num % 3 == 0: # Check if the number is divisible by 2 or 3
print("The number is divisible by either 2 or 3.")
elif sqrt(num).is_integer(): # Check if the number is a perfect square
print("The number is a perfect square.")
else: # Runs only if both expressions are false
print("The number is neither divisible by 2 or 3 nor a perfect square.")
# Instead of the is_integer() method, you can use:
# int(sqrt(num)) == sqrt(num)
# This will convert the square root to an integer and compare it with the original square root.
# If the number is not a perfect square, the original square root will have some decimal places.
Run the above program with 14, 25, 29 & 36 as inputs. You may notice
that 36 is not recognised as a perfect square. Now change the
elif into if and run with 36 as input.
Both if statements will be executed. Thus, once the if statement is
satisfied, elif and else will not be looked at; but another if
statement will be checked. There can be any number of if or elif
statements, but only one else statement in the end.
if None: will not be
executed. You can also use the if statement to
check if a variable is None or not. This is useful when you want
to check if a variable has been assigned a value or not.
x = 0
if x: # Here, x evaluates to False
print("Action A")
else:
print("Action B")
if x is not None: # Even though x is 0, it is not None. So this evaluates to True
print("Action A")
else:
print("Action B")
age = 16
eligibility = "Eligible" if age >= 18 else "Not eligible"
print(eligibility)
# This is the same as:
# if age >= 18:
# eligibility = "Eligible"
# else:
# eligibility = "Not eligible"