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 discrads 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 = "Shetty777"; print(type(name))
#The variables can be used as normal
print(f"{name} has {y} flowers")
Comparision 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 flase/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) comparision 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 afer 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"