print(type(10)) # Int
print(type(3.14)) # Float
print(type(1 + 3j)) # Complex
print(type('Asabeneh')) # String
print(type([1, 2, 3])) # List
print(type({'name': 'Asabeneh'})) # Dictionary
print(type({9.8, 3.14, 2.7})) # Set
print(type((1,2,3))) #tuple
NOTE
Python build-in functions will be done after the functions.
Variables
Variables store data in a computer memory. Mnemonic variables are recommended to use in many programming languages. A mnemonic variable is a variable name that can be easily remembered and associated. A variable refers to a memory address in which data is stored. Number at the beginning, special character, hyphen are not allowed when naming a variable. A variable can have a short name (like x, y, z), but a more descriptive name (firstname, lastname, age, country) is highly recommended.
Python Variable Name Rules
A variable name must start with a letter or the underscore character
A variable name cannot start with a number
A variable name can only contain alpha-numeric characters and underscores (A-z, 0-9, and _ )
Variable names are case-sensitive (firstname, Firstname, FirstName and FIRSTNAME) are different variables)
→ If you want to use reserved keywords as the variable then use a underscore before them. Eg- “_if”
Example List of Valid variables
firstname
lastname
age
country
city
first_name
last_name
capital_city
_if # if we want to use reserved word as a variable
year_2021
year2021
current_year_2021
birth_year
num1
num2
Example list of invalid variables
first-name
first@name
first$name
num-1
1num
Declaring Multiple Variable in a Line
Multiple variables can also be declared in one line:
There are several data types in Python. To identify the data type we use the type built-in function.
# Different python data types
# Let's declare variables with various data types
first_name = 'Asabeneh' # str
last_name = 'Yetayeh' # str
country = 'Finland' # str
city= 'Helsinki' # str
age = 250 # int, it is not my real age, don't worry about it
# Printing out types
print(type('Asabeneh')) # str
print(type(first_name)) # str
print(type(10)) # int
print(type(3.14)) # float
print(type(1 + 1j)) # complex
print(type(True)) # bool
print(type([1, 2, 3, 4])) # list
print(type({'name':'Asabeneh'})) # dict
print(type((1,2))) # tuple
print(type(zip([1,2],[3,4]))) # zip
print(type({1,2,3})) # set
zip - In Python, there is no native “zip data type.” Instead, zip is a built-in constructor function that returns a specialized iterator called a zip object. This zip object maps corresponding elements from multiple iterables (like lists, tuples, or strings) into an iterator of grouped tuples.
Text is a string data type. Any data type written as text is a string. Any data under single, double or triple quote are strings. There are different string methods and built-in functions to deal with string data types. To check the length of a string use the len() method.
Creating a string
letter = 'P' # A string could be a single character or a bunch of texts
print(letter) # P
print(len(letter)) # 1
greeting = 'Hello, World!' # String could be made using a single or double quote,"Hello, World!"
print(greeting) # Hello, World!
print(len(greeting)) # 13
sentence = "I hope you are enjoying 30 days of Python Challenge"
print(sentence)
multiline_string = '''I am a teacher and enjoy teaching.
I didn't find anything as rewarding as empowering people.
That is why I created 30 days of python.'''
print(multiline_string)
# Another way of doing the same thing
multiline_string = """I am a teacher and enjoy teaching.
I didn't find anything as rewarding as empowering people.
That is why I created 30 days of python."""
print(multiline_string)
String Concatenation
first_name = 'Amitabh'
last_name = 'Bacchan'
space = ' '
full_name = first_name + space + last_name
print(full_name) # Amitabh Bacchan
# Checking the length of a string using len() built-in function
print(len(first_name)) # 8
print(len(last_name)) # 7
print(len(first_name) > len(last_name)) # True
print(len(full_name)) # 16
Escape Sequences in Strings
In Python and other programming languages \ followed by a character is an escape sequence. Let us see the most common escape characters:
\n: new line
\t: Tab means(8 spaces)
\: Back slash
\’: Single quote (’)
\”: Double quote (”)
String Formatting
Old Style String Formatting (% Operator)
%s - String (or any object with a string representation, like numbers)
%d - Integers
%f - Floating point numbers
“%.number of digitsf” - Floating point numbers with fixed precision.
# Strings only
first_name = 'Asabeneh'
last_name = 'Yetayeh'
language = 'Python'
formated_string = 'I am %s %s. I teach %s' %(first_name, last_name, language)
print(formated_string)
# Strings and numbers
radius = 10
pi = 3.14
area = pi * radius ** 2
formated_string = 'The area of circle with a radius %d is %.2f.' %(radius, area) # 2 refers the 2 significant digits after the point
python_libraries = ['Django', 'Flask', 'NumPy', 'Matplotlib','Pandas']
formated_string = 'The following are python libraries:%s' % (python_libraries)
print(formated_string) # "The following are python libraries:['Django', 'Flask', 'NumPy', 'Matplotlib','Pandas']"
New Style String Formatting (str.format)
This format was introduced in Python version 3.
first_name = 'Asabeneh'
last_name = 'Yetayeh'
language = 'Python'
formated_string = 'I am {} {}. I teach {}'.format(first_name, last_name, language)
print(formated_string)
a = 4
b = 3
print('{} + {} = {}'.format(a, b, a + b))
print('{} - {} = {}'.format(a, b, a - b))
print('{} * {} = {}'.format(a, b, a * b))
print('{} / {} = {:.2f}'.format(a, b, a / b)) # limits it to two digits after decimal
print('{} % {} = {}'.format(a, b, a % b))
print('{} // {} = {}'.format(a, b, a // b))
print('{} ** {} = {}'.format(a, b, a ** b))
# output
4 + 3 = 7
4 - 3 = 1
4 * 3 = 12
4 / 3 = 1.33
4 % 3 = 1
4 // 3 = 1
4 ** 3 = 64
# Strings and numbers
radius = 10
pi = 3.14
area = pi * radius ** 2
formated_string = 'The area of a circle with a radius {} is {:.2f}.'.format(radius, area) # 2 digits after decimal
print(formated_string)
String Interpolation / f-Strings (Python 3.6+)
Another new string formatting is string interpolation, f-strings. Strings start with f and we can inject the data in their corresponding positions.
Python strings are sequences of characters, and share their basic methods of access with other Python ordered sequences of objects – lists and tuples. The simplest way of extracting single characters from strings (and individual members from any sequence) is to unpack them into corresponding variables.
language = 'Python'
a,b,c,d,e,f = language # unpacking sequence characters into variables
print(a) # P
print(b) # y
print(c) # t
print(d) # h
print(e) # o
print(f) # n
```
language = 'Python'
first_letter = language[0]
print(first_letter) # P
second_letter = language[1]
print(second_letter) # y
last_index = len(language) - 1
last_letter = language[last_index]
print(last_letter) # n
language = 'Python'
last_letter = language[-1]
print(last_letter) # n
second_last = language[-2]
print(second_last) # o
```
Slicing Python Strings
language = 'Python'
first_three = language[0:3] # starts at zero index and up to 3 but not include 3
print(first_three) #Pyt
last_three = language[3:6]
print(last_three) # hon
# Another way
last_three = language[-3:]
print(last_three) # hon
last_three = language[3:]
print(last_three) # hon
capitalize(): Converts the first character of the string to capital letter.
challenge = 'python is a mastikhor language'
print(challenge.capitalize()) # 'Python is a mastikhor language'
count(): returns occurrences of substring in string, count(substring, start=.., end=..). The start is a starting indexing for counting and end is the last index to count.
challenge = 'thirty days of python'
print(challenge.count('y')) # 3
print(challenge.count('y', 7, 14)) # 1,
print(challenge.count('th')) # 2
endswith(): Checks if a string ends with a specified ending.
challenge = 'thirty days of python'
print(challenge.endswith('on')) # True
print(challenge.endswith('tion')) # False
expandtabs(): Replaces tab character with spaces, default tab size is 8. It takes tab size argument.
challenge = 'thirty\tdays\tof\tpython'
print(challenge.expandtabs()) # 'thirty days of python'
print(challenge.expandtabs(10)) # 'thirty days of python'
find(): Returns the index of the first occurrence of a substring, if not found returns -1.
challenge = 'thirty days of python'
print(challenge.find('y')) # 5
print(challenge.find('th')) # 0
rfind(): Returns the index of the last occurrence of a substring, if not found returns -1.
challenge = 'thirty days of python'
print(challenge.rfind('y')) # 16
print(challenge.rfind('th')) # 17
index(): Returns the lowest index of a substring, additional arguments indicate starting and ending index (default 0 and string length - 1). If the substring is not found it raises a valueError.
challenge = 'thirty days of python'
sub_string = 'da'
print(challenge.index(sub_string)) # 7
print(challenge.index(sub_string, 9)) # error
rindex(): Returns the highest index of a substring, additional arguments indicate starting and ending index (default 0 and string length - 1)
challenge = 'thirty days of python'
sub_string = 'da'
print(challenge.rindex(sub_string)) # 7
print(challenge.rindex(sub_string, 9)) # error
print(challenge.rindex('on', 8)) # 19
isalnum(): Checks alphanumeric character
challenge = 'ThirtyDaysPython'print(challenge.isalnum()) # Truechallenge = '30DaysPython'print(challenge.isalnum()) # Truechallenge = 'thirty days of python'print(challenge.isalnum()) # False, space is not an alphanumeric characterchallenge = 'thirty days of python 2019'print(challenge.isalnum()) # False
isalpha(): Checks if all string elements are alphabet characters (a-z and A-Z)
challenge = 'thirty days of python'print(challenge.isalpha()) # False, space is once again excludedchallenge = 'ThirtyDaysPython'print(challenge.isalpha()) # Truenum = '123'print(num.isalpha()) # False
isdecimal(): Checks if all characters in a string are decimal (0-9)
challenge = 'thirty days of python'print(challenge.isdecimal()) # Falsechallenge = '123'print(challenge.isdecimal()) # Truechallenge = '\u00B2'print(challenge.isdigit()) # True challenge = '12 3'print(challenge.isdecimal()) # False, space not allowed
isdigit(): Checks if all characters in a string are numbers (0-9 and some other unicode characters for numbers)
isidentifier(): Checks for a valid identifier - it checks if a string is a valid variable name
challenge = '30DaysOfPython'print(challenge.isidentifier()) # False, because it starts with a numberchallenge = 'thirty_days_of_python'print(challenge.isidentifier()) # True
islower(): Checks if all alphabet characters in the string are lowercase
challenge = 'thirty days of python'print(challenge.islower()) # Truechallenge = 'Thirty days of python'print(challenge.islower()) # False
isupper(): Checks if all alphabet characters in the string are uppercase
challenge = 'thirty days of python'print(challenge.isupper()) # Falsechallenge = 'THIRTY DAYS OF PYTHON'print(challenge.isupper()) # True
challenge = 'thirty days of python'print(challenge.title()) # Thirty Days Of Python
swapcase(): Converts all uppercase characters to lowercase and all lowercase characters to uppercase characters
challenge = 'thirty days of python'print(challenge.swapcase()) # THIRTY DAYS OF PYTHONchallenge = 'Thirty Days Of Python'print(challenge.swapcase()) # tHIRTY dAYS oF pYTHON
startswith(): Checks if String Starts with the Specified String
challenge = 'thirty days of python'print(challenge.startswith('thirty')) # Truechallenge = '30 days of python'print(challenge.startswith('thirty')) # False
Lists
List: is a collection which is ordered and changeable(modifiable). Allows duplicate members.
A list is collection of different data types which is ordered and modifiable(mutable). A list can be empty or it may have different data type items.
Creating a list
A list can be created in two manners
→ Using the build-in function list()
→ Using the [] square brackets
# syntax
lst = list()
empty_list = list() # this is an empty list, no item in the list
print(len(empty_list)) # 0
# syntax
lst = []
empty_list = [] # this is an empty list, no item in the list
print(len(empty_list)) # 0
fruits = ['banana', 'orange', 'mango', 'lemon'] # list of fruits
vegetables = ['Tomato', 'Potato', 'Cabbage','Onion', 'Carrot'] # list of vegetables
animal_products = ['milk', 'meat', 'butter', 'yoghurt'] # list of animal products
web_techs = ['HTML', 'CSS', 'JS', 'React','Redux', 'Node', 'MongDB'] # list of web technologies
countries = ['Finland', 'Estonia', 'Denmark', 'Sweden', 'Norway']
# Print the lists and its length
print('Fruits:', fruits)
print('Number of fruits:', len(fruits))
print('Vegetables:', vegetables)
print('Number of vegetables:', len(vegetables))
print('Animal products:',animal_products)
print('Number of animal products:', len(animal_products))
print('Web technologies:', web_techs)
print('Number of web technologies:', len(web_techs))
print('Countries:', countries)
print('Number of countries:', len(countries))
Outputs:
output
Fruits: ['banana', 'orange', 'mango', 'lemon']
Number of fruits: 4
Vegetables: ['Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
Number of vegetables: 5
Animal products: ['milk', 'meat', 'butter', 'yoghurt']
Number of animal products: 4
Web technologies: ['HTML', 'CSS', 'JS', 'React', 'Redux', 'Node', 'MongDB']
Number of web technologies: 7
Countries: ['Finland', 'Estonia', 'Denmark', 'Sweden', 'Norway']
Number of countries: 5
A list can have more than one datatype
lst = ['Asabeneh', 250, True, {'country':'Finland', 'city':'Helsinki'}] # list containing different data types
Indexing in list
Unpacking list items
lst = ['item1','item2','item3', 'item4', 'item5']
first_item, second_item, third_item, *rest = lst
print(first_item) # item1
print(second_item) # item2
print(third_item) # item3
print(rest) # ['item4', 'item5']
# First Example
fruits = ['banana', 'orange', 'mango', 'lemon','lime','apple']
first_fruit, second_fruit, third_fruit, *rest = fruits
print(first_fruit) # banana
print(second_fruit) # orange
print(third_fruit) # mango
print(rest) # ['lemon','lime','apple']
# Second Example about unpacking list
first, second, third,*rest, tenth = [1,2,3,4,5,6,7,8,9,10]
print(first) # 1
print(second) # 2
print(third) # 3
print(rest) # [4,5,6,7,8,9]
print(tenth) # 10
# Third Example about unpacking list
countries = ['Germany', 'France','Belgium','Sweden','Denmark','Finland','Norway','Iceland','Estonia']
gr, fr, bg, sw, *scandic, es = countries
print(gr)
print(fr)
print(bg)
print(sw)
print(scandic)
print(es)
Slicing Items from a List
Positive Indexing: We can specify a range of positive indexes by specifying the start, end and step, the return value will be a new list. (default values for start = 0, end = len(lst) - 1 (last item), step = 1)
fruits = ['banana', 'orange', 'mango', 'lemon']all_fruits = fruits[0:4] # it returns all the fruits# this will also give the same result as the one aboveall_fruits = fruits[0:] # if we don't set where to stop it takes all the restorange_and_mango = fruits[1:3] # it does not include the first indexorange_mango_lemon = fruits[1:]orange_and_lemon = fruits[::2] # here we used a 3rd argument, step. It will take every 2cnd item - ['banana', 'mango']
Negative Indexing: We can specify a range of negative indexes by specifying the start, end and step, the return value will be a new list.
fruits = ['banana', 'orange', 'mango', 'lemon']all_fruits = fruits[-4:] # it returns all the fruitsorange_and_mango = fruits[-3:-1] # it does not include the last index,['orange', 'mango']orange_mango_lemon = fruits[-3:] # this will give starting from -3 to the end,['orange', 'mango', 'lemon']reverse_fruits = fruits[::-1] # a negative step will take the list in reverse order,['lemon', 'mango', 'orange', 'banana']
Modifying Lists
List is a mutable or modifiable ordered collection of items. Lets modify the fruit list.
Inserting Items into a List
We can use insert() method to insert a single item at a specified index in a list. Note that other items are shifted to the right. The insert() methods takes two arguments:index and an item to insert.
fruits = ['banana', 'orange', 'mango', 'lemon']fruits.insert(2, 'apple') # insert apple between orange and mangoprint(fruits) # ['banana', 'orange', 'apple', 'mango', 'lemon']fruits.insert(3, 'lime') # ['banana', 'orange', 'apple', 'lime', 'mango', 'lemon']print(fruits)
Removing Items from a List
The remove method removes a specified item from a list
# syntaxlst = ['item1', 'item2']lst.remove(item)
fruits = ['banana', 'orange', 'mango', 'lemon', 'banana']fruits.remove('banana')print(fruits) # ['orange', 'mango', 'lemon', 'banana'] - this method removes the first occurrence of the item in the listfruits.remove('lemon')print(fruits) # ['orange', 'mango', 'banana']
Removing Items Using Pop
The pop() method removes the specified index, (or the last item if index is not specified):
# syntaxlst = ['item1', 'item2']lst.pop() # last itemlst.pop(index)
Removing Items Using Del
The del keyword removes the specified index and it can also be used to delete items within index range. It can also delete the list completely
# syntaxlst = ['item1', 'item2']del lst[index] # only a single itemdel lst # to delete the list completely
fruits = ['banana', 'orange', 'mango', 'lemon', 'kiwi', 'lime']del fruits[0]print(fruits) # ['orange', 'mango', 'lemon', 'kiwi', 'lime']del fruits[1]print(fruits) # ['orange', 'lemon', 'kiwi', 'lime']del fruits[1:3] # this deletes items between given indexes, so it does not delete the item with index 3!print(fruits) # ['orange', 'lime']del fruitsprint(fruits) # This should give: NameError: name 'fruits' is not defined
Clearing List Items
The clear() method empties the list:
Copying a List
It is possible to copy a list by reassigning it to a new variable in the following way: list2 = list1. Now, list2 is a reference of list1, any changes we make in list2 will also modify the original, list1. But there are lots of case in which we do not like to modify the original instead we like to have a different copy. One of way of avoiding the problem above is using copy().
Sorting List Items
To sort lists we can use sort() method or sorted() built-in functions. The sort() method reorders the list items in ascending order and modifies the original list. If an argument of sort() method reverse is equal to true, it will arrange the list in descending order.
→ sort(): this method modifies the original list
A tuple is a collection of different data types which is ordered and unchangeable (immutable). Tuples are written with round brackets, (). Once a tuple is created, we cannot change its values. We cannot use add, insert, remove methods in a tuple because it is not modifiable (mutable). Unlike list, tuple has few methods. Methods related to tuples:
tuple(): to create an empty tuple
count(): to count the number of a specified item in a tuple
index(): to find the index of a specified item in a tuple
+ operator: to join two or more tuples and to create a new tuple
Creating a Tuple
Empty tuple: Creating an empty tuple
# syntaxempty_tuple = ()# or using the tuple constructorempty_tuple = tuple()
Tuple with initial values
# syntaxtpl = ('item1', 'item2','item3')
fruits = ('banana', 'orange', 'mango', 'lemon')
Tuple length
We use the len() method to get the length of a tuple.
# syntaxtpl = ('item1', 'item2', 'item3')len(tpl)
Accessing Tuple Items
Positive Indexing
Similar to the list data type we use positive or negative indexing to access tuple items.
Negative indexing
Negative indexing means beginning from the end, -1 refers to the last item, -2 refers to the second last and the negative of the list/tuple length refers to the first item.
We can slice out a sub-tuple by specifying a range of indexes where to start and where to end in the tuple, the return value will be a new tuple with the specified items.
Range of Positive Indexes
# Syntaxtpl = ('item1', 'item2', 'item3','item4')all_items = tpl[0:4] # all itemsall_items = tpl[0:] # all itemsmiddle_two_items = tpl[1:3] # does not include item at index 3
fruits = ('banana', 'orange', 'mango', 'lemon')all_fruits = fruits[0:4] # all itemsall_fruits= fruits[0:] # all itemsorange_mango = fruits[1:3] # doesn't include item at index 3orange_to_the_rest = fruits[1:]
Range of Negative Indexes
# Syntaxtpl = ('item1', 'item2', 'item3','item4')all_items = tpl[-4:] # all itemsmiddle_two_items = tpl[-3:-1] # does not include item at index 3 (-1)
fruits = ('banana', 'orange', 'mango', 'lemon')all_fruits = fruits[-4:] # all itemsorange_mango = fruits[-3:-1] # doesn't include item at index 3orange_to_the_rest = fruits[-3:]
Changing Tuples to Lists
We can change tuples to lists and lists to tuples. Tuple is immutable if we want to modify a tuple we should change it to a list.
We can check if an item exists or not in a tuple using in, it returns a boolean.
# Syntaxtpl = ('item1', 'item2', 'item3','item4')'item2' in tpl # True
fruits = ('banana', 'orange', 'mango', 'lemon')print('orange' in fruits) # Trueprint('apple' in fruits) # Falsefruits[0] = 'apple' # TypeError: 'tuple' object does not support item assignment
Set is a collection of items. Let me take you back to your elementary or high school Mathematics lesson. The Mathematics definition of a set can be applied also in Python. Set is a collection of unordered and un-indexed distinct elements. In Python set is used to store unique items, and it is possible to find the union, intersection, difference, symmetric difference, subset, super set and disjoint set among sets.
Creating a Set
To create an empty set, we use the set() function. Empty curly brackets {} will create a dictionary.
We can remove an item from a set using remove() method. If the item is not found remove() method will raise errors, so it is good to check if the item exist in the given set. However, discard() method doesn’t raise any errors.
We can convert list to set and set to list. Converting list to set removes duplicates and only unique items will be reserved.
# syntaxlst = ['item1', 'item2', 'item3', 'item4', 'item1']st = set(lst) # {'item2', 'item4', 'item1', 'item3'} - the order is random, because sets in general are unordered
It returns the symmetric difference between two sets. It means that it returns a set that contains all items from both sets, except items that are present in both sets, mathematically: (A\B) ∪ (B\A)
# syntaxst1 = {'item1', 'item2', 'item3', 'item4'}st2 = {'item2', 'item3'}# it means (A\B)∪(B\A)st2.symmetric_difference(st1) # {'item1', 'item4'} : st2 ^ st1
Accessing an item by key name raises an error if the key does not exist. To avoid this error first we have to check if a key exist or we can use the get method. The get method returns None, which is a NoneType object data type, if the key does not exist.
By default, statements in Python script are executed sequentially from top to bottom. If the processing logic require so, the sequential flow of execution can be altered in two way:
Conditional execution: a block of one or more statements will be executed if a certain expression is true
Repetitive execution: a block of one or more statements will be repetitively executed as long as a certain expression is true. In this section, we will cover if, else, elif statements. The comparison and logical operators we learned in previous sections will be useful here.
If Condition
In python and other programming languages the key word if is used to check if a condition is true and to execute the block code. Remember the indentation after the colon.
# syntaxif condition: this part of code runs for truthy conditions
Example: 1
a = 3if a > 0: print('A is a positive number')# A is a positive number
As you can see in the example above, 3 is greater than 0. The condition was true and the block code was executed. However, if the condition is false, we do not see the result. In order to see the result of the falsy condition, we should have another block, which is going to be else.
If Else
If condition is true the first block will be executed, if not the else condition will run.
# syntaxif condition: this part of code runs for truthy conditionselse: this part of code runs for false conditions
Example:
a = 3if a < 0: print('A is a negative number')else: print('A is a positive number')
The condition above proves false, therefore the else block was executed. How about if our condition is more than two? We could use elif.
If Elif Else
In our daily life, we make decisions on daily basis. We make decisions not by checking one or two conditions but multiple conditions. As similar to life, programming is also full of conditions. We use elif when we have multiple conditions.
a = 0if a > 0: print('A is a positive number')elif a < 0: print('A is a negative number')else: print('A is zero')
Short Hand
# syntaxcode if condition else code
Example:
a = 3print('A is positive') if a > 0 else print('A is negative') # first condition met, 'A is positive' will be printed
Nested Conditions
Conditions can be nested
# syntaxif condition: code if condition: code
Example:
a = 0if a > 0: if a % 2 == 0: print('A is a positive and even integer') else: print('A is a positive number')elif a == 0: print('A is zero')else: print('A is a negative number')
We can avoid writing nested condition by using logical operator and.
If Condition and Logical Operators
# syntaxif condition and condition: code
Example:
a = 0if a > 0 and a % 2 == 0: print('A is an even and positive integer')elif a > 0 and a % 2 != 0: print('A is a positive integer')elif a == 0: print('A is zero')else: print('A is negative')
If and Or Logical Operators
# syntaxif condition or condition: code
Example:
user = 'James'access_level = 3if user == 'admin' or access_level >= 4: print('Access granted!')else: print('Access denied!')
Loops
Life is full of routines. In programming we also do lots of repetitive tasks. In order to handle repetitive task programming languages use loops. Python programming language also provides the following types of two loops:
while loop
for loop
While Loop
We use the reserved word while to make a while loop. It is used to execute a block of statements repeatedly until a given condition is satisfied. When the condition becomes false, the lines of code after the loop will be continued to be executed.
# syntaxwhile condition: code goes here
Example:
count = 0while count < 5: print(count) count = count + 1#prints from 0 to 4
In the above while loop, the condition becomes false when count is 5. That is when the loop stops.
If we are interested to run block of code once the condition is no longer true, we can use else.
# syntaxwhile condition: code goes hereelse: code goes here
The above while loop only prints 0, 1, 2 and 4 (skips 3).
For Loop
A for keyword is used to make a for loop, similar with other programming languages, but with some syntax differences. Loop is used for iterating over a sequence (that is either a list, a tuple, a dictionary, a set, or a string).
-Using For loop on list
# syntaxfor iterator in lst: code goes here
Example:
numbers = [0, 1, 2, 3, 4, 5]for number in numbers: # number is temporary name to refer to the list's items, valid only inside this loop print(number) # the numbers will be printed line by line, from 0 to 5
-Using For loop on string
# syntaxfor iterator in string: code goes here
Example:
language = 'Python'for letter in language: print(letter)for i in range(len(language)): print(language[i])
-Using For loop on tuple
# syntaxfor iterator in tpl: code goes here
Example:
numbers = (0, 1, 2, 3, 4, 5)for number in numbers: print(number)
For loop with dictionary
Looping through a dictionary gives you the key of the dictionary.
# syntaxfor iterator in dct: code goes here
Example:
person = { 'first_name':'Asabeneh', 'last_name':'Yetayeh', 'age':250, 'country':'Finland', 'is_marred':True, 'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'], 'address':{ 'street':'Space street', 'zipcode':'02210' }}for key in person: print(key)for key, value in person.items(): print(key, value) # this way we get both keys and values printed out
-Using For Loop in set
# syntaxfor iterator in st: code goes here
Example:
it_companies = {'Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon'}for company in it_companies: print(company)
Break and Continue - Part 2
Short reminder:
Break: We use break when we want to stop our loop before it is completed.
# syntaxfor iterator in sequence: code goes here if condition: break
Example:
numbers = (0,1,2,3,4,5)for number in numbers: print(number) if number == 3: break
In the above example, the loop stops when it reaches 3.
Continue: We use continue when we want to skip some of the steps in the iteration of the loop.
# syntaxfor iterator in sequence: code goes here if condition: continue
Example:
numbers = (0,1,2,3,4,5)for number in numbers: print(number) if number == 3: continue print('Next number should be ', number + 1) if number != 5 else print("loop's end") # for short hand conditions need both if and else statementsprint('outside the loop')
In the example above, if the number equals 3, the step after the condition (but inside the loop) is skipped and the execution of the loop continues if there are any iterations left.
The Range Function
The range() function is used to return a list of numbers. The range(start, end, step) takes three parameters: starting, ending and increment. By default it starts from 0 and the increment is 1. The range sequence needs at least 1 argument (end).
Creating sequences using range
lst = list(range(11))print(lst) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]st = set(range(1, 11)) # 2 arguments indicate start and end of the sequence, step set to default 1print(st) # {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}lst = list(range(0,11,2))print(lst) # [0, 2, 4, 6, 8, 10]st = set(range(0,11,2))print(st) # {0, 2, 4, 6, 8, 10}# for backward from start to end lst = list(range(11,0,-2))print(lst) # [11,9,7,5,3,1]
# syntaxfor iterator in range(start, end, step):
Example:
for number in range(11): print(number) # prints 0 to 10, not including 11
Nested For Loop
We can write loops inside a loop.
# syntaxfor x in y: for t in x: print(t)
Example:
person = { 'first_name': 'Asabeneh', 'last_name': 'Yetayeh', 'age': 250, 'country': 'Finland', 'is_marred': True, 'skills': ['JavaScript', 'React', 'Node', 'MongoDB', 'Python'], 'address': { 'street': 'Space street', 'zipcode': '02210' }}for key in person: if key == 'skills': for skill in person['skills']: print(skill)
For Else
If we want to execute some message when the loop ends, we use else.
# syntaxfor iterator in range(start, end, step): do somethingelse: print('The loop ended')
Example:
for number in range(11): print(number) # prints 0 to 10, not including 11else: print('The loop stops at', number)
Pass
In python when statement is required (after semicolon), but we don’t like to execute any code there, we can write the word pass to avoid errors. Also we can use it as a placeholder, for future statements.
Example:
for number in range(6): pass
Functions
What is a function? Before we start making functions, let us learn what a function is and why we need them?
Defining a Function
A function is a reusable block of code or programming statements designed to perform a certain task. To define or declare a function, Python provides the def keyword. The following is the syntax for defining a function. The function block of code is executed only if the function is called or invoked.
Declaring and Calling a Function
When we make a function, we call it declaring a function. When we start using the it, we call it calling or invoking a function. Functions can be declared with or without parameters.
# syntax# Declaring a functiondef function_name(): codes codes# Calling a functionfunction_name()
Function without Parameters
Function can be declared without parameters.
Example:
def generate_full_name (): first_name = 'Asabeneh' last_name = 'Yetayeh' space = ' ' full_name = first_name + space + last_name print(full_name)generate_full_name () # calling a functiondef add_two_numbers (): num_one = 2 num_two = 3 total = num_one + num_two print(total)add_two_numbers()
Function Returning a Value - Part 1
Functions return values using the return statement. If a function has no return statement, it returns None. Let us rewrite the above functions using return. From now on, we get a value from a function when we call the function and print it.
In a function we can pass different data types(number, string, boolean, list, tuple, dictionary or set) as parameters.
Single Parameter: If our function takes a parameter we should call our function with an argument
# syntax # Declaring a function def function_name(parameter): codes codes # Calling function print(function_name(argument))
Example:
def greetings (name): message = name + ', welcome to Python for Everyone!' return messageprint(greetings('Asabeneh'))def add_ten(num): ten = 10 return num + tenprint(add_ten(90))def square_number(x): return x * xprint(square_number(2))def area_of_circle (r): PI = 3.14 area = PI * r ** 2 return areaprint(area_of_circle(10))def sum_of_numbers(n): total = 0 for i in range(n+1): total+=i return totalprint(sum_of_numbers(10)) # 55print(sum_of_numbers(100)) # 5050
Two Parameter: A function may or may not have a parameter or parameters. A function may also have two or more parameters. If our function takes parameters we should call it with arguments. Let us check a function with two parameters:
# syntax # Declaring a function def function_name(para1, para2): codes codes # Calling function print(function_name(arg1, arg2))
Example:
def generate_full_name (first_name, last_name): space = ' ' full_name = first_name + space + last_name return full_nameprint('Full Name: ', generate_full_name('Asabeneh','Yetayeh'))def sum_two_numbers (num_one, num_two): sum = num_one + num_two return sumprint('Sum of two numbers: ', sum_two_numbers(1, 9))def calculate_age (current_year, birth_year): age = current_year - birth_year return age print('Age: ', calculate_age(2021, 1819))def weight_of_object (mass, gravity): weight = str(mass * gravity)+ ' N' # the value has to be changed to a string first return weightprint('Weight of an object in Newtons: ', weight_of_object(100, 9.81))
Passing Arguments with Key and Value
If we pass the arguments with key and value, the order of the arguments does not matter.
# syntax# Declaring a functiondef function_name(para1, para2): codes codes# Calling functionprint(function_name(para1 = 'John', para2 = 'Doe')) # the order of arguments does not matter here
Example:
def print_fullname(firstname, lastname): space = ' ' full_name = firstname + space + lastname print(full_name)print_fullname(firstname = 'Asabeneh', lastname = 'Yetayeh')def add_two_numbers (num1, num2): total = num1 + num2 return totalprint(add_two_numbers(num2 = 3, num1 = 2)) # Order does not matter
Function Returning a Value - Part 2
If we do not return a value with a function, then our function is returning None by default. To return a value with a function we use the keyword return followed by the variable we are returning. We can return any kind of data types from a function.
def is_even (n): if n % 2 == 0: return True # return stops further execution of the function, similar to break return Falseprint(is_even(10)) # Trueprint(is_even(7)) # False
Returning a list:
Example:
def find_even_numbers(n): evens = [] for i in range(n + 1): if i % 2 == 0: evens.append(i) return evensprint(find_even_numbers(10))
Function with Default Parameters
Sometimes we pass default values to parameters, when we invoke the function. If we do not pass arguments when calling the function, their default values will be used.
def greetings (name = 'Peter'): message = name + ', welcome to Python for Everyone!' return messageprint(greetings())print(greetings('Asabeneh'))def generate_full_name (first_name = 'Asabeneh', last_name = 'Yetayeh'): space = ' ' full_name = first_name + space + last_name return full_nameprint(generate_full_name())print(generate_full_name('David','Smith'))def calculate_age (birth_year,current_year = 2021): age = current_year - birth_year return age print('Age: ', calculate_age(1821))def weight_of_object (mass, gravity = 9.81): weight = str(mass * gravity)+ ' N' # the value has to be changed to string first return weightprint('Weight of an object in Newtons: ', weight_of_object(100)) # 9.81 - average gravity on Earth's surfaceprint('Weight of an object in Newtons: ', weight_of_object(100, 1.62)) # gravity on the surface of the Moon
Arbitrary Number of Arguments
If we do not know the number of arguments we pass to our function, we can create a function which can take arbitrary number of arguments by adding * before the parameter name.
def sum_all_nums(*nums): total = 0 for num in nums: total += num # same as total = total + num return totalprint(sum_all_nums(2, 3, 5)) # 10
Default and Arbitrary Number of Parameters in Functions
def generate_groups (team,*args): print(team) for i in args: print(i) generate_groups('Team-1','Asabeneh','Brook','David','Eyob')
Dictionary unpacking
You can call a function which has named arguments using a dictionary with matching key names. You do so using **.
# Define a function that takes two arguments: 'name' and 'location'def greet(name, location): # Print a greeting message using the provided arguments print("Hi there", name, "how is the weather in", location)# Call the function using keyword argumentsgreet(name="Alice", location="New York") # Output: Hi there Alice how is the weather in New York# Create a dictionary with keys matching the function's parameter namesmy_dict = {"name": "Alice", "location": "New York"}# Call the function using dictionary unpackinggreet(**my_dict) # The ** operator unpacks the dictionary, passing its key-value pairs # as keyword arguments to the function.# Output: Hi there Alice how is the weather in New York
Arbitrary Number of Named Arguments
You can also define a function to accept an arbitrary number of named arguments.
def arbitrary_named_args(**args): print("I received an arbitrary number of arguments, totaling", len(args)) print("They are provided as a dictionary in my function:", type(args)) print("Let's print them:") for k, v in args.items(): print(" * key:", k, "value:", v)
Generally avoid this unless required as it makes it harder to understand what the function accepts and does.
Function as a Parameter of Another Function
#You can pass functions around as parametersdef square_number (n): return n ** ndef do_something(f, x): return f(x)print(do_something(square_number, 3)) # 27
Modules
What is a Module
A module is a file containing a set of codes or a set of functions which can be included to an application. A module could be a file containing a single variable, a function or a big code base.
Creating a Module
To create a module we write our codes in a python script and we save it as a .py file. Create a file named mymodule.py inside your project folder. Let us write some code in this file.
During importing we can rename the name of the module.
# main.py filefrom mymodule import generate_full_name as fullname, sum_two_nums as total, person as p, gravity as gprint(fullname('Asabneh','Yetayeh'))print(total(1, 9))mass = 100weight = mass * gprint(weight)print(p)print(p['firstname'])
Import Built-in Modules
Like other programming languages we can also import modules by importing the file/function using the key word import. Let’s import the common module we will use most of the time. Some of the common built-in modules: math, datetime, os,sys, random, statistics, collections, json,re
OS Module
Using python os module it is possible to automatically perform many operating system tasks. The OS module in Python provides functions for creating, changing current working directory, and removing a directory (folder), fetching its contents, changing and identifying the current directory.
# import the moduleimport os# Creating a directoryos.mkdir('directory_name')# Changing the current directoryos.chdir('path')# Getting current working directoryos.getcwd()# Removing directoryos.rmdir()
Sys Module
The sys module provides functions and variables used to manipulate different parts of the Python runtime environment. Function sys.argv returns a list of command line arguments passed to a Python script. The item at index 0 in this list is always the name of the script, at index 1 is the argument passed from the command line.
Example of a script.py file:
import sys#print(sys.argv[0], argv[1],sys.argv[2]) # this line would print out: filename argument1 argument2print('Welcome {}. Enjoy {} challenge!'.format(sys.argv[1], sys.argv[2]))
Now to check how this script works I wrote in command line:
python script.py Asabeneh 30DaysOfPython
The result:
Welcome Asabeneh. Enjoy 30DayOfPython challenge!
Some useful sys commands:
# to exit syssys.exit()# To know the largest integer variable it takessys.maxsize# To know environment pathsys.path# To know the version of python you are usingsys.version
Statistics Module
The statistics module provides functions for mathematical statistics of numeric data. The popular statistical functions which are defined in this module: mean, median, mode, stdev etc.
from statistics import * # importing all the statistics modulesages = [20, 20, 4, 24, 25, 22, 26, 20, 23, 22, 26]print(mean(ages)) # ~22.9print(median(ages)) # 23print(mode(ages)) # 20print(stdev(ages)) # ~2.3
Math Module
Module containing many mathematical operations and constants.
import mathprint(math.pi) # 3.141592653589793, pi constantprint(math.sqrt(2)) # 1.4142135623730951, square rootprint(math.pow(2, 3)) # 8.0, exponential functionprint(math.floor(9.81)) # 9, rounding to the lowestprint(math.ceil(9.81)) # 10, rounding to the highestprint(math.log10(100)) # 2, logarithm with 10 as base
Now, we have imported the math module which contains lots of function which can help us to perform mathematical calculations. To check what functions the module has got, we can use help(math), or dir(math). This will display the available functions in the module. If we want to import only a specific function from the module we import it as follows:
from math import piprint(pi)
It is also possible to import multiple functions at once
But if we want to import all the function in math module we can use * .
from math import *print(pi) # 3.141592653589793, pi constantprint(sqrt(2)) # 1.4142135623730951, square rootprint(pow(2, 3)) # 8.0, exponentialprint(floor(9.81)) # 9, rounding to the lowestprint(ceil(9.81)) # 10, rounding to the highestprint(math.log10(100)) # 2
When we import we can also rename the name of the function.
from math import pi as PIprint(PI) # 3.141592653589793
String Module
A string module is a useful module for many purposes. The example below shows some use of the string module.
By now you are familiar with importing modules. Let us do one more import to get very familiar with it. Let us import random module which gives us a random number between 0 and 0.9999… The random module has lots of functions but in this section we will only use random and randint.
from random import random, randintprint(random()) # it doesn't take any arguments; it returns a value between 0 and 0.9999print(randint(5, 20)) # it returns a random integer number between [5, 20] inclusive
List Comprehension
List comprehension in Python is a compact way of creating a list from a sequence. It is a short way to create a new list. List comprehension is considerably faster than processing a list using the for loop.
# syntax[expression for i in iterable if condition]
Example:1
For instance if you want to change a string to a list of characters. You can use a couple of methods. Let’s see some of them:
# One waylanguage = 'Python'lst = list(language) # changing the string to listprint(type(lst)) # listprint(lst) # ['P', 'y', 't', 'h', 'o', 'n']# Second way: list comprehensionlst = [i for i in language]print(type(lst)) # listprint(lst) # ['P', 'y', 't', 'h', 'o', 'n']
Example:2
For instance if you want to generate a list of numbers
# Generating numbersnumbers = [i for i in range(11)] # to generate numbers from 0 to 10print(numbers) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]# It is possible to do mathematical operations during iterationsquares = [i * i for i in range(11)]print(squares) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]# It is also possible to make a list of tuplesnumbers = [(i, i * i) for i in range(11)]print(numbers) # [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
Example:2
List comprehension can be combined with if expression
# Generating even numberseven_numbers = [i for i in range(21) if i % 2 == 0] # to generate even numbers list in range 0 to 21print(even_numbers) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]# Generating odd numbersodd_numbers = [i for i in range(21) if i % 2 != 0] # to generate odd numbers in range 0 to 21print(odd_numbers) # [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]# Filter numbers: let's filter out positive even numbers from the list belownumbers = [-8, -7, -3, -1, 0, 1, 3, 4, 5, 7, 6, 8, 10]positive_even_numbers = [i for i in numbers if i % 2 == 0 and i > 0]print(positive_even_numbers) # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]# Flattening a two dimensional arraylist_of_lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]flattened_list = [ number for row in list_of_lists for number in row]print(flattened_list) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
Lambda Function
Lambda function is a small anonymous function without a name. It can take any number of arguments, but can only have one expression. Lambda function is similar to anonymous functions in JavaScript. We need it when we want to write an anonymous function inside another function.
Creating a Lambda Function
To create a lambda function we use lambda keyword followed by a parameter(s), followed by an expression. See the syntax and the example below. Lambda function does not use return but it explicitly returns the expression.
# Named functiondef add_two_nums(a, b): return a + bprint(add_two_nums(2, 3)) # 5# Lets change the above function to a lambda functionadd_two_nums = lambda a, b: a + bprint(add_two_nums(2,3)) # 5# Self invoking lambda function(lambda a, b: a + b)(2,3) # 5 - need to encapsulate it in print() to see the result in the consolesquare = lambda x : x ** 2print(square(3)) # 9cube = lambda x : x ** 3print(cube(3)) # 27# Multiple variablesmultiple_variable = lambda a, b, c: a ** 2 - 3 * b + 4 * cprint(multiple_variable(5, 5, 3)) # 22
Lambda Function Inside Another Function
Using a lambda function inside another function.
def power(x): return lambda n : x ** ncube = power(2)(3) # function power now need 2 arguments to run, in separate rounded bracketsprint(cube) # 8two_power_of_five = power(2)(5) print(two_power_of_five) # 32
Higher Order Functions
In Python functions are treated as first class citizens, allowing you to perform the following operations on functions:
A function can take one or more functions as parameters
A function can be returned as a result of another function
A function can be modified
A function can be assigned to a variable
In this section, we will cover:
Handling functions as parameters
Returning functions as return value from another functions
Using Python closures and decorators
Function as a Parameter
def sum_numbers(nums): # normal function return sum(nums) # a sad function abusing the built-in sum function :<def higher_order_function(f, lst): # function as a parameter summation = f(lst) return summationresult = higher_order_function(sum_numbers, [1, 2, 3, 4, 5])print(result) # 15
Function as a Return Value
def square(x): # a square function return x ** 2def cube(x): # a cube function return x ** 3def absolute(x): # an absolute value function if x >= 0: return x else: return -(x)def higher_order_function(type): # a higher order function returning a function if type == 'square': return square elif type == 'cube': return cube elif type == 'absolute': return absoluteresult = higher_order_function('square')print(result(3)) # 9result = higher_order_function('cube')print(result(3)) # 27result = higher_order_function('absolute')print(result(-3)) # 3
You can see from the above example that the higher order function is returning different functions depending on the passed parameter
Python Closures
Python allows a nested function to access the outer scope of the enclosing function. This is is known as a Closure. Let us have a look at how closures work in Python. In Python, closure is created by nesting a function inside another encapsulating function and then returning the inner function. See the example below.
Example:
def add_ten(): ten = 10 def add(num): return num + ten return addclosure_result = add_ten()print(closure_result(5)) # 15print(closure_result(10)) # 20
Python Decorators
A decorator is a design pattern in Python that allows a user to add new functionality to an existing object without modifying its structure. Decorators are usually called before the definition of a function you want to decorate.
Creating Decorators
To create a decorator function, we need an outer function with an inner wrapper function.
Example:
# Normal functiondef greeting(): return 'Welcome to Python'def uppercase_decorator(function): def wrapper(): func = function() make_uppercase = func.upper() return make_uppercase return wrapperg = uppercase_decorator(greeting)print(g()) # WELCOME TO PYTHON## Let us implement the example above with a decorator'''This decorator function is a higher order functionthat takes a function as a parameter'''def uppercase_decorator(function): def wrapper(): func = function() make_uppercase = func.upper() return make_uppercase return wrapper@uppercase_decoratordef greeting(): return 'Welcome to Python'print(greeting()) # WELCOME TO PYTHON
Applying Multiple Decorators to a Single Function
'''These decorator functions are higher order functionsthat take functions as parameters'''# First Decoratordef uppercase_decorator(function): def wrapper(): func = function() make_uppercase = func.upper() return make_uppercase return wrapper# Second decoratordef split_string_decorator(function): def wrapper(): func = function() splitted_string = func.split() return splitted_string return wrapper#Decorators will be executed from bottom to top@split_string_decorator@uppercase_decorator # order with decorators is important in this case - .upper() function does not work with listsdef greeting(): return 'Welcome to Python'print(greeting()) # ['WELCOME', 'TO', 'PYTHON']
Accepting Parameters in Decorator Functions
Most of the time we need our functions to take parameters, so we might need to define a decorator that accepts parameters.
def decorator_with_parameters(function): def wrapper_accepting_parameters(para1, para2, para3): function(para1, para2, para3) print("I live in {}".format(para3)) return wrapper_accepting_parameters@decorator_with_parametersdef print_full_name(first_name, last_name, country): print("I am {} {}. I love to teach.".format( first_name, last_name))print_full_name("Asabeneh", "Yetayeh",'Finland')
Built-in Higher Order Functions
Some of the built-in higher order functions that we cover in this part are map(), filter, and reduce.
Lambda function can be passed as a parameter and the best use case of lambda functions is in functions like map, filter and reduce.
Python - Map Function
The map() function is a built-in function that takes a function and iterable as parameters.
# syntax map(function, iterable)
Example:1
numbers = [1, 2, 3, 4, 5] # iterabledef square(x): return x ** 2numbers_squared = map(square, numbers)print(list(numbers_squared)) # [1, 4, 9, 16, 25]# Lets apply it with a lambda functionnumbers_squared = map(lambda x : x ** 2, numbers)print(list(numbers_squared)) # [1, 4, 9, 16, 25]
names = ['Asabeneh', 'Lidiya', 'Ermias', 'Abraham'] # iterabledef change_to_upper(name): return name.upper()names_upper_cased = map(change_to_upper, names)print(list(names_upper_cased)) # ['ASABENEH', 'LIDIYA', 'ERMIAS', 'ABRAHAM']# Let us apply it with a lambda functionnames_upper_cased = map(lambda name: name.upper(), names)print(list(names_upper_cased)) # ['ASABENEH', 'LIDIYA', 'ERMIAS', 'ABRAHAM']
What actually map does is iterating over a list. For instance, it changes the names to upper case and returns a new list.
Python - Filter Function
The filter() function calls the specified function which returns boolean for each item of the specified iterable (list). It filters the items that satisfy the filtering criteria.
# syntax filter(function, iterable)
Example:1
# Lets filter only even nubersnumbers = [1, 2, 3, 4, 5] # iterabledef is_even(num): if num % 2 == 0: return True return Falseeven_numbers = filter(is_even, numbers)print(list(even_numbers)) # [2, 4]
The reduce() function is defined in the functools module and we should import it from this module. Like map and filter it takes two parameters, a function and an iterable. However, it does not return another iterable, instead it returns a single value.
Example:1
When we write code it is common that we make a typo or some other common error. If our code fails to run, the Python interpreter will display a message, containing feedback with information on where the problem occurs and the type of an error. It will also sometimes gives us suggestions on a possible fix. Understanding different types of errors in programming languages will help us to debug our code quickly and also it makes us better at what we do.
Let us see the most common error types one by one. First let us open our Python interactive shell. Go to your you computer terminal and write ‘python’. The python interactive shell will be opened.
SyntaxError
Example 1: SyntaxError
asabeneh@Asabeneh:~$ pythonPython 3.9.6 (default, Jun 28 2021, 15:26:21)[Clang 11.0.0 (clang-1100.0.33.8)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> print 'hello world' File "<stdin>", line 1 print 'hello world' ^SyntaxError: Missing parentheses in call to 'print'. Did you mean print('hello world')?>>>
As you can see we made a syntax error because we forgot to enclose the string with parenthesis and Python already suggests the solution. Let us fix it.
asabeneh@Asabeneh:~$ pythonPython 3.9.6 (default, Jun 28 2021, 15:26:21)[Clang 11.0.0 (clang-1100.0.33.8)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> print 'hello world' File "<stdin>", line 1 print 'hello world' ^SyntaxError: Missing parentheses in call to 'print'. Did you mean print('hello world')?>>> print('hello world')hello world>>>
The error was a SyntaxError. After the fix our code was executed without a hitch. Let see more error types.
NameError
Example 1: NameError
asabeneh@Asabeneh:~$ pythonPython 3.9.6 (default, Jun 28 2021, 15:26:21)[Clang 11.0.0 (clang-1100.0.33.8)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> print(age)Traceback (most recent call last): File "<stdin>", line 1, in <module>NameError: name 'age' is not defined>>>
As you can see from the message above, name age is not defined. Yes, it is true that we did not define an age variable but we were trying to print it out as if we had had declared it. Now, lets fix this by declaring it and assigning with a value.
asabeneh@Asabeneh:~$ pythonPython 3.9.6 (default, Jun 28 2021, 15:26:21)[Clang 11.0.0 (clang-1100.0.33.8)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> print(age)Traceback (most recent call last): File "<stdin>", line 1, in <module>NameError: name 'age' is not defined>>> age = 25>>> print(age)25>>>
The type of error was a NameError. We debugged the error by defining the variable name.
IndexError
Example 1: IndexError
asabeneh@Asabeneh:~$ pythonPython 3.9.6 (default, Jun 28 2021, 15:26:21)[Clang 11.0.0 (clang-1100.0.33.8)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> numbers = [1, 2, 3, 4, 5]>>> numbers[5]Traceback (most recent call last): File "<stdin>", line 1, in <module>IndexError: list index out of range>>>
In the example above, Python raised an IndexError, because the list has only indexes from 0 to 4 , so it was out of range.
ModuleNotFoundError
Example 1: ModuleNotFoundError
asabeneh@Asabeneh:~$ pythonPython 3.9.6 (default, Jun 28 2021, 15:26:21)[Clang 11.0.0 (clang-1100.0.33.8)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> import mathsTraceback (most recent call last): File "<stdin>", line 1, in <module>ModuleNotFoundError: No module named 'maths'>>>
In the example above, I added an extra s to math deliberately and ModuleNotFoundError was raised. Lets fix it by removing the extra s from math.
asabeneh@Asabeneh:~$ pythonPython 3.9.6 (default, Jun 28 2021, 15:26:21)[Clang 11.0.0 (clang-1100.0.33.8)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> import mathsTraceback (most recent call last): File "<stdin>", line 1, in <module>ModuleNotFoundError: No module named 'maths'>>> import math>>>
We fixed it, so let’s use some of the functions from the math module.
AttributeError
Example 1: AttributeError
asabeneh@Asabeneh:~$ pythonPython 3.9.6 (default, Jun 28 2021, 15:26:21)[Clang 11.0.0 (clang-1100.0.33.8)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> import mathsTraceback (most recent call last): File "<stdin>", line 1, in <module>ModuleNotFoundError: No module named 'maths'>>> import math>>> math.PITraceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: module 'math' has no attribute 'PI'>>>
As you can see, I made a mistake again! Instead of pi, I tried to call a PI constant from maths module. It raised an attribute error, it means, that the attribute does not exist in the module. Lets fix it by changing from PI to pi.
asabeneh@Asabeneh:~$ pythonPython 3.9.6 (default, Jun 28 2021, 15:26:21)[Clang 11.0.0 (clang-1100.0.33.8)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> import mathsTraceback (most recent call last): File "<stdin>", line 1, in <module>ModuleNotFoundError: No module named 'maths'>>> import math>>> math.PITraceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: module 'math' has no attribute 'PI'>>> math.pi3.141592653589793>>>
Now, when we call pi from the math module we got the result.
KeyError
Example 1: KeyError
asabeneh@Asabeneh:~$ pythonPython 3.9.6 (default, Jun 28 2021, 15:26:21)[Clang 11.0.0 (clang-1100.0.33.8)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> users = {'name':'Asab', 'age':250, 'country':'Finland'}>>> users['name']'Asab'>>> users['county']Traceback (most recent call last): File "<stdin>", line 1, in <module>KeyError: 'county'>>>
As you can see, there was a typo in the key used to get the dictionary value. so, this is a key error and the fix is quite straight forward. Let’s do this!
asabeneh@Asabeneh:~$ pythonPython 3.9.6 (default, Jun 28 2021, 15:26:21)[Clang 11.0.0 (clang-1100.0.33.8)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> user = {'name':'Asab', 'age':250, 'country':'Finland'}>>> user['name']'Asab'>>> user['county']Traceback (most recent call last): File "<stdin>", line 1, in <module>KeyError: 'county'>>> user['country']'Finland'>>>
We debugged the error, our code ran and we got the value.
TypeError
Example 1: TypeError
asabeneh@Asabeneh:~$ pythonPython 3.9.6 (default, Jun 28 2021, 15:26:21)[Clang 11.0.0 (clang-1100.0.33.8)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> 4 + '3'Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: unsupported operand type(s) for +: 'int' and 'str'>>>
In the example above, a TypeError is raised because we cannot add a number to a string. First solution would be to convert the string to int or float. Another solution would be converting the number to a string (the result then would be ‘43’). Let us follow the first fix.
asabeneh@Asabeneh:~$ pythonPython 3.9.6 (default, Jun 28 2021, 15:26:21)[Clang 11.0.0 (clang-1100.0.33.8)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> 4 + '3'Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: unsupported operand type(s) for +: 'int' and 'str'>>> 4 + int('3')7>>> 4 + float('3')7.0>>>
Error removed and we got the result we expected.
ImportError
Example 1: TypeError
asabeneh@Asabeneh:~$ pythonPython 3.9.6 (default, Jun 28 2021, 15:26:21)[Clang 11.0.0 (clang-1100.0.33.8)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> from math import powerTraceback (most recent call last): File "<stdin>", line 1, in <module>ImportError: cannot import name 'power' from 'math'>>>
There is no function called power in the math module, it goes with a different name: pow. Let’s correct it:
asabeneh@Asabeneh:~$ pythonPython 3.9.6 (default, Jun 28 2021, 15:26:21)[Clang 11.0.0 (clang-1100.0.33.8)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> from math import powerTraceback (most recent call last): File "<stdin>", line 1, in <module>ImportError: cannot import name 'power' from 'math'>>> from math import pow>>> pow(2,3)8.0>>>
ValueError
asabeneh@Asabeneh:~$ pythonPython 3.9.6 (default, Jun 28 2021, 15:26:21)[Clang 11.0.0 (clang-1100.0.33.8)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> int('12a')Traceback (most recent call last): File "<stdin>", line 1, in <module>ValueError: invalid literal for int() with base 10: '12a'>>>
In this case we cannot change the given string to a number, because of the ‘a’ letter in it.
ZeroDivisionError
asabeneh@Asabeneh:~$ pythonPython 3.9.6 (default, Jun 28 2021, 15:26:21)[Clang 11.0.0 (clang-1100.0.33.8)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> 1/0Traceback (most recent call last): File "<stdin>", line 1, in <module>ZeroDivisionError: division by zero>>>
We cannot divide a number by zero.
We have covered some of the python error types, if you want to check more about it check the python documentation about python error types.
If you are good at reading the error types, then you will be able to fix your bugs fast and you will also become a better programmer.
Exception Handling
Python uses try and except to handle errors gracefully. A graceful exit (or graceful handling) of errors is a simple programming idiom - a program detects a serious error condition and “exits gracefully”, in a controlled manner as a result. Often the program prints a descriptive error message to a terminal or log as part of the graceful exit, this makes our application more robust. The cause of an exception is often external to the program itself. An example of exceptions could be an incorrect input, wrong file name, unable to find a file, a malfunctioning IO device. Graceful handling of errors prevents our applications from crashing.
We have covered the different Python error types in the previous section. If we use try and except in our program, then it will not raise errors in those blocks.