0% found this document useful (0 votes)
5 views209 pages

Python

The document provides an overview of variable declaration, user input, string formatting, and string manipulation in Python. It covers multiple variable declarations, string formatting methods (both old and new), and various string methods for manipulation and checking properties. Additionally, it includes examples of slicing, indexing, and reversing strings, along with exercises for practice.

Uploaded by

achidaaron4
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views209 pages

Python

The document provides an overview of variable declaration, user input, string formatting, and string manipulation in Python. It covers multiple variable declarations, string formatting methods (both old and new), and various string methods for manipulation and checking properties. Additionally, it includes examples of slicing, indexing, and reversing strings, along with exercises for practice.

Uploaded by

achidaaron4
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Declaring Multiple Variable in a Line

Multiple variables can also be declared in one line:

Example:

first_name, last_name, country, age, is_married = 'Asabeneh', 'Yetayeh',


'Helsink', 250, True

print(first_name, last_name, country, age, is_married)


print('First name:', first_name)
print('Last name: ', last_name)
print('Country: ', country)
print('Age: ', age)
print('Married: ', is_married)

Getting user input using the input() built-in function. Let us assign the data
we get from a user into first_name and age variables. Example:

first_name = input('What is your name: ')


age = input('How old are you? ')

print(first_name)
print(age)

# Variables in Python

first_name = 'Asabeneh'
last_name = 'Yetayeh'
country = 'Finland'
city = 'Helsinki'
age = 250
is_married = True
skills = ['HTML', 'CSS', 'JS', 'React', 'Python']
person_info = {
'firstname':'Asabeneh',

'lastname':'Yetayeh',

'country':'Finland',

'city':'Helsinki'
}

# Printing the values stored in the variables

print('First name:', first_name)

print('First name length:', len(first_name))

print('Last name: ', last_name)

print('Last name length: ', len(last_name))

print('Country: ', country)

print('City: ', city)

print('Age: ', age)

print('Married: ', is_married)

print('Skills: ', skills)

print('Person information: ', person_info)

# Declaring multiple variables in one line

first_name, last_name, country, age, is_married = 'Asabeneh', 'Yetayeh', 'Helsink', 250, True

print(first_name, last_name, country, age, is_married)

print('First name:', first_name)

print('Last name: ', last_name)

print('Country: ', country)

print('Age: ', age)

print('Married: ', is_married)

String formatting
Old Style String Formatting (% Operator)

In Python there are many ways of formatting strings. In this section, we will
cover some of them. The "%" operator is used to format a set of variables
enclosed in a "tuple" (a fixed size list), together with a format string, which
contains normal text together with "argument specifiers", special symbols
like "%s", "%d", "%f", "%.number of digitsf".

 %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 ([Link])

This formatting is 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)

a = 4
b = 3
print(f'{a} + {b} = {a +b}')
print(f'{a} - {b} = {a - b}')
print(f'{a} * {b} = {a * b}')
print(f'{a} / {b} = {a / b:.2f}')
print(f'{a} % {b} = {a % b}')
print(f'{a} // {b} = {a // b}')
print(f'{a} ** {b} = {a ** b}')

Unpacking Characters
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

Accessing Characters in Strings by Index

In programming counting starts from zero. Therefore the first letter of a


string is at zero index and the last letter of a string is the length of a string
minus one.
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

If we want to start from right end we can use negative indexing. -1 is the last
index.

language = 'Python'
last_letter = language[-1]
print(last_letter) # n
second_last = language[-2]
print(second_last) # o

Slicing Python Strings

In python we can slice strings into substrings.

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

Reversing a String
We can easily reverse strings in python.

greeting = 'Hello, World!'


print(greeting[::-1]) # !dlroW ,olleH

Skipping Characters While Slicing


It is possible to skip characters while slicing by passing step argument to
slice method.

language = 'Python'
pto = language[0:6:2] #
print(pto) # Pto

String Methods There are many string methods which allow us to


format strings. See some of the string methods in the following example:

capitalize(): Converts the first character of the string to capital letter

challenge = 'thirty days of python'


print([Link]()) # 'Thirty days of python'

 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([Link]('y')) # 3
print([Link]('y', 7, 14)) # 1,
print([Link]('th')) # 2`

 endswith(): Checks if a string ends with a specified ending

challenge = 'thirty days of python'


print([Link]('on')) # True
print([Link]('tion')) # False

 expandtabs(): Replaces tab character with spaces, default tab size is 8.


It takes tab size argument

challenge = 'thirty\tdays\tof\tpython'
print([Link]()) # 'thirty days of python'
print([Link](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([Link]('y')) # 5
print([Link]('th')) # 0

 rfind(): Returns the index of the last occurrence of a substring, if not


found returns -1

challenge = 'thirty days of python'


print([Link]('y')) # 16
print([Link]('th')) # 17

 format(): formats string into a nicer output


More about string formatting check this link

first_name = 'Asabeneh'
last_name = 'Yetayeh'
age = 250
job = 'teacher'
country = 'Finland'
sentence = 'I am {} {}. I am a {}. I am {} years old. I live in
{}.'.format(first_name, last_name, age, job, country)
print(sentence) # I am Asabeneh Yetayeh. I am 250 years old. I am a teacher.
I live in Finland.

radius = 10
pi = 3.14
area = pi * radius ** 2
result = 'The area of a circle with radius {} is {}'.format(str(radius),
str(area))
print(result) # The area of a circle with radius 10 is 314

 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([Link](sub_string)) # 7
print([Link](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([Link](sub_string)) # 7
print([Link](sub_string, 9)) # error
print([Link]('on', 8)) # 19

 isalnum(): Checks alphanumeric character

challenge = 'ThirtyDaysPython'
print([Link]()) # True

challenge = '30DaysPython'
print([Link]()) # True

challenge = 'thirty days of python'


print([Link]()) # False, space is not an alphanumeric character
challenge = 'thirty days of python 2019'
print([Link]()) # False

 isalpha(): Checks if all string elements are alphabet characters (a-z and
A-Z)

challenge = 'thirty days of python'


print([Link]()) # False, space is once again excluded
challenge = 'ThirtyDaysPython'
print([Link]()) # True
num = '123'
print([Link]()) # False

 isdecimal(): Checks if all characters in a string are decimal (0-9)

challenge = 'thirty days of python'


print([Link]()) # False
challenge = '123'
print([Link]()) # True
challenge = '\u00B2'
print([Link]()) # False
challenge = '12 3'
print([Link]()) # False, space not allowed

 isdigit(): Checks if all characters in a string are numbers (0-9 and some
other unicode characters for numbers)

challenge = 'Thirty'
print([Link]()) # False
challenge = '30'
print([Link]()) # True
challenge = '\u00B2'
print([Link]()) # True

 isnumeric(): Checks if all characters in a string are numbers or number


related (just like isdigit(), just accepts more symbols, like ½)

num = '10'
print([Link]()) # True
num = '\u00BD' # ½
print([Link]()) # True
num = '10.5'
print([Link]()) # False

 isidentifier(): Checks for a valid identifier - it checks if a string is a valid


variable name

challenge = '30DaysOfPython'
print([Link]()) # False, because it starts with a number
challenge = 'thirty_days_of_python'
print([Link]()) # True
 islower(): Checks if all alphabet characters in the string are lowercase

challenge = 'thirty days of python'


print([Link]()) # True
challenge = 'Thirty days of python'
print([Link]()) # False

 isupper(): Checks if all alphabet characters in the string are uppercase

challenge = 'thirty days of python'


print([Link]()) # False
challenge = 'THIRTY DAYS OF PYTHON'
print([Link]()) # True

 join(): Returns a concatenated string

web_tech = ['HTML', 'CSS', 'JavaScript', 'React']


result = ' '.join(web_tech)
print(result) # 'HTML CSS JavaScript React'
web_tech = ['HTML', 'CSS', 'JavaScript', 'React']
result = '# '.join(web_tech)
print(result) # 'HTML# CSS# JavaScript# React'

 strip(): Removes all given characters starting from the beginning and
end of the string

challenge = 'thirty days of pythoonnn'


print([Link]('noth')) # 'irty days of py'

 replace(): Replaces substring with a given string

challenge = 'thirty days of python'


print([Link]('python', 'coding')) # 'thirty days of coding'

 split(): Splits the string, using given string or space as a separator

challenge = 'thirty days of python'


print([Link]()) # ['thirty', 'days', 'of', 'python']
challenge = 'thirty, days, of, python'
print([Link](', ')) # ['thirty', 'days', 'of', 'python']

 title(): Returns a title cased string

challenge = 'thirty days of python'


print([Link]()) # Thirty Days Of Python

 swapcase(): Converts all uppercase characters to lowercase and all


lowercase characters to uppercase characters
challenge = 'thirty days of python'
print([Link]()) # THIRTY DAYS OF PYTHON
challenge = 'Thirty Days Of Python'
print([Link]()) # tHIRTY dAYS oF pYTHON

 startswith(): Checks if String Starts with the Specified String

challenge = 'thirty days of python'


print([Link]('thirty')) # True

challenge = '30 days of python'


print([Link]('thirty')) # False

🌕 You are an extraordinary person and you have a remarkable potential. You
have just completed day 4 challenges and you are four steps a head in to
your way to greatness. Now do some exercises for your brain and muscles.

1. Use the string formatting method to display the following:

radius = 10
area = 3.14 * radius ** 2
The area of a circle with radius 10 is 314 meters square.

36. Make the following using string formatting methods:

8 + 6 = 14
8 - 6 = 2
8 * 6 = 48
8 / 6 = 1.33
8 % 6 = 2
8 // 6 = 1
8 ** 6 = 262144

# Single line comment


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 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
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 = 'Asabeneh'
last_name = 'Yetayeh'
space = ' '
full_name = first_name + space + last_name
print(full_name) # Asabeneh Yetayeh
# Checking length of a string using len() builtin function
print(len(first_name)) # 8
print(len(last_name)) # 7
print(len(first_name) > len(last_name)) # True
print(len(full_name)) # 15

#### Unpacking characters


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

# Accessing characters in strings by index


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

# If we want to start from right end we can use negative indexing. -1 is the
last index
language = 'Python'
last_letter = language[-1]
print(last_letter) # n
second_last = language[-2]
print(second_last) # o

# Slicing

language = 'Python'
first_three = language[0:3] # starts at zero index and up to 3 but not
include 3
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

# Skipping character while splitting Python strings


language = 'Python'
pto = language[0:6:2] #
print(pto) # pto
# Escape sequence
print('I hope every one enjoying the python challenge.\nDo you ?') # line
break
print('Days\tTopics\tExercises')
print('Day 1\t3\t5')
print('Day 2\t3\t5')
print('Day 3\t3\t5')
print('Day 4\t3\t5')
print('This is a back slash symbol (\\)') # To write a back slash
print('In every programming language it starts with \"Hello, World!\"')

## String Methods
# capitalize(): Converts the first character the string to Capital Letter

challenge = 'thirty days of python'


print([Link]()) # 'Thirty days of python'

# count(): returns occurrences of substring in string, count(substring,


start=.., end=..)

challenge = 'thirty days of python'


print([Link]('y')) # 3
print([Link]('y', 7, 14)) # 1
print([Link]('th')) # 2`

# endswith(): Checks if a string ends with a specified ending

challenge = 'thirty days of python'


print([Link]('on')) # True
print([Link]('tion')) # False

# expandtabs(): Replaces tab character with spaces, default tab size is 8. It


takes tab size argument
challenge = 'thirty\tdays\tof\tpython'
print([Link]()) # 'thirty days of python'
print([Link](10)) # 'thirty days of python'

# find(): Returns the index of first occurrence of substring

challenge = 'thirty days of python'


print([Link]('y')) # 5
print([Link]('th')) # 0

# format() formats string into nicer output


first_name = 'Asabeneh'
last_name = 'Yetayeh'
job = 'teacher'
country = 'Finland'
sentence = 'I am {} {}. I am a {}. I live in {}.'.format(first_name,
last_name, job, country)
print(sentence) # I am Asabeneh Yetayeh. I am a teacher. I live in Finland.

radius = 10
pi = 3.14
area = pi # radius ## 2
result = 'The area of circle with {} is {}'.format(str(radius), str(area))
print(result) # The area of circle with 10 is 314.0

# index(): Returns the index of substring


challenge = 'thirty days of python'
print([Link]('y')) # 5
print([Link]('th')) # 0

# isalnum(): Checks alphanumeric character


challenge = 'ThirtyDaysPython'
print([Link]()) # True

challenge = '30DaysPython'
print([Link]()) # True

challenge = 'thirty days of python'


print([Link]()) # False

challenge = 'thirty days of python 2019'


print([Link]()) # False

# isalpha(): Checks if all characters are alphabets

challenge = 'thirty days of python'


print([Link]()) # True
num = '123'
print([Link]()) # False

# isdecimal(): Checks Decimal Characters

challenge = 'thirty days of python'


print([Link]('y')) # 5
print([Link]('th')) # 0

# isdigit(): Checks Digit Characters

challenge = 'Thirty'
print([Link]()) # False
challenge = '30'
print([Link]()) # True

# isdecimal():Checks decimal characters


num = '10'
print([Link]()) # True
num = '10.5'
print([Link]()) # False

# isidentifier():Checks for valid identifier means it check if a string is a


valid variable name

challenge = '30DaysOfPython'
print([Link]()) # False, because it starts with a number
challenge = 'thirty_days_of_python'
print([Link]()) # True

# islower():Checks if all alphabets in a string are lowercase

challenge = 'thirty days of python'


print([Link]()) # True
challenge = 'Thirty days of python'
print([Link]()) # False

# isupper(): returns if all characters are uppercase characters

challenge = 'thirty days of python'


print([Link]()) # False
challenge = 'THIRTY DAYS OF PYTHON'
print([Link]()) # True

# isnumeric():Checks numeric characters


num = '10'
print([Link]()) # True
print('ten'.isnumeric()) # False

# join(): Returns a concatenated string

web_tech = ['HTML', 'CSS', 'JavaScript', 'React']


result = '#, '.join(web_tech)
print(result) # 'HTML# CSS# JavaScript# React'

# strip(): Removes both leading and trailing characters

challenge = ' thirty days of python '


print([Link]('y')) # 5

# replace(): Replaces substring inside

challenge = 'thirty days of python'


print([Link]('python', 'coding')) # 'thirty days of coding'

# split():Splits String from Left

challenge = 'thirty days of python'


print([Link]()) # ['thirty', 'days', 'of', 'python']

# title(): Returns a Title Cased String

challenge = 'thirty days of python'


print([Link]()) # Thirty Days Of Python

# swapcase(): Checks if String Starts with the Specified String

challenge = 'thirty days of python'


print([Link]()) # THIRTY DAYS OF PYTHON
challenge = 'Thirty Days Of Python'
print([Link]()) # tHIRTY dAYS oF pYTHON

# startswith(): Checks if String Starts with the Specified String

challenge = 'thirty days of python'


print([Link]('thirty')) # True
challenge = '30 days of python'
print([Link]('thirty')) # False

How to Create a List


In Python we can create lists in two ways:

 Using list built-in function

# syntax
lst = list()
empty_list = list() # this is an empty list, no item in the list
print(len(empty_list)) # 0

 Using square brackets, []

# syntax
lst = []
empty_list = [] # this is an empty list, no item in the list
print(len(empty_list)) # 0

Lists with initial values. We use len() to find the length of a list.

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))
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

 Lists can have items of different data types

lst = ['Asabeneh', 250, True, {'country':'Finland', 'city':'Helsinki'}] #


list containing different data type

Accessing List Items Using Positive Indexing


We access each item in a list using their index. A list index starts from 0. The
picture below shows clearly where the index start

fruits = ['banana', 'orange', 'mango', 'lemon']


first_fruit = fruits[0] # we are accessing the first item using its index
print(first_fruit) # banana
second_fruit = fruits[1]
print(second_fruit) # orange
last_fruit = fruits[3]
print(last_fruit) # lemon
# Last index
last_index = len(fruits) - 1
last_fruit = fruits[last_index]
Accessing List Items Using Negative Indexing

Negative indexing means beginning from the end, -1 refers to the last item, -
2 refers to the second last item.

fruits = ['banana', 'orange', 'mango', 'lemon']


first_fruit = fruits[-4]
last_fruit = fruits[-1]
second_last = fruits[-2]
print(first_fruit) # banana
print(last_fruit) # lemon
print(second_last) # mango

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 above
all_fruits = fruits[0:] # if we don't set where to stop it takes all the rest
orange_and_mango = fruits[1:3] # it does not include the first index
orange_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 fruits
orange_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.

fruits = ['banana', 'orange', 'mango', 'lemon']


fruits[0] = 'avocado'
print(fruits) # ['avocado', 'orange', 'mango', 'lemon']
fruits[1] = 'apple'
print(fruits) # ['avocado', 'apple', 'mango', 'lemon']
last_index = len(fruits) - 1
fruits[last_index] = 'lime'
print(fruits) # ['avocado', 'apple', 'mango', 'lime']

Checking Items in a List


Checking an item if it is a member of a list using in operator. See the
example below.

fruits = ['banana', 'orange', 'mango', 'lemon']


does_exist = 'banana' in fruits
print(does_exist) # True
does_exist = 'lime' in fruits
print(does_exist) # False

Adding Items to a List


To add item to the end of an existing list we use the method append().

# syntax
lst = list()
[Link](item)
fruits = ['banana', 'orange', 'mango', 'lemon']
[Link]('apple')
print(fruits) # ['banana', 'orange', 'mango', 'lemon', 'apple']
[Link]('lime') # ['banana', 'orange', 'mango', 'lemon', 'apple',
'lime']
print(fruits)

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.

# syntax
lst = ['item1', 'item2']
[Link](index, item)
fruits = ['banana', 'orange', 'mango', 'lemon']
[Link](2, 'apple') # insert apple between orange and mango
print(fruits) # ['banana', 'orange', 'apple', 'mango', 'lemon']
[Link](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

# syntax
lst = ['item1', 'item2']
[Link](item)
fruits = ['banana', 'orange', 'mango', 'lemon', 'banana']
[Link]('banana')
print(fruits) # ['orange', 'mango', 'lemon', 'banana'] - this method removes
the first occurrence of the item in the list
[Link]('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):

# syntax
lst = ['item1', 'item2']
[Link]() # last item
[Link](index)
fruits = ['banana', 'orange', 'mango', 'lemon']
[Link]()
print(fruits) # ['banana', 'orange', 'mango']

[Link](0)
print(fruits) # ['orange', 'mango']

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

# syntax
lst = ['item1', 'item2']
del lst[index] # only a single item
del 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 fruits
print(fruits) # This should give: NameError: name 'fruits' is not
defined

Clearing List Items


The clear() method empties the list:

# syntax
lst = ['item1', 'item2']
[Link]()
fruits = ['banana', 'orange', 'mango', 'lemon']
[Link]()
print(fruits) # []

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().

# syntax
lst = ['item1', 'item2']
lst_copy = [Link]()
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits_copy = [Link]()
print(fruits_copy) # ['banana', 'orange', 'mango', 'lemon']

Joining Lists
There are several ways to join, or concatenate, two or more lists in Python.

 Plus Operator (+)

# syntax
list3 = list1 + list2
positive_numbers = [1, 2, 3, 4, 5]
zero = [0]
negative_numbers = [-5,-4,-3,-2,-1]
integers = negative_numbers + zero + positive_numbers
print(integers) # [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
fruits = ['banana', 'orange', 'mango', 'lemon']
vegetables = ['Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
fruits_and_vegetables = fruits + vegetables
print(fruits_and_vegetables ) # ['banana', 'orange', 'mango', 'lemon',
'Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']

 Joining using extend() method The extend() method allows to append


list in a list. See the example below.

# syntax
list1 = ['item1', 'item2']
list2 = ['item3', 'item4', 'item5']
[Link](list2)
num1 = [0, 1, 2, 3]
num2= [4, 5, 6]
[Link](num2)
print('Numbers:', num1) # Numbers: [0, 1, 2, 3, 4, 5, 6]
negative_numbers = [-5,-4,-3,-2,-1]
positive_numbers = [1, 2, 3,4,5]
zero = [0]

negative_numbers.extend(zero)
negative_numbers.extend(positive_numbers)
print('Integers:', negative_numbers) # Integers: [-5, -4, -3, -2, -1, 0, 1,
2, 3, 4, 5]
fruits = ['banana', 'orange', 'mango', 'lemon']
vegetables = ['Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']
[Link](vegetables)
print('Fruits and vegetables:', fruits ) # Fruits and vegetables: ['banana',
'orange', 'mango', 'lemon', 'Tomato', 'Potato', 'Cabbage', 'Onion', 'Carrot']

Counting Items in a List


The count() method returns the number of times an item appears in a list:

# syntax
lst = ['item1', 'item2']
[Link](item)
fruits = ['banana', 'orange', 'mango', 'lemon']
print([Link]('orange')) # 1
ages = [22, 19, 24, 25, 26, 24, 25, 24]
print([Link](24)) # 3

Finding Index of an Item


The index() method returns the index of an item in the list:

# syntax
lst = ['item1', 'item2']
[Link](item)
fruits = ['banana', 'orange', 'mango', 'lemon']
print([Link]('orange')) # 1
ages = [22, 19, 24, 25, 26, 24, 25, 24]
print([Link](24)) # 2, the first occurrence

Reversing a List
The reverse() method reverses the order of a list.

# syntax
lst = ['item1', 'item2']
[Link]()
fruits = ['banana', 'orange', 'mango', 'lemon']
[Link]()
print(fruits) # ['lemon', 'mango', 'orange', 'banana']
ages = [22, 19, 24, 25, 26, 24, 25, 24]
[Link]()
print(ages) # [24, 25, 24, 26, 25, 24, 19, 22]

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

 # syntax
 lst = ['item1', 'item2']
 [Link]() # ascending
[Link](reverse=True) # descending

Example:

fruits = ['banana', 'orange', 'mango', 'lemon']


[Link]()
print(fruits) # sorted in alphabetical order, ['banana',
'lemon', 'mango', 'orange']
[Link](reverse=True)
print(fruits) # ['orange', 'mango', 'lemon', 'banana']
ages = [22, 19, 24, 25, 26, 24, 25, 24]
[Link]()
print(ages) # [19, 22, 24, 24, 24, 25, 25, 26]

[Link](reverse=True)
print(ages) # [26, 25, 25, 24, 24, 24, 22, 19]

sorted(): returns the ordered list without modifying the original


list Example:

fruits = ['banana', 'orange', 'mango', 'lemon']


print(sorted(fruits)) # ['banana', 'lemon', 'mango', 'orange']
# Reverse order
fruits = ['banana', 'orange', 'mango', 'lemon']
fruits = sorted(fruits,reverse=True)
print(fruits) # ['orange', 'mango', 'lemon', 'banana']
empty_list = 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 it 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('Number of countries:', len(countries))

# Modifying list

fruits = ['banana', 'orange', 'mango', 'lemon']


first_fruit = fruits[0] # we are accessing the first item using its index
print(first_fruit) # banana
second_fruit = fruits[1]
print(second_fruit) # orange
last_fruit = fruits[3]
print(last_fruit) # lemon
# Last index
last_index = len(fruits) - 1
last_fruit = fruits[last_index]

# Accessing items
fruits = ['banana', 'orange', 'mango', 'lemon']
last_fruit = fruits[-1]
second_last = fruits[-2]
print(last_fruit) # lemon
print(second_last) # mango

# Slicing items
fruits = ['banana', 'orange', 'mango', 'lemon']
all_fruits = fruits[0:4] # it returns all the fruits
# this is also give the same result as the above
all_fruits = fruits[0:] # if we don't set where to stop it takes all the rest
orange_and_mango = fruits[1:3] # it does not include the end index
orange_mango_lemon = fruits[1:]

fruits = ['banana', 'orange', 'mango', 'lemon']


all_fruits = fruits[-4:] # it returns all the fruits
# this is also give the same result as the above
orange_and_mango = fruits[-3:-1] # it does not include the end index
orange_mango_lemon = fruits[-3:]

fruits = ['banana', 'orange', 'mango', 'lemon']


fruits[0] = 'Avocado'
print(fruits) # ['avocado', 'orange', 'mango', 'lemon']
fruits[1] = 'apple'
print(fruits) # ['avocado', 'apple', 'mango', 'lemon']
last_index = len(fruits) - 1
fruits[last_index] = 'lime'
print(fruits) # ['avocado', 'apple', 'mango', 'lime']

# checking items
fruits = ['banana', 'orange', 'mango', 'lemon']
does_exist = 'banana' in fruits
print(does_exist) # True
does_exist = 'lime' in fruits
print(does_exist) # False
# Append
fruits = ['banana', 'orange', 'mango', 'lemon']
[Link]('apple')
print(fruits) # ['banana', 'orange', 'mango', 'lemon', 'apple']
[Link]('lime') # ['banana', 'orange', 'mango', 'lemon', 'apple',
'lime]
print(fruits)

# insert
fruits = ['banana', 'orange', 'mango', 'lemon']
[Link](2, 'apple') # insert apple between orange and mango
print(fruits) # ['banana', 'orange', 'apple', 'mango', 'lemon']
[Link](3, 'lime') # ['banana', 'orange', 'apple', 'mango',
'lime','lemon',]
print(fruits)

# remove
fruits = ['banana', 'orange', 'mango', 'lemon']
[Link]('banana')
print(fruits) # ['orange', 'mango', 'lemon']
[Link]('lemon')
print(fruits) # ['orange', 'mango']

# pop
fruits = ['banana', 'orange', 'mango', 'lemon']
[Link]()
print(fruits) # ['banana', 'orange', 'mango']

[Link](0)
print(fruits) # ['orange', 'mango']

# del
fruits = ['banana', 'orange', 'mango', 'lemon']
del fruits[0]
print(fruits) # ['orange', 'mango', 'lemon']

del fruits[1]
print(fruits) # ['orange', 'lemon']
del fruits
print(fruits) # This should give: NameError: name 'fruits' is not
defined

# clear
fruits = ['banana', 'orange', 'mango', 'lemon']
[Link]()
print(fruits) # []

# copying a lits

fruits = ['banana', 'orange', 'mango', 'lemon']


fruits_copy = [Link]()
print(fruits_copy) # ['banana', 'orange', 'mango', 'lemon']

# join
positive_numbers = [1, 2, 3,4,5]
zero = [0]
negative_numbers = [-5,-4,-3,-2,-1]
integers = negative_numbers + zero + positive_numbers
print(integers)
fruits = ['banana', 'orange', 'mango', 'lemon']
vegetables = ['Tomato', 'Potato', 'Cabbage','Onion', 'Carrot']
fruits_and_vegetables = fruits + vegetables
print(fruits_and_vegetables )

# join with extend


num1 = [0, 1, 2, 3]
num2= [4, 5,6]
[Link](num2)
print('Numbers:', num1)
negative_numbers = [-5,-4,-3,-2,-1]
positive_numbers = [1, 2, 3,4,5]
zero = [0]

negative_numbers.extend(zero)
negative_numbers.extend(positive_numbers)
print('Integers:', negative_numbers)
fruits = ['banana', 'orange', 'mango', 'lemon']
vegetables = ['Tomato', 'Potato', 'Cabbage','Onion', 'Carrot']
[Link](vegetables)
print('Fruits and vegetables:', fruits )

# count
fruits = ['banana', 'orange', 'mango', 'lemon']
print([Link]('orange')) # 1
ages = [22, 19, 24, 25, 26, 24, 25, 24]
print([Link](24)) # 3

# index
fruits = ['banana', 'orange', 'mango', 'lemon']
print([Link]('orange')) # 1
ages = [22, 19, 24, 25, 26, 24, 25, 24]
print([Link](24))
# Reverse
fruits = ['banana', 'orange', 'mango', 'lemon']
[Link]()
print(fruits)
ages = [22, 19, 24, 25, 26, 24, 25, 24]
[Link]()
print(ages)
# sort
fruits = ['banana', 'orange', 'mango', 'lemon']
[Link]()
print(fruits)
[Link](reverse=True)
print(fruits)
ages = [22, 19, 24, 25, 26, 24, 25, 24]
[Link]()
print(ages)
[Link](reverse=True)
print(ages)

Tuples
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

o operator: to join two or more tuples and to create a new tuple

Creating a Tuple
 Empty tuple: Creating an empty tuple

 # syntax
 empty_tuple = ()
 # or using the tuple constructor
empty_tuple = tuple()

 Tuple with initial values

 # syntax
tpl = ('item1', 'item2','item3')
fruits = ('banana', 'orange', 'mango', 'lemon')
Tuple length
We use the len() method to get the length of a tuple.

# syntax
tpl = ('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.

 # Syntax
 tpl = ('item1', 'item2', 'item3')
 first_item = tpl[0]
second_item = tpl[1]
fruits = ('banana', 'orange', 'mango', 'lemon')
first_fruit = fruits[0]
second_fruit = fruits[1]
last_index =len(fruits) - 1
last_fruit = fruits[las_index]

 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.

 # Syntax
 tpl = ('item1', 'item2', 'item3','item4')
 first_item = tpl[-4]
second_item = tpl[-3]
fruits = ('banana', 'orange', 'mango', 'lemon')
first_fruit = fruits[-4]
second_fruit = fruits[-3]
last_fruit = fruits[-1]

Slicing tuples
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

 # Syntax
 tpl = ('item1', 'item2', 'item3','item4')
 all_items = tpl[0:4] # all items
 all_items = tpl[0:] # all items
middle_two_items = tpl[1:3] # does not include item at index 3
fruits = ('banana', 'orange', 'mango', 'lemon')
all_fruits = fruits[0:4] # all items
all_fruits= fruits[0:] # all items
orange_mango = fruits[1:3] # doesn't include item at index 3
orange_to_the_rest = fruits[1:]

 Range of Negative Indexes

 # Syntax
 tpl = ('item1', 'item2', 'item3','item4')
 all_items = tpl[-4:] # all items
middle_two_items = tpl[-3:-1] # does not include item at index 3 (-1)
fruits = ('banana', 'orange', 'mango', 'lemon')
all_fruits = fruits[-4:] # all items
orange_mango = fruits[-3:-1] # doesn't include item at index 3
orange_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.

# Syntax
tpl = ('item1', 'item2', 'item3','item4')
lst = list(tpl)
fruits = ('banana', 'orange', 'mango', 'lemon')
fruits = list(fruits)
fruits[0] = 'apple'
print(fruits) # ['apple', 'orange', 'mango', 'lemon']
fruits = tuple(fruits)
print(fruits) # ('apple', 'orange', 'mango', 'lemon')

Checking an Item in a Tuple


We can check if an item exists or not in a tuple using in, it returns a boolean.

# Syntax
tpl = ('item1', 'item2', 'item3','item4')
'item2' in tpl # True
fruits = ('banana', 'orange', 'mango', 'lemon')
print('orange' in fruits) # True
print('apple' in fruits) # False
fruits[0] = 'apple' # TypeError: 'tuple' object does not support item
assignment

Joining Tuples
We can join two or more tuples using + operator

# syntax
tpl1 = ('item1', 'item2', 'item3')
tpl2 = ('item4', 'item5','item6')
tpl3 = tpl1 + tpl2
fruits = ('banana', 'orange', 'mango', 'lemon')
vegetables = ('Tomato', 'Potato', 'Cabbage','Onion', 'Carrot')
fruits_and_vegetables = fruits + vegetables

Deleting Tuples
It is not possible to remove a single item in a tuple but it is possible to delete
the tuple itself using del.

# syntax
tpl1 = ('item1', 'item2', 'item3')
del tpl1
fruits = ('banana', 'orange', 'mango', 'lemon')
del fruits

🌕 You are so brave, you made it to this far. You have just completed day 6
challenges and you are 6 steps a head in to your way to greatness. Now do
some exercises for your brain and for your muscle.

Sets
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
We use the set() built-in function.

 Creating an empty set

# syntax
st = set()

 Creating a set with initial items

# syntax
st = {'item1', 'item2', 'item3', 'item4'}

Example:

# syntax
fruits = {'banana', 'orange', 'mango', 'lemon'}

Getting Set's Length


We use len() method to find the length of a set.

# syntax
st = {'item1', 'item2', 'item3', 'item4'}
len(st)

Example:

fruits = {'banana', 'orange', 'mango', 'lemon'}


len(fruits)

Accessing Items in a Set


We use loops to access items. We will see this in loop section

Checking an Item
To check if an item exist in a list we use in membership operator.

# syntax
st = {'item1', 'item2', 'item3', 'item4'}
print("Does set st contain item3? ", 'item3' in st) # Does set st contain
item3? True

Example:

fruits = {'banana', 'orange', 'mango', 'lemon'}


print('mango' in fruits ) # True
Adding Items to a Set
Once a set is created we cannot change any items and we can also add
additional items.

 Add one item using add()

# syntax
st = {'item1', 'item2', 'item3', 'item4'}
[Link]('item5')

Example:

fruits = {'banana', 'orange', 'mango', 'lemon'}


[Link]('lime')

 Add multiple items using update() The update() allows to add multiple
items to a set. The update() takes a list argument.

# syntax
st = {'item1', 'item2', 'item3', 'item4'}
[Link](['item5','item6','item7'])

Example:

fruits = {'banana', 'orange', 'mango', 'lemon'}


vegetables = ('tomato', 'potato', 'cabbage','onion', 'carrot')
[Link](vegetables)

Removing Items from a Set


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.

# syntax
st = {'item1', 'item2', 'item3', 'item4'}
[Link]('item2')

The pop() methods remove a random item from a list and it returns the
removed item.

Example:

fruits = {'banana', 'orange', 'mango', 'lemon'}


[Link]() # removes a random item from the set

If we are interested in the removed item.

fruits = {'banana', 'orange', 'mango', 'lemon'}


removed_item = [Link]()
Clearing Items in a Set
If we want to clear or empty the set we use clear method.

# syntax
st = {'item1', 'item2', 'item3', 'item4'}
[Link]()

Example:

fruits = {'banana', 'orange', 'mango', 'lemon'}


[Link]()
print(fruits) # set()

Deleting a Set
If we want to delete the set itself we use del operator.

# syntax
st = {'item1', 'item2', 'item3', 'item4'}
del st

Example:

fruits = {'banana', 'orange', 'mango', 'lemon'}


del fruits

Converting List to Set


We can convert list to set and set to list. Converting list to set removes
duplicates and only unique items will be reserved.

# syntax
lst = ['item1', 'item2', 'item3', 'item4', 'item1']
st = set(lst) # {'item2', 'item4', 'item1', 'item3'} - the order is random,
because sets in general are unordered

Example:

fruits = ['banana', 'orange', 'mango', 'lemon','orange', 'banana']


fruits = set(fruits) # {'mango', 'lemon', 'banana', 'orange'}

Joining Sets
We can join two sets using the union() or update() method.

 Union This method returns a new set

# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item5', 'item6', 'item7', 'item8'}
st3 = [Link](st2)

Example:

fruits = {'banana', 'orange', 'mango', 'lemon'}


vegetables = {'tomato', 'potato', 'cabbage','onion', 'carrot'}
print([Link](vegetables)) # {'lemon', 'carrot', 'tomato', 'banana',
'mango', 'orange', 'cabbage', 'potato', 'onion'}

 Update This method inserts a set into a given set

# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item5', 'item6', 'item7', 'item8'}
[Link](st2) # st2 contents are added to st1

Example:

fruits = {'banana', 'orange', 'mango', 'lemon'}


vegetables = {'tomato', 'potato', 'cabbage','onion', 'carrot'}
[Link](vegetables)
print(fruits) # {'lemon', 'carrot', 'tomato', 'banana', 'mango', 'orange',
'cabbage', 'potato', 'onion'}

Finding Intersection Items


Intersection returns a set of items which are in both the sets. See the
example

# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item3', 'item2'}
[Link](st2) # {'item3', 'item2'}

Example:

whole_numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}


even_numbers = {0, 2, 4, 6, 8, 10}
whole_numbers.intersection(even_numbers) # {0, 2, 4, 6, 8, 10}

python = {'p', 'y', 't', 'h', 'o','n'}


dragon = {'d', 'r', 'a', 'g', 'o','n'}
[Link](dragon) # {'o', 'n'}

Checking Subset and Super Set


A set can be a subset or super set of other sets:

 Subset: issubset()
 Super set: issuperset
# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item2', 'item3'}
[Link](st1) # True
[Link](st2) # True

Example:

whole_numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}


even_numbers = {0, 2, 4, 6, 8, 10}
whole_numbers.issubset(even_numbers) # False, because it is a super set
whole_numbers.issuperset(even_numbers) # True

python = {'p', 'y', 't', 'h', 'o','n'}


dragon = {'d', 'r', 'a', 'g', 'o','n'}
[Link](dragon) # False

Checking the Difference Between Two Sets


It returns the difference between two sets.

# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item2', 'item3'}
[Link](st1) # set()
[Link](st2) # {'item1', 'item4'} => st1\st2

Example:

whole_numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}


even_numbers = {0, 2, 4, 6, 8, 10}
whole_numbers.difference(even_numbers) # {1, 3, 5, 7, 9}

python = {'p', 'y', 't', 'o','n'}


dragon = {'d', 'r', 'a', 'g', 'o','n'}
[Link](dragon) # {'p', 'y', 't'} - the result is unordered
(characteristic of sets)
[Link](python) # {'d', 'r', 'a', 'g'}

Finding Symmetric Difference Between Two Sets


It returns the symmetric difference between two sets. It means that it returns

both sets, mathematically: (A\B) ∪ (B\A)


a set that contains all items from both sets, except items that are present in

# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item2', 'item3'}
# it means (A\B)∪(B\A)
st2.symmetric_difference(st1) # {'item1', 'item4'}

Example:
whole_numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
some_numbers = {1, 2, 3, 4, 5}
whole_numbers.symmetric_difference(some_numbers) # {0, 6, 7, 8, 9, 10}

python = {'p', 'y', 't', 'h', 'o','n'}


dragon = {'d', 'r', 'a', 'g', 'o','n'}
python.symmetric_difference(dragon) # {'r', 't', 'p', 'y', 'g', 'a', 'd',
'h'}

Joining Sets
If two sets do not have a common item or items we call them disjoint sets.
We can check if two sets are joint or disjoint using isdisjoint() method.

# syntax
st1 = {'item1', 'item2', 'item3', 'item4'}
st2 = {'item2', 'item3'}
[Link](st1) # False

Example:

even_numbers = {0, 2, 4 ,6, 8}


odd_numbers = {1, 3, 5, 7, 9}
even_numbers.isdisjoint(odd_numbers) # True, because no common item

python = {'p', 'y', 't', 'h', 'o','n'}


dragon = {'d', 'r', 'a', 'g', 'o','n'}
[Link](dragon) # False, there are common items {'o', 'n'}

🌕 You are a rising star . You have just completed day 7 challenges and you
are 7 steps ahead in to your way to greatness. Now do some exercises for
your brain and muscles.

Dictionaries
A dictionary is a collection of unordered, modifiable(mutable) paired (key:
value) data type.

Creating a Dictionary
To create a dictionary we use curly brackets, {} or the dict() built-in function.

# syntax
empty_dict = {}
# Dictionary with data values
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}

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'
}
}

The dictionary above shows that a value could be any data types:string,
boolean, list, tuple, set or a dictionary.

Dictionary Length
It checks the number of 'key: value' pairs in the dictionary.

# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
print(len(dct)) # 4

Example:

person = {
'first_name':'Asabeneh',
'last_name':'Yetayeh',
'age':250,
'country':'Finland',
'is_married':True,
'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
'address':{
'street':'Space street',
'zipcode':'02210'
}
}
print(len(person)) # 7

Accessing Dictionary Items


We can access Dictionary items by referring to its key name.

# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
print(dct['key1']) # value1
print(dct['key4']) # value4

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'
}
}
print(person['first_name']) # Asabeneh
print(person['country']) # Finland
print(person['skills']) # ['JavaScript', 'React', 'Node', 'MongoDB',
'Python']
print(person['skills'][0]) # JavaScript
print(person['address']['street']) # Space street
print(person['city']) # Error

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.

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'
}
}
print([Link]('first_name')) # Asabeneh
print([Link]('country')) # Finland
print([Link]('skills')) #['HTML','CSS','JavaScript', 'React', 'Node',
'MongoDB', 'Python']
print([Link]('city')) # None

Adding Items to a Dictionary


We can add new key and value pairs to a dictionary

# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
dct['key5'] = 'value5'

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'
}
}
person['job_title'] = 'Instructor'
person['skills'].append('HTML')
print(person)

Modifying Items in a Dictionary


We can modify items in a dictionary

# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
dct['key1'] = 'value-one'

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'
}
}
person['first_name'] = 'Eyob'
person['age'] = 252

Checking Keys in a Dictionary


We use the in operator to check if a key exist in a dictionary

# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
print('key2' in dct) # True
print('key5' in dct) # False

Removing Key and Value Pairs from a Dictionary


 pop(key): removes the item with the specified key name:
 popitem(): removes the last item
 del: removes an item with specified key name

# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
[Link]('key1') # removes key1 item
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
[Link]() # removes the last item
del dct['key2'] # removes key2 item

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'
}
}
[Link]('first_name') # Removes the firstname item
[Link]() # Removes the address item
del person['is_married'] # Removes the is_married item

Changing Dictionary to a List of Items


The items() method changes dictionary to a list of tuples.

# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
print([Link]()) # dict_items([('key1', 'value1'), ('key2', 'value2'),
('key3', 'value3'), ('key4', 'value4')])

Clearing a Dictionary
If we don't want the items in a dictionary we can clear them
using clear() method

# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
print([Link]()) # None

Deleting a Dictionary
If we do not use the dictionary we can delete it completely

# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
del dct

Copy a Dictionary
We can copy a dictionary using a copy() method. Using copy we can avoid
mutation of the original dictionary.

# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
dct_copy = [Link]() # {'key1':'value1', 'key2':'value2', 'key3':'value3',
'key4':'value4'}

Getting Dictionary Keys as a List


The keys() method gives us all the keys of a a dictionary as a list.

# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
keys = [Link]()
print(keys) # dict_keys(['key1', 'key2', 'key3', 'key4'])

Getting Dictionary Values as a List


The values method gives us all the values of a a dictionary as a list.

# syntax
dct = {'key1':'value1', 'key2':'value2', 'key3':'value3', 'key4':'value4'}
values = [Link]()
print(values) # dict_values(['value1', 'value2', 'value3', 'value4'])

🌕 You are astonishing. Now, you are super charged with the power of
dictionaries. You have just completed day 8 challenges and you are 8 steps a
head in to your way to greatness. Now do some exercises for your brain and
muscles.

Conditionals
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.

# syntax
if condition:
this part of code runs for truthy conditions

Example: 1

a = 3
if 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.

# syntax
if condition:
this part of code runs for truthy conditions
else:
this part of code runs for false conditions

Example:

a = 3
if 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.
# syntax
if condition:
code
elif condition:
code
else:
code

Example:

a = 0
if a > 0:
print('A is a positive number')
elif a < 0:
print('A is a negative number')
else:
print('A is zero')

Short Hand
# syntax
code if condition else code

Example:

a = 3
print('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

# syntax
if condition:
code
if condition:
code

Example:

a = 0
if 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
# syntax
if condition and condition:
code

Example:

a = 0
if 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


# syntax
if condition or condition:
code

Example:

user = 'James'
access_level = 3
if user == 'admin' or access_level >= 4:
print('Access granted!')
else:
print('Access denied!')

🌕 You are doing [Link] give up because great things take time. You
have just completed day 9 challenges and you are 9 steps a head in to your
way to greatness. Now do some exercises for your brain and muscles.

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:

1. while loop
2. 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.

# syntax
while condition:
code goes here

Example:

count = 0
while 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.

# syntax
while condition:
code goes here
else:
code goes here

Example:

count = 0
while count < 5:
print(count)
count = count + 1
else:
print(count)

The above loop condition will be false when count is 5 and the loop stops,
and execution starts the else statement. As a result 5 will be printed.

Break and Continue - Part 1


 Break: We use break when we like to get out of or stop the loop.

# syntax
while condition:
code goes here
if another_condition:
break

Example:

count = 0
while count < 5:
print(count)
count = count + 1
if count == 3:
break

The above while loop only prints 0, 1, 2, but when it reaches 3 it stops.

 Continue: With the continue statement we can skip the current


iteration, and continue with the next:

# syntax
while condition:
code goes here
if another_condition:
continue

Example:

count = 0
while count < 5:
if count == 3:
count = count + 1
continue
print(count)
count = count + 1

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).

 For loop with list

# syntax
for 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

 For loop with string

# syntax
for iterator in string:
code goes here

Example:

language = 'Python'
for letter in language:
print(letter)

for i in range(len(language)):
print(language[i])

 For loop with tuple

# syntax
for 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.

# syntax
for 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 [Link]():


print(key, value) # this way we get both keys and values printed out

 Loops in set
# syntax
for 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 like to stop our loop before it
is completed.

# syntax
for 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 like to skip some of the steps in the
iteration of the loop.

# syntax
for 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
statements
print('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 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 1
print(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}
# syntax
for 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.

# syntax
for 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.

# syntax
for iterator in range(start, end, step):
do something
else:
print('The loop ended')

Example:

for number in range(11):


print(number) # prints 0 to 10, not including 11
else:
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

🌕 You established a big milestone, you are unstoppable. Keep going! You
have just completed day 10 challenges and you are 10 steps a head in to
your way to greatness. Now do some exercises for your brain and muscles.

Functions
So far we have seen many built-in Python functions. In this section, we will
focus on custom 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. Function can be declared
with or without parameters.

# syntax
# Declaring a function
def function_name():
codes
codes
# Calling a function
function_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 function

def 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


Function can also return values, if a function does not have a return
statement, the value of the function is 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.

def generate_full_name ():


first_name = 'Asabeneh'
last_name = 'Yetayeh'
space = ' '
full_name = first_name + space + last_name
return full_name
print(generate_full_name())

def add_two_numbers ():


num_one = 2
num_two = 3
total = num_one + num_two
return total
print(add_two_numbers())

Function with Parameters


In a function we can pass different data types(number, string, boolean, list,
tuple, dictionary or set) as a parameter

 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 message

print(greetings('Asabeneh'))

def add_ten(num):
ten = 10
return num + ten
print(add_ten(90))

def square_number(x):
return x * x
print(square_number(2))

def area_of_circle (r):


PI = 3.14
area = PI * r ** 2
return area
print(area_of_circle(10))

def sum_of_numbers(n):
total = 0
for i in range(n+1):
total+=i
print(total)
print(sum_of_numbers(10)) # 55
print(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_name
print('Full Name: ', generate_full_name('Asabeneh','Yetayeh'))

def sum_two_numbers (num_one, num_two):


sum = num_one + num_two
return sum
print('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 weight
print('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 function
def function_name(para1, para2):
codes
codes
# Calling function
print(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(print_fullname(firstname = 'Asabeneh', lastname = 'Yetayeh'))

def add_two_numbers (num1, num2):


total = num1 + num2
print(total)
print(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.

 Returning a string: Example:

def print_name(firstname):
return firstname
print_name('Asabeneh') # Asabeneh

def print_full_name(firstname, lastname):


space = ' '
full_name = firstname + space + lastname
return full_name
print_full_name(firstname='Asabeneh', lastname='Yetayeh')

 Returning a number:

Example:

def add_two_numbers (num1, num2):


total = num1 + num2
return total
print(add_two_numbers(2, 3))

def calculate_age (current_year, birth_year):


age = current_year - birth_year
return age;
print('Age: ', calculate_age(2019, 1819))

 Returning a boolean: Example:


def is_even (n):
if n % 2 == 0:
print('even')
return True # return stops further execution of the function,
similar to break
return False
print(is_even(10)) # True
print(is_even(7)) # False

 Returning a list: Example:

def find_even_numbers(n):
evens = []
for i in range(n + 1):
if i % 2 == 0:
[Link](i)
return evens
print(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.

# syntax
# Declaring a function
def function_name(param = value):
codes
codes
# Calling function
function_name()
function_name(arg)

Example:

def greetings (name = 'Peter'):


message = name + ', welcome to Python for Everyone!'
return message
print(greetings())
print(greetings('Asabeneh'))

def generate_full_name (first_name = 'Asabeneh', last_name = 'Yetayeh'):


space = ' '
full_name = first_name + space + last_name
return full_name

print(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 weight
print('Weight of an object in Newtons: ', weight_of_object(100)) # 9.81 -
average gravity on Earth's surface
print('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.

# syntax
# Declaring a function
def function_name(*args):
codes
codes
# Calling function
function_name(param1, param2, param3,..)

Example:

def sum_all_nums(*nums):
total = 0
for num in nums:
total += num # same as total = total + num
return total
print(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)
print(generate_groups('Team-1','Asabeneh','Brook','David','Eyob'))

Function as a Parameter of Another Function


#You can pass functions around as parameters
def square_number (n):
return n * n
def do_something(f, x):
return f(x)
print(do_something(square_number, 3)) # 27
🌕 You achieved quite a lot so far. Keep going! You have just completed day
11 challenges and you are 11 steps a head in to your way to greatness. Now
do some exercises for your brain and muscles.

Exercises: Level 2
1. Declare a function named evens_and_odds . It takes a positive integer
as parameter and it counts number of evens and odds in the number.

print(evens_and_odds(100))
# The number of odds are 50.
# The number of evens are 51.

1. Call your function factorial, it takes a whole number as a parameter


and it return a factorial of the number
2. Call your function is_empty, it takes a parameter and it checks if it is
empty or not
3. Write different functions which take lists. They should calculate_mean,
calculate_median, calculate_mode, calculate_range,
calculate_variance, calculate_std (standard deviation).

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 [Link] inside your project folder. Let us
write some code in this file.

# [Link] file
def generate_full_name(firstname, lastname):
return firstname + ' ' + lastname

Create [Link] file in your project directory and import the [Link]
file.

Importing a Module
To import the file we use the import keyword and the name of the file only.
# [Link] file
import mymodule
print(mymodule.generate_full_name('Asabeneh', 'Yetayeh')) # Asabeneh Yetayeh

Import Functions from a Module


We can have many functions in a file and we can import all the functions
differently.

# [Link] file
from mymodule import generate_full_name, sum_two_nums, person, gravity
print(generate_full_name('Asabneh','Yetayeh'))
print(sum_two_nums(1,9))
mass = 100;
weight = mass * gravity
print(weight)
print(person['firstname'])

Import Functions from a Module and Renaming


During importing we can rename the name of the module.

# [Link] file
from mymodule import generate_full_name as fullname, sum_two_nums as total,
person as p, gravity as g
print(fullname('Asabneh','Yetayeh'))
print(total(1, 9))
mass = 100;
weight = mass * g
print(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 module


import os
# Creating a directory
[Link]('directory_name')
# Changing the current directory
[Link]('path')
# Getting current working directory
[Link]()
# Removing directory
[Link]()

Sys Module
The sys module provides functions and variables used to manipulate
different parts of the Python runtime environment. Function [Link] 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 [Link] file:

import sys
#print([Link][0], argv[1],[Link][2]) # this line would print out:
filename argument1 argument2
print('Welcome {}. Enjoy {} challenge!'.format([Link][1], [Link][2]))

Now to check how this script works I wrote in command line:

python [Link] Asabeneh 30DaysOfPython

The result:

Welcome Asabeneh. Enjoy 30DayOfPython challenge!

Some useful sys commands:

# to exit sys
[Link]()
# To know the largest integer variable it takes
[Link]
# To know environment path
[Link]
# To know the version of python you are using
[Link]

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 modules


ages = [20, 20, 4, 24, 25, 22, 26, 20, 23, 22, 26]
print(mean(ages)) # ~22.9
print(median(ages)) # 23
print(mode(ages)) # 20
print(stdev(ages)) # ~2.3

Math Module
Module containing many mathematical operations and constants.

import math
print([Link]) # 3.141592653589793, pi constant
print([Link](2)) # 1.4142135623730951, square root
print([Link](2, 3)) # 8.0, exponential function
print([Link](9.81)) # 9, rounding to the lowest
print([Link](9.81)) # 10, rounding to the highest
print(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 pi


print(pi)

It is also possible to import multiple functions at once

from math import pi, sqrt, pow, floor, ceil, log10


print(pi) # 3.141592653589793
print(sqrt(2)) # 1.4142135623730951
print(pow(2, 3)) # 8.0
print(floor(9.81)) # 9
print(ceil(9.81)) # 10
print(math.log10(100)) # 2

But if we want to import all the function in math module we can use * .

from math import *


print(pi) # 3.141592653589793, pi constant
print(sqrt(2)) # 1.4142135623730951, square root
print(pow(2, 3)) # 8.0, exponential
print(floor(9.81)) # 9, rounding to the lowest
print(ceil(9.81)) # 10, rounding to the highest
print(math.log10(100)) # 2

When we import we can also rename the name of the function.

from math import pi as PI


print(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.

import string
print(string.ascii_letters) #
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
print([Link]) # 0123456789
print([Link]) # !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

Random 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, randint


print(random()) # it doesn't take any arguments; it returns a value between
0 and 0.9999
print(randint(5, 20)) # it returns a random integer number between [5, 20]
inclusive

🌕 You are going far. Keep going! You have just completed day 12 challenges
and you are 12 steps a head in to your way to greatness. Now do some
exercises for your brain and muscles.

[Link]

from mymodule import generate_full_name as fullname, sum_two_nums as total,


person as p, gravity as g

print(fullname('Asabneh','Yetayeh'))

print(total(1, 9))

mass = 100;

weight = mass * g

print(weight)

print(p)

print(p['firstname']
My [Link]

def generate_full_name(firstname, lastname):

space = ' '

fullname = firstname + space + lastname

return fullname

def sum_two_nums (num1, num2):

return num1 + num2

gravity = 9.81

person = {

"firstname": "Asabeneh",

"age": 250,

"country": "Finland",

"city":'Helsinki'

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
[i for i in iterable if expression]

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 way
language = 'Python'
lst = list(language) # changing the string to list
print(type(lst)) # list
print(lst) # ['P', 'y', 't', 'h', 'o', 'n']

# Second way: list comprehension


lst = [i for i in language]
print(type(lst)) # list
print(lst) # ['P', 'y', 't', 'h', 'o', 'n']

Example:2

For instance if you want to generate a list of numbers

# Generating numbers
numbers = [i for i in range(11)] # to generate numbers from 0 to 10
print(numbers) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# It is possible to do mathematical operations during iteration


squares = [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 tuples


numbers = [(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 numbers


even_numbers = [i for i in range(21) if i % 2 == 0] # to generate even
numbers list in range 0 to 21
print(even_numbers) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18,
20]

# Generating odd numbers


odd_numbers = [i for i in range(21) if i % 2 != 0] # to generate odd numbers
in range 0 to 21
print(odd_numbers) # [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
# Filter numbers: let's filter out positive even numbers from the list below
numbers = [-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 three dimensional array


list_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.

# syntax
x = lambda param1, param2, param3: param1 + param2 + param2
print(x(arg1, arg2, arg3))

Example:

# Named function
def add_two_nums(a, b):
return a + b

print(add_two_nums(2, 3)) # 5
# Lets change the above function to a lambda function
add_two_nums = lambda a, b: a + b
print(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 console

square = lambda x : x ** 2
print(square(3)) # 9
cube = lambda x : x ** 3
print(cube(3)) # 27

# Multiple variables
multiple_variable = lambda a, b, c: a ** 2 - 3 * b + 4 * c
print(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 ** n

cube = power(2)(3) # function power now need 2 arguments to run, in


separate rounded brackets
print(cube) # 8
two_power_of_five = power(2)(5)
print(two_power_of_five) # 32
🌕 Keep up the good work. Keep the momentum going, the sky is the limit!
You have just completed day 13 challenges and you are 13 steps a head in
to your way to greatness. Now do some exercises for your brain and
muscles.

💻 Exercises: Day 13
1. Filter only negative and zero in the list using list comprehension

numbers = [-4, -3, -2, -1, 0, 2, 4, 6]

2. Flatten the following list of lists of lists to a one dimensional list :

3. list_of_lists =[[[1, 2, 3]], [[4, 5, 6]], [[7, 8, 9]]]


4.
5. output
[1, 2, 3, 4, 5, 6, 7, 8, 9]

6. Using list comprehension create the following list of tuples:

7. [(0, 1, 0, 0, 0, 0, 0),
8. (1, 1, 1, 1, 1, 1, 1),
9. (2, 1, 2, 4, 8, 16, 32),
10. (3, 1, 3, 9, 27, 81, 243),
11. (4, 1, 4, 16, 64, 256, 1024),
12. (5, 1, 5, 25, 125, 625, 3125),
13. (6, 1, 6, 36, 216, 1296, 7776),
14. (7, 1, 7, 49, 343, 2401, 16807),
15. (8, 1, 8, 64, 512, 4096, 32768),
16. (9, 1, 9, 81, 729, 6561, 59049),
(10, 1, 10, 100, 1000, 10000, 100000)]

17. Flatten the following list to a new list:

18. countries = [[('Finland', 'Helsinki')], [('Sweden', 'Stockholm')],


[('Norway', 'Oslo')]]
19. output:
[['FINLAND','FIN', 'HELSINKI'], ['SWEDEN', 'SWE', 'STOCKHOLM'],
['NORWAY', 'NOR', 'OSLO']]

20. Change the following list to a list of dictionaries:

21. countries = [[('Finland', 'Helsinki')], [('Sweden', 'Stockholm')],


[('Norway', 'Oslo')]]
22. output:
23. [{'country': 'FINLAND', 'city': 'HELSINKI'},
24. {'country': 'SWEDEN', 'city': 'STOCKHOLM'},
{'country': 'NORWAY', 'city': 'OSLO'}]

25. Change the following list of lists to a list of concatenated strings:


26. names = [[('Asabeneh', 'Yetayeh')], [('David', 'Smith')], [('Donald',
'Trump')], [('Bill', 'Gates')]]
27. output
['Asabeneh Yetaeyeh', 'David Smith', 'Donald Trump', 'Bill Gates']

28. Write a lambda function which can solve a slope or y-intercept of


linear functions.

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:

1. Handling functions as parameters


2. Returning functions as return value from another functions
3. 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 summation
result = 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 ** 2

def cube(x): # a cube function


return x ** 3

def 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 absolute

result = higher_order_function('square')
print(result(3)) # 9
result = higher_order_function('cube')
print(result(3)) # 27
result = 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 add

closure_result = add_ten()
print(closure_result(5)) # 15
print(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 function
def greeting():
return 'Welcome to Python'
def uppercase_decorator(function):
def wrapper():
func = function()
make_uppercase = [Link]()
return make_uppercase
return wrapper
g = uppercase_decorator(greeting)
print(g()) # WELCOME TO PYTHON

## Let us implement the example above with a decorator

'''This decorator function is a higher order function


that takes a function as a parameter'''
def uppercase_decorator(function):
def wrapper():
func = function()
make_uppercase = [Link]()
return make_uppercase
return wrapper
@uppercase_decorator
def greeting():
return 'Welcome to Python'
print(greeting()) # WELCOME TO PYTHON

Applying Multiple Decorators to a Single Function


'''These decorator functions are higher order functions
that take functions as parameters'''

# First Decorator
def uppercase_decorator(function):
def wrapper():
func = function()
make_uppercase = [Link]()
return make_uppercase
return wrapper

# Second decorator
def split_string_decorator(function):
def wrapper():
func = function()
splitted_string = [Link]()
return splitted_string

return wrapper
@split_string_decorator
@uppercase_decorator # order with decorators is important in this case
- .upper() function does not work with lists
def 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_parameters
def print_full_name(first_name, last_name, country):
print("I am {} {}. I love to teach.".format(
first_name, last_name, country))

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] # iterable


def square(x):
return x ** 2
numbers_squared = map(square, numbers)
print(list(numbers_squared)) # [1, 4, 9, 16, 25]
# Lets apply it with a lambda function
numbers_squared = map(lambda x : x ** 2, numbers)
print(list(numbers_squared)) # [1, 4, 9, 16, 25]

Example:2

numbers_str = ['1', '2', '3', '4', '5'] # iterable


numbers_int = map(int, numbers_str)
print(list(numbers_int)) # [1, 2, 3, 4, 5]

Example:3

names = ['Asabeneh', 'Lidiya', 'Ermias', 'Abraham'] # iterable

def change_to_upper(name):
return [Link]()

names_upper_cased = map(change_to_upper, names)


print(list(names_upper_cased)) # ['ASABENEH', 'LIDIYA', 'ERMIAS',
'ABRAHAM']

# Let us apply it with a lambda function


names_upper_cased = map(lambda name: [Link](), 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 nubers


numbers = [1, 2, 3, 4, 5] # iterable

def is_even(num):
if num % 2 == 0:
return True
return False

even_numbers = filter(is_even, numbers)


print(list(even_numbers)) # [2, 4]

Example:2

numbers = [1, 2, 3, 4, 5] # iterable

def is_odd(num):
if num % 2 != 0:
return True
return False

odd_numbers = filter(is_odd, numbers)


print(list(odd_numbers)) # [1, 3, 5]
# Filter long name
names = ['Asabeneh', 'Lidiya', 'Ermias', 'Abraham'] # iterable
def is_name_long(name):
if len(name) > 7:
return True
return False

long_names = filter(is_name_long, names)


print(list(long_names)) # ['Asabeneh']

Python - Reduce Function


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

numbers_str = ['1', '2', '3', '4', '5'] # iterable


def add_two_nums(x, y):
return int(x) + int(y)

total = reduce(add_two_nums, numbers_str)


print(total) # 15

💻 Exercises: Day 14
countries = ['Estonia', 'Finland', 'Sweden', 'Denmark', 'Norway', 'Iceland']
names = ['Asabeneh', 'Lidiya', 'Ermias', 'Abraham']
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Exercises: Level 1
1. Explain the difference between map, filter, and reduce.
2. Explain the difference between higher order function, closure and
decorator
3. Define a call function before map, filter or reduce, see examples.
4. Use for loop to print each country in the countries list.
5. Use for to print each name in the names list.
6. Use for to print each number in the numbers list.
Exercises: Level 2
1. Use map to create a new list by changing each country to uppercase in
the countries list
2. Use map to create a new list by changing each number to its square in
the numbers list
3. Use map to change each name to uppercase in the names list
4. Use filter to filter out countries containing 'land'.
5. Use filter to filter out countries having exactly six characters.
6. Use filter to filter out countries containing six letters and more in the
country list.
7. Use filter to filter out countries starting with an 'E'
8. Chain two or more list iterators (eg.
[Link](callback).filter(callback).reduce(callback))
9. Declare a function called get_string_lists which takes a list as a
parameter and then returns a list containing only string items.
10. Use reduce to sum all the numbers in the numbers list.
11. Use reduce to concatenate all the countries and to produce this
sentence: Estonia, Finland, Sweden, Denmark, Norway, and Iceland are
north European countries
12. Declare a function called categorize_countries that returns a list
of countries with some common pattern (you can find the countries
list in this repository as [Link](eg 'land', 'ia', 'island', 'stan')).
13. Create a function returning a dictionary, where keys stand for
starting letters of countries and values are the number of country
names starting with that letter.
14. Declare a get_first_ten_countries function - it returns a list of first
ten countries from the [Link] list in the data folder.
15. Declare a get_last_ten_countries function that returns the last
ten countries in the countries list.

Python Error Types


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:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "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:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "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:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "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:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "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:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "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:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (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:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (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:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'maths'
>>> import math
>>> [Link]
Traceback (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
function from maths module. It raised an attribute error, it means, that the
function does not exist in the module. Lets fix it by changing from PI to pi.

asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import maths
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'maths'
>>> import math
>>> [Link]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'math' has no attribute 'PI'
>>> [Link]
3.141592653589793
>>>

Now, when we call pi from the math module we got the result.

KeyError
Example 1: KeyError

asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "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:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "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:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "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:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "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:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from math import power
Traceback (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:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from math import power
Traceback (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:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "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:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 1/0
Traceback (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.

🌕 You are excelling. You made it to half way to your way to greatness. Now
do some exercises for your brain and for your muscle.

Python datetime
Python has got datetime module to handle date and time.

import datetime
print(dir(datetime))
['MAXYEAR', 'MINYEAR', '__builtins__', '__cached__', '__doc__', '__file__',
'__loader__', '__name__', '__package__', '__spec__', 'date', 'datetime',
'datetime_CAPI', 'sys', 'time', 'timedelta', 'timezone', 'tzinfo']

With dir or help built-in commands it is possible to know the available


functions in a certain module. As you can see, in the datetime module there
are many functions, but we will focus on date, datetime, time and timedelta.
Let se see them one by one.

Getting datetime Information


from datetime import datetime
now = [Link]()
print(now) # 2021-07-08 07:34:46.549883
day = [Link] # 8
month = [Link] # 7
year = [Link] # 2021
hour = [Link] # 7
minute = [Link] # 38
second = [Link]
timestamp = [Link]()
print(day, month, year, hour, minute)
print('timestamp', timestamp)
print(f'{day}/{month}/{year}, {hour}:{minute}') # 8/7/2021, 7:38

Timestamp or Unix timestamp is the number of seconds elapsed from 1st of


January 1970 UTC.

Formatting Date Output Using strftime


from datetime import datetime
new_year = datetime(2020, 1, 1)
print(new_year) # 2020-01-01 00:00:00
day = new_year.day
month = new_year.month
year = new_year.year
hour = new_year.hour
minute = new_year.minute
second = new_year.second
print(day, month, year, hour, minute) #1 1 2020 0 0
print(f'{day}/{month}/{year}, {hour}:{minute}') # 1/1/2020, 0:0

Formatting date time using strftime method and the documentation can be
found here.

from datetime import datetime


# current date and time
now = [Link]()
t = [Link]("%H:%M:%S")
print("time:", t)
time_one = [Link]("%m/%d/%Y, %H:%M:%S")
# mm/dd/YY H:M:S format
print("time one:", time_one)
time_two = [Link]("%d/%m/%Y, %H:%M:%S")
# dd/mm/YY H:M:S format
print("time two:", time_two)
time: 01:05:01
time one: 12/05/2019, 01:05:01
time two: 05/12/2019, 01:05:01

Here are all the strftime symbols we use to format time. An example of all
the formats for this module.
String to Time Using strptime
Here is a documentation hat helps to understand the format.

from datetime import datetime


date_string = "5 December, 2019"
print("date_string =", date_string)
date_object = [Link](date_string, "%d %B, %Y")
print("date_object =", date_object)
date_string = 5 December, 2019
date_object = 2019-12-05 00:00:00

Using date from datetime


from datetime import date
d = date(2020, 1, 1)
print(d)
print('Current date:', [Link]()) # 2019-12-05
# date object of today's date
today = [Link]()
print("Current year:", [Link]) # 2019
print("Current month:", [Link]) # 12
print("Current day:", [Link]) # 5

Time Objects to Represent Time


from datetime import time
# time(hour = 0, minute = 0, second = 0)
a = time()
print("a =", a)
# time(hour, minute and second)
b = time(10, 30, 50)
print("b =", b)
# time(hour, minute and second)
c = time(hour=10, minute=30, second=50)
print("c =", c)
# time(hour, minute, second, microsecond)
d = time(10, 30, 50, 200555)
print("d =", d)

output
a = 00:00:00
b = 10:30:50
c = 10:30:50
d = 10:30:50.200555

Difference Between Two Points in Time Using


today = date(year=2019, month=12, day=5)
new_year = date(year=2020, month=1, day=1)
time_left_for_newyear = new_year - today
# Time left for new year: 27 days, 0:00:00
print('Time left for new year: ', time_left_for_newyear)

t1 = datetime(year = 2019, month = 12, day = 5, hour = 0, minute = 59, second


= 0)
t2 = datetime(year = 2020, month = 1, day = 1, hour = 0, minute = 0, second =
0)
diff = t2 - t1
print('Time left for new year:', diff) # Time left for new year: 26 days, 23:
01: 00

Difference Between Two Points in Time


Using timedelta
from datetime import timedelta
t1 = timedelta(weeks=12, days=10, hours=4, seconds=20)
t2 = timedelta(days=7, hours=5, minutes=3, seconds=30)
t3 = t1 - t2
print("t3 =", t3)
date_string = 5 December, 2019
date_object = 2019-12-05 00:00:00
t3 = 86 days, 22:56:50

🌕 You are an extraordinary. You are 16 steps a head to your way to


greatness. Now do some exercises for your brain and mus

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.
try:
code in this block if things go well
except:
code in this block run if things go wrong

Example:

try:
print(10 + '5')
except:
print('Something went wrong')
In the example above the second operand is a string. We could change it to
float or int to add it with the number to make it work. But without any
changes, the second block, except, will be executed.

Example:

try:
name = input('Enter your name:')
year_born = input('Year you were born:')
age = 2019 - year_born
print(f'You are {name}. And your age is {age}.')
except:
print('Something went wrong')
Something went wrong

In the above example, the exception block will run and we do not know
exactly the problem. To analyze the problem, we can use the different error
types with except.

In the following example, it will handle the error and will also tell us the kind
of error raised.

try:
name = input('Enter your name:')
year_born = input('Year you were born:')
age = 2019 - year_born
print(f'You are {name}. And your age is {age}.')
except TypeError:
print('Type error occured')
except ValueError:
print('Value error occured')
except ZeroDivisionError:
print('zero division error occured')
Enter your name:Asabeneh
Year you born:1920
Type error occured

In the code above the output is going to be TypeError. Now, let's add an
additional block:

try:
name = input('Enter your name:')
year_born = input('Year you born:')
age = 2019 - int(year_born)
print(f'You are {name}. And your age is {age}.')
except TypeError:
print('Type error occur')
except ValueError:
print('Value error occur')
except ZeroDivisionError:
print('zero division error occur')
else:
print('I usually run with the try block')
finally:
print('I alway run.')
Enter your name:Asabeneh
Year you born:1920
You are Asabeneh. And your age is 99.
I usually run with the try block
I alway run.

It is also shorten the above code as follows:

try:
name = input('Enter your name:')
year_born = input('Year you born:')
age = 2019 - int(year_born)
print(f'You are {name}. And your age is {age}.')
except Exception as e:
print(e)

Packing and Unpacking Arguments in Python


We use two operators:

 * for tuples
 ** for dictionaries

Let us take as an example below. It takes only arguments but we have list.
We can unpack the list and changes to argument.

Unpacking

Unpacking Lists

def sum_of_five_nums(a, b, c, d, e):


return a + b + c + d + e

lst = [1, 2, 3, 4, 5]
print(sum_of_five_nums(lst)) # TypeError: sum_of_five_nums() missing 4
required positional arguments: 'b', 'c', 'd', and 'e'

When we run the this code, it raises an error, because this function takes
numbers (not a list) as arguments. Let us unpack/destructure the list.

def sum_of_five_nums(a, b, c, d, e):


return a + b + c + d + e

lst = [1, 2, 3, 4, 5]
print(sum_of_five_nums(*lst)) # 15
We can also use unpacking in the range built-in function that expects a start
and an end.

numbers = range(2, 7) # normal call with separate arguments


print(list(numbers)) # [2, 3, 4, 5, 6]
args = [2, 7]
numbers = range(*args) # call with arguments unpacked from a list
print(numbers) # [2, 3, 4, 5,6]

A list or a tuple can also be unpacked like this:

countries = ['Finland', 'Sweden', 'Norway', 'Denmark', 'Iceland']


fin, sw, nor, *rest = countries
print(fin, sw, nor, rest) # Finland Sweden Norway ['Denmark', 'Iceland']
numbers = [1, 2, 3, 4, 5, 6, 7]
one, *middle, last = numbers
print(one, middle, last) # 1 [2, 3, 4, 5, 6] 7

Unpacking Dictionaries

def unpacking_person_info(name, country, city, age):


return f'{name} lives in {country}, {city}. He is {age} year old.'
dct = {'name':'Asabeneh', 'country':'Finland', 'city':'Helsinki', 'age':250}
print(unpacking_person_info(**dct)) # Asabeneh lives in Finland, Helsinki. He
is 250 years old.

Packing
Sometimes we never know how many arguments need to be passed to a
python function. We can use the packing method to allow our function to
take unlimited number or arbitrary number of arguments.

Packing Lists
def sum_all(*args):
s = 0
for i in args:
s += i
return s
print(sum_all(1, 2, 3)) # 6
print(sum_all(1, 2, 3, 4, 5, 6, 7)) # 28

Packing Dictionaries

def packing_person_info(**kwargs):
# check the type of kwargs and it is a dict type
# print(type(kwargs))
# Printing dictionary items
for key in kwargs:
print(f"{key} = {kwargs[key]}")
return kwargs

print(packing_person_info(name="Asabeneh",
country="Finland", city="Helsinki", age=250))
name = Asabeneh
country = Finland
city = Helsinki
age = 250
{'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'age': 250}

Spreading in Python
Like in JavaScript, spreading is possible in Python. Let us check it in an
example below:

lst_one = [1, 2, 3]
lst_two = [4, 5, 6, 7]
lst = [0, *lst_one, *lst_two]
print(lst) # [0, 1, 2, 3, 4, 5, 6, 7]
country_lst_one = ['Finland', 'Sweden', 'Norway']
country_lst_two = ['Denmark', 'Iceland']
nordic_countries = [*country_lst_one, *country_lst_two]
print(nordic_countries) # ['Finland', 'Sweden', 'Norway', 'Denmark',
'Iceland']

Enumerate
If we are interested in an index of a list, we use enumerate built-in function
to get the index of each item in the list.

for index, item in enumerate([20, 30, 40]):


print(index, item)
for index, i in enumerate(countries):
print('hi')
if i == 'Finland':
print('The country {i} has been found at index {index}')
The country Finland has been found at index 1.

Zip
Sometimes we would like to combine lists when looping through them. See
the example below:

fruits = ['banana', 'orange', 'mango', 'lemon', 'lime']


vegetables = ['Tomato', 'Potato', 'Cabbage','Onion', 'Carrot']
fruits_and_veges = []
for f, v in zip(fruits, vegetables):
fruits_and_veges.append({'fruit':f, 'veg':v})
print(fruits_and_veges)
[{'fruit': 'banana', 'veg': 'Tomato'}, {'fruit': 'orange', 'veg': 'Potato'},
{'fruit': 'mango', 'veg': 'Cabbage'}, {'fruit': 'lemon', 'veg': 'Onion'},
{'fruit': 'lime', 'veg': 'Carrot'}]

🌕 You are determined. You are 17 steps a head to your way to greatness.
Now do some exercises for your brain and mus

Regular Expressions
A regular expression or RegEx is a special text string that helps to find
patterns in data. A RegEx can be used to check if some pattern exists in a
different data type. To use RegEx in python first we should import the RegEx
module which is called re.

The re Module
After importing the module we can use it to detect or find patterns.

import re

Methods in re Module
To find a pattern we use different set of re character sets that allows to
search for a match in a string.

 [Link](): searches only in the beginning of the first line of the string
and returns matched objects if found, else returns None.
 [Link]: Returns a match object if there is one anywhere in the
string, including multiline strings.
 [Link]: Returns a list containing all matches
 [Link]: Takes a string, splits it at the match points, returns a list
 [Link]: Replaces one or many matches within a string

Match

# syntac
[Link](substring, string, re.I)
# substring is a string or a pattern, string is the text we look for a
pattern , re.I is case ignore
import re

txt = 'I love to teach python and javaScript'


# It returns an object with span, and match
match = [Link]('I love to teach', txt, re.I)
print(match) # <[Link] object; span=(0, 15), match='I love to teach'>
# We can get the starting and ending position of the match as tuple using
span
span = [Link]()
print(span) # (0, 15)
# Lets find the start and stop position from the span
start, end = span
print(start, end) # 0, 15
substring = txt[start:end]
print(substring) # I love to teach

As you can see from the example above, the pattern we are looking for (or
the substring we are looking for) is I love to teach. The match function
returns an object only if the text starts with the pattern.

import re

txt = 'I love to teach python and javaScript'


match = [Link]('I like to teach', txt, re.I)
print(match) # None

The string does not string with I like to teach, therefore there was no match
and the match method returned None.

Search

# syntax
[Link](substring, string, re.I)
# substring is a pattern, string is the text we look for a pattern , re.I is
case ignore flag
import re

txt = '''Python is the most beautiful language that a human being has ever
created.
I recommend python for a first programming language'''

# It returns an object with span and match


match = [Link]('first', txt, re.I)
print(match) # <[Link] object; span=(100, 105), match='first'>
# We can get the starting and ending position of the match as tuple using
span
span = [Link]()
print(span) # (100, 105)
# Lets find the start and stop position from the span
start, end = span
print(start, end) # 100 105
substring = txt[start:end]
print(substring) # first

As you can see, search is much better than match because it can look for the
pattern throughout the text. Search returns a match object with a first match
that was found, otherwise it returns None. A much better re function
is findall. This function checks for the pattern through the whole string and
returns all the matches as a list.

Searching for All Matches Using findall

findall() returns all the matches as a list

txt = '''Python is the most beautiful language that a human being has ever
created.
I recommend python for a first programming language'''

# It return a list
matches = [Link]('language', txt, re.I)
print(matches) # ['language', 'language']

As you can see, the word language was found two times in the string. Let us
practice some more. Now we will look for both Python and python words in
the string:

txt = '''Python is the most beautiful language that a human being has ever
created.
I recommend python for a first programming language'''

# It returns list
matches = [Link]('python', txt, re.I)
print(matches) # ['Python', 'python']

Since we are using re.I both lowercase and uppercase letters are included. If
we do not have the re.I flag, then we will have to write our pattern
differently. Let us check it out:

txt = '''Python is the most beautiful language that a human being has ever
created.
I recommend python for a first programming language'''

matches = [Link]('Python|python', txt)


print(matches) # ['Python', 'python']

#
matches = [Link]('[Pp]ython', txt)
print(matches) # ['Python', 'python']

Replacing a Substring

txt = '''Python is the most beautiful language that a human being has ever
created.
I recommend python for a first programming language'''

match_replaced = [Link]('Python|python', 'JavaScript', txt, re.I)


print(match_replaced) # JavaScript is the most beautiful language that a
human being has ever created.
# OR
match_replaced = [Link]('[Pp]ython', 'JavaScript', txt, re.I)
print(match_replaced) # JavaScript is the most beautiful language that a
human being has ever created.

Let us add one more example. The following string is really hard to read
unless we remove the % symbol. Replacing the % with an empty string will
clean the text.

txt = '''%I a%m te%%a%%che%r% a%n%d %% I l%o%ve te%ach%ing.


T%he%re i%s n%o%th%ing as r%ewarding a%s e%duc%at%i%ng a%n%d e%m%p%ow%er%ing
p%e%o%ple.
I fo%und te%a%ching m%ore i%n%t%er%%es%ting t%h%an any other %jobs.
D%o%es thi%s m%ot%iv%a%te %y%o%u to b%e a t%e%a%cher?'''

matches = [Link]('%', '', txt)


print(matches)
I am teacher and I love teaching.
There is nothing as rewarding as educating and empowering people.
I found teaching more interesting than any other jobs. Does this motivate you
to be a teacher?

Splitting Text Using RegEx Split


txt = '''I am teacher and I love teaching.
There is nothing as rewarding as educating and empowering people.
I found teaching more interesting than any other jobs.
Does this motivate you to be a teacher?'''
print([Link]('\n', txt)) # splitting using \n - end of line symbol
['I am teacher and I love teaching.', 'There is nothing as rewarding as
educating and empowering people.', 'I found teaching more interesting than
any other jobs.', 'Does this motivate you to be a teacher?']

Writing RegEx Patterns


To declare a string variable we use a single or double quote. To declare
RegEx variable r''. The following pattern only identifies apple with lowercase,
to make it case insensitive either we should rewrite our pattern or we should
add a flag.

import re

regex_pattern = r'apple'
txt = 'Apple and banana are fruits. An old cliche says an apple a day a
doctor way has been replaced by a banana a day keeps the doctor far far away.
'
matches = [Link](regex_pattern, txt)
print(matches) # ['apple']

# To make case insensitive adding flag '


matches = [Link](regex_pattern, txt, re.I)
print(matches) # ['Apple', 'apple']
# or we can use a set of characters method
regex_pattern = r'[Aa]pple' # this mean the first letter could be Apple or
apple
matches = [Link](regex_pattern, txt)
print(matches) # ['Apple', 'apple']

 []: A set of characters


o [a-c] means, a or b or c
o [a-z] means, any letter from a to z
o [A-Z] means, any character from A to Z
o [0-3] means, 0 or 1 or 2 or 3
o [0-9] means any number from 0 to 9
o [A-Za-z0-9] any single character, that is a to z, A to Z or 0 to 9

 \: uses to escape special characters


o \d means: match where the string contains digits (numbers from
0-9)
o \D means: match where the string does not contain digits
 . : any character except new line character(\n)
 ^: starts with
o r'^substring' eg r'^love', a sentence that starts with a word love
o r'[^abc] means not a, not b, not c.
 $: ends with
o r'substring$' eg r'love$', sentence that ends with a word love
 *: zero or more times
o r'[a]*' means a optional or it can occur many times.
 +: one or more times
o r'[a]+' means at least once (or more)
 ?: zero or one time
o r'[a]?' means zero times or once
 {3}: Exactly 3 characters
 {3,}: At least 3 characters
 {3,8}: 3 to 8 characters
 |: Either or
o r'apple|banana' means either apple or a banana
 (): Capture and group
Let us use examples to clarify the meta characters above

Square Bracket
Let us use square bracket to include lower and upper case

regex_pattern = r'[Aa]pple' # this square bracket mean either A or a


txt = 'Apple and banana are fruits. An old cliche says an apple a day a
doctor way has been replaced by a banana a day keeps the doctor far far
away.'
matches = [Link](regex_pattern, txt)
print(matches) # ['Apple', 'apple']

If we want to look for the banana, we write the pattern as follows:

regex_pattern = r'[Aa]pple|[Bb]anana' # this square bracket means either A or


a
txt = 'Apple and banana are fruits. An old cliche says an apple a day a
doctor way has been replaced by a banana a day keeps the doctor far far
away.'
matches = [Link](regex_pattern, txt)
print(matches) # ['Apple', 'banana', 'apple', 'banana']

Using the square bracket and or operator , we manage to extract Apple,


apple, Banana and banana.

Escape character(\) in RegEx


regex_pattern = r'\d' # d is a special character which means digits
txt = 'This regular expression example was made on December 6, 2019 and
revised on July 8, 2021'
matches = [Link](regex_pattern, txt)
print(matches) # ['6', '2', '0', '1', '9', '8', '2', '0', '2', '1'], this is
not what we want

One or more times(+)


regex_pattern = r'\d+' # d is a special character which means digits, + mean
one or more times
txt = 'This regular expression example was made on December 6, 2019 and
revised on July 8, 2021'
matches = [Link](regex_pattern, txt)
print(matches) # ['6', '2019', '8', '2021'] - now, this is better!

Period(.)
regex_pattern = r'[a].' # this square bracket means a and . means any
character except new line
txt = '''Apple and banana are fruits'''
matches = [Link](regex_pattern, txt)
print(matches) # ['an', 'an', 'an', 'a ', 'ar']

regex_pattern = r'[a].+' # . any character, + any character one or more


times
matches = [Link](regex_pattern, txt)
print(matches) # ['and banana are fruits']

Zero or more times(*)


Zero or many times. The pattern could may not occur or it can occur many
times.

regex_pattern = r'[a].*' # . any character, * any character zero or more


times
txt = '''Apple and banana are fruits'''
matches = [Link](regex_pattern, txt)
print(matches) # ['and banana are fruits']

Zero or one time(?)


Zero or one time. The pattern may not occur or it may occur once.

txt = '''I am not sure if there is a convention how to write the word e-mail.
Some people write it as email others may write it as Email or E-mail.'''
regex_pattern = r'[Ee]-?mail' # ? means here that '-' is optional
matches = [Link](regex_pattern, txt)
print(matches) # ['e-mail', 'email', 'Email', 'E-mail']

Quantifier in RegEx
We can specify the length of the substring we are looking for in a text, using
a curly bracket. Let us imagine, we are interested in a substring with a length
of 4 characters:

txt = 'This regular expression example was made on December 6, 2019 and
revised on July 8, 2021'
regex_pattern = r'\d{4}' # exactly four times
matches = [Link](regex_pattern, txt)
print(matches) # ['2019', '2021']

txt = 'This regular expression example was made on December 6, 2019 and
revised on July 8, 2021'
regex_pattern = r'\d{1, 4}' # 1 to 4
matches = [Link](regex_pattern, txt)
print(matches) # ['6', '2019', '8', '2021']

Cart ^
 Starts with

txt = 'This regular expression example was made on December 6, 2019 and
revised on July 8, 2021'
regex_pattern = r'^This' # ^ means starts with
matches = [Link](regex_pattern, txt)
print(matches) # ['This']

 Negation

txt = 'This regular expression example was made on December 6, 2019 and
revised on July 8, 2021'
regex_pattern = r'[^A-Za-z ]+' # ^ in set character means negation, not A to
Z, not a to z, no space
matches = [Link](regex_pattern, txt)

File Handling
So far we have seen different Python data types. We usually store our data in
different file formats. In addition to handling files, we will also see different
file formats(.txt, .json, .xml, .csv, .tsv, .excel) in this section. First, let us get
familiar with handling files with common file format(.txt).

File handling is an import part of programming which allows us to create,


read, update and delete files. In Python to handle data we use open() built-in
function.

# Syntax
open('filename', mode) # mode(r, a, w, x, t,b) could be to read, write,
update

 "r" - Read - Default value. Opens a file for reading, it returns an error if
the file does not exist
 "a" - Append - Opens a file for appending, creates the file if it does not
exist
 "w" - Write - Opens a file for writing, creates the file if it does not exist
 "x" - Create - Creates the specified file, returns an error if the file exists
 "t" - Text - Default value. Text mode
 "b" - Binary - Binary mode (e.g. images)

Opening Files for Reading


The default mode of open is reading, so we do not have to specify 'r' or 'rt'. I
have created and saved a file named reading_file_example.txt in the files
directory. Let us see how it is done:

f = open('./files/reading_file_example.txt')
print(f) # <_io.TextIOWrapper name='./files/reading_file_example.txt'
mode='r' encoding='UTF-8'>

As you can see in the example above, I printed the opened file and it gave
some information about it. Opened file has different reading
methods: read(), readline, readlines. An opened file has to be closed
with close() method.

 read(): read the whole text as string. If we want to limit the number of
characters we want to read, we can limit it by passing int value to
the read(number) method.

f = open('./files/reading_file_example.txt')
txt = [Link]()
print(type(txt))
print(txt)
[Link]()
# output
<class 'str'>
This is an example to show how to open a file and read.
This is the second line of the text.

Instead of printing all the text, let us print the first 10 characters of the text
file.

f = open('./files/reading_file_example.txt')
txt = [Link](10)
print(type(txt))
print(txt)
[Link]()
# output
<class 'str'>
This is an

 readline(): read only the first line

f = open('./files/reading_file_example.txt')
line = [Link]()
print(type(line))
print(line)
[Link]()
# output
<class 'str'>
This is an example to show how to open a file and read.

 readlines(): read all the text line by line and returns a list of lines

f = open('./files/reading_file_example.txt')
lines = [Link]()
print(type(lines))
print(lines)
[Link]()
# output
<class 'list'>
['This is an example to show how to open a file and read.\n', 'This is the
second line of the text.']

Another way to get all the lines as a list is using splitlines():

f = open('./files/reading_file_example.txt')
lines = [Link]().splitlines()
print(type(lines))
print(lines)
[Link]()
# output
<class 'list'>
['This is an example to show how to open a file and read.', 'This is the
second line of the text.']
After we open a file, we should close it. There is a high tendency of forgetting
to close them. There is a new way of opening files using with - closes the
files by itself. Let us rewrite the the previous example with the with method:

with open('./files/reading_file_example.txt') as f:
lines = [Link]().splitlines()
print(type(lines))
print(lines)
# output
<class 'list'>
['This is an example to show how to open a file and read.', 'This is the
second line of the text.']

Opening Files for Writing and Updating


To write to an existing file, we must add a mode as parameter to
the open() function:

 "a" - append - will append to the end of the file, if the file does not it
creates a new file.
 "w" - write - will overwrite any existing content, if the file does not exist
it creates.

Let us append some text to the file we have been reading:

with open('./files/reading_file_example.txt','a') as f:
[Link]('This text has to be appended at the end')

The method below creates a new file, if the file does not exist:

with open('./files/writing_file_example.txt','w') as f:
[Link]('This text will be written in a newly created file')

Deleting Files
We have seen in previous section, how to make and remove a directory
using os module. Again now, if we want to remove a file we use os module.

import os
[Link]('./files/[Link]')

If the file does not exist, the remove method will raise an error, so it is good
to use a condition like this:

import os
if [Link]('./files/[Link]'):
[Link]('./files/[Link]')
else:
print('The file does not exist')
File Types

File with txt Extension


File with txt extension is a very common form of data and we have covered it
in the previous section. Let us move to the JSON file

File with json Extension


JSON stands for JavaScript Object Notation. Actually, it is a stringified
JavaScript object or Python dictionary.

Example:

# dictionary
person_dct= {
"name":"Asabeneh",
"country":"Finland",
"city":"Helsinki",
"skills":["JavaScrip", "React","Python"]
}
# JSON: A string form a dictionary
person_json = "{'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki',
'skills': ['JavaScrip', 'React', 'Python']}"

# we use three quotes and make it multiple line to make it more readable
person_json = '''{
"name":"Asabeneh",
"country":"Finland",
"city":"Helsinki",
"skills":["JavaScrip", "React","Python"]
}'''

Changing JSON to Dictionary


To change a JSON to a dictionary, first we import the json module and then
we use loads method.

import json
# JSON
person_json = '''{
"name": "Asabeneh",
"country": "Finland",
"city": "Helsinki",
"skills": ["JavaScrip", "React", "Python"]
}'''
# let's change JSON to dictionary
person_dct = [Link](person_json)
print(type(person_dct))
print(person_dct)
print(person_dct['name'])
# output
<class 'dict'>
{'name': 'Asabeneh', 'country': 'Finland', 'city': 'Helsinki', 'skills':
['JavaScrip', 'React', 'Python']}
Asabeneh

Changing Dictionary to JSON


To change a dictionary to a JSON we use dumps method from the json
module.

import json
# python dictionary
person = {
"name": "Asabeneh",
"country": "Finland",
"city": "Helsinki",
"skills": ["JavaScrip", "React", "Python"]
}
# let's convert it to json
person_json = [Link](person, indent=4) # indent could be 2, 4, 8. It
beautifies the json
print(type(person_json))
print(person_json)
# output
# when you print it, it does not have the quote, but actually it is a string
# JSON does not have type, it is a string type.
<class 'str'>
{
"name": "Asabeneh",
"country": "Finland",
"city": "Helsinki",
"skills": [
"JavaScrip",
"React",
"Python"
]
}

Saving as JSON File


We can also save our data as a json file. Let us save it as a json file using the
following steps. For writing a json file, we use the [Link]() method, it can
take dictionary, output file, ensure_ascii and indent.

import json
# python dictionary
person = {
"name": "Asabeneh",
"country": "Finland",
"city": "Helsinki",
"skills": ["JavaScrip", "React", "Python"]
}
with open('./files/json_example.json', 'w', encoding='utf-8') as f:
[Link](person, f, ensure_ascii=False, indent=4)

In the code above, we use encoding and indentation. Indentation makes the
json file easy to read.

File with csv Extension


CSV stands for comma separated values. CSV is a simple file format used to
store tabular data, such as a spreadsheet or database. CSV is a very
common data format in data science.

Example:

"name","country","city","skills"
"Asabeneh","Finland","Helsinki","JavaScript"

Example:

import csv
with open('./files/csv_example.csv') as f:
csv_reader = [Link](f, delimiter=',') # w use, reader method to read
csv
line_count = 0
for row in csv_reader:
if line_count == 0:
print(f'Column names are :{", ".join(row)}')
line_count += 1
else:
print(
f'\t{row[0]} is a teachers. He lives in {row[1]}, {row[2]}.')
line_count += 1
print(f'Number of lines: {line_count}')
# output:
Column names are :name, country, city, skills
Asabeneh is a teacher. He lives in Finland, Helsinki.
Number of lines: 2

File with xlsx Extension


To read excel files we need to install xlrd package. We will cover this after
we cover package installing using pip.

import xlrd
excel_book = xlrd.open_workbook('[Link])
print(excel_book.nsheets)
print(excel_book.sheet_names)
File with xml Extension
XML is another structured data format which looks like HTML. In XML the tags
are not predefined. The first line is an XML declaration. The person tag is the
root of the XML. The person has a gender attribute. Example:XML

<?xml version="1.0"?>
<person gender="female">
<name>Asabeneh</name>
<country>Finland</country>
<city>Helsinki</city>
<skills>
<skill>JavaScrip</skill>
<skill>React</skill>
<skill>Python</skill>
</skills>
</person>

For more information on how to read an XML file check the documentation

import [Link] as ET
tree = [Link]('./files/xml_example.xml')
root = [Link]()
print('Root tag:', [Link])
print('Attribute:', [Link])
for child in root:
print('field: ', [Link])
# output
Root tag: person
Attribute: {'gender': 'male'}
field: name
field: country
field: city
field: skills

🌕 You are making a big progress. Maintain your momentum, keep the good
work. Now do some exercises for your brain and muscles.

💻 Exercises: Day 19

Exercises: Level 1
1. Write a function which count number of lines and number of words in a
text. All the files are in the data the folder: a) Read obama_speech.txt
file and count number of lines and words b) Read
michelle_obama_speech.txt file and count number of lines and words
c) Read donald_speech.txt file and count number of lines and words d)
Read melina_trump_speech.txt file and count number of lines and
words
2. Read the countries_data.json data file in data directory, create a
function that finds the ten most spoken languages

3. # Your output should look like this


4. print(most_spoken_languages(filename='./data/countries_data.json', 10))
5. [(91, 'English'),
6. (45, 'French'),
7. (25, 'Arabic'),
8. (24, 'Spanish'),
9. (9, 'Russian'),
10. (9, 'Portuguese'),
11. (8, 'Dutch'),
12. (7, 'German'),
13. (5, 'Chinese'),
14. (4, 'Swahili'),
15. (4, 'Serbian')]
16.
17. # Your output should look like this
18. print(most_spoken_languages(filename='./data/countries_data.json', 3))
19. [(91, 'English'),
20. (45, 'French'),
(25, 'Arabic')]

21. Read the countries_data.json data file in data directory, create a


function that creates a list of the ten most populated countries

22. # Your output should look like this


23. print(most_populated_countries(filename='./data/countries_data.json',
10))
24.
25. [
26. {'country': 'China', 'population': 1377422166},
27. {'country': 'India', 'population': 1295210000},
28. {'country': 'United States of America', 'population': 323947000},
29. {'country': 'Indonesia', 'population': 258705000},
30. {'country': 'Brazil', 'population': 206135893},
31. {'country': 'Pakistan', 'population': 194125062},
32. {'country': 'Nigeria', 'population': 186988000},
33. {'country': 'Bangladesh', 'population': 161006790},
34. {'country': 'Russian Federation', 'population': 146599183},
35. {'country': 'Japan', 'population': 126960000}
36. ]
37.
38. # Your output should look like this
39.
40. print(most_populated_countries(filename='./data/countries_data.json',
3))
41. [
42. {'country': 'China', 'population': 1377422166},
43. {'country': 'India', 'population': 1295210000},
44. {'country': 'United States of America', 'population': 323947000}
]
Exercises: Level 2
4. Extract all incoming email addresses as a list from the
email_exchange_big.txt file.
5. Find the most common words in the English language. Call the name of
your function find_most_common_words, it will take two parameters - a
string or a file and a positive integer, indicating the number of words.
Your function will return an array of tuples in descending order. Check
the output

# Your output should look like this


print(find_most_common_words('[Link]', 10))
[(10, 'the'),
(8, 'be'),
(6, 'to'),
(6, 'of'),
(5, 'and'),
(4, 'a'),
(4, 'in'),
(3, 'that'),
(2, 'have'),
(2, 'I')]

# Your output should look like this


print(find_most_common_words('[Link]', 5))

[(10, 'the'),
(8, 'be'),
(6, 'to'),
(6, 'of'),
(5, 'and')]

6. Use the function, find_most_frequent_words to find: a) The ten most


frequent words used in Obama's speech b) The ten most frequent
words used in Michelle's speech c) The ten most frequent words used
in Trump's speech d) The ten most frequent words used in Melina's
speech
7. Write a python application that checks similarity between two texts. It
takes a file or a string as a parameter and it will evaluate the similarity
of the two texts. For instance check the similarity between the
transcripts of Michelle's and Melina's speech. You may need a couple
of functions, function to clean the text(clean_text), function to remove
support words(remove_support_words) and finally to check the
similarity(check_text_similarity). List of stop words are in the data
directory
8. Find the 10 most repeated words in the romeo_and_juliet.txt
9. Read the hacker news csv file and find out: a) Count the number of
lines containing python or Python b) Count the number lines containing
JavaScript, javascript or Javascript c) Count the number lines
containing Java and not JavaScript

Python PIP - Python Package Manager

What is PIP ?
PIP stands for Preferred installer program. We use pip to install different
Python packages. Package is a Python module that can contain one or more
modules or other packages. A module or modules that we can install to our
application is a package. In programming, we do not have to write every
utility program, instead we install packages and import them to our
applications.

Installing PIP
If you did not install pip, let us install it now. Go to your terminal or command
prompt and copy and paste this:

asabeneh@Asabeneh:~$ pip install pip

Check if pip is installed by writing

pip --version
asabeneh@Asabeneh:~$ pip --version
pip 21.1.3 from /usr/local/lib/python3.7/site-packages/pip (python 3.9.6)

As you can see, I am using pip version 21.1.3, if you see some number a bit
below or above that, means you have pip installed.

Let us check some of the packages used in the Python community for
different purposes. Just to let you know that there are lots of packages
available for use with different applications.

Installing packages using pip


Let us try to install numpy, called numeric python. It is one of the most
popular packages in machine learning and data science community.

 NumPy is the fundamental package for scientific computing with


Python. It contains among other things:
o a powerful N-dimensional array object
o sophisticated (broadcasting) functions
o tools for integrating C/C++ and Fortran code
o useful linear algebra, Fourier transform, and random number
capabilities

asabeneh@Asabeneh:~$ pip install numpy

Let us start using numpy. Open your python interactive shell, write python
and then import numpy as follows:

asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
>>> [Link]
'1.20.1'
>>> lst = [1, 2, 3,4, 5]
>>> np_arr = [Link](lst)
>>> np_arr
array([1, 2, 3, 4, 5])
>>> len(np_arr)
5
>>> np_arr * 2
array([ 2, 4, 6, 8, 10])
>>> np_arr + 2
array([3, 4, 5, 6, 7])
>>>

Pandas is an open source, BSD-licensed library providing high-performance,


easy-to-use data structures and data analysis tools for the Python
programming language. Let us install the big brother of numpy, pandas:

asabeneh@Asabeneh:~$ pip install pandas


asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pandas

This section is not about numpy nor pandas, here we are trying to learn how
to install packages and how to import them. If it is needed, we will talk about
different packages in other sections.

Let us import a web browser module, which can help us to open any website.
We do not need to install this module, it is already installed by default with
Python 3. For instance if you like to open any number of websites at any time
or if you like to schedule something, this webbrowser module can be used.

import webbrowser # web browser module to open websites

# list of urls: python


url_lists = [
'[Link]
'[Link]
'[Link]
'[Link]
]

# opens the above list of websites in a different tab


for url in url_lists:
webbrowser.open_new_tab(url)

Uninstalling Packages
If you do not like to keep the installed packages, you can remove them using
the following command.

pip uninstall packagename

List of Packages
To see the installed packages on our machine. We can use pip followed by
list.

pip list

Show Package
To show information about a package

pip show packagename


asabeneh@Asabeneh:~$ pip show pandas
Name: pandas
Version: 1.2.3
Summary: Powerful data structures for data analysis, time series, and
statistics
Home-page: [Link]
Author: None
Author-email: None
License: BSD
Location: /usr/local/lib/python3.7/site-packages
Requires: python-dateutil, pytz, numpy
Required-by:

If we want even more details, just add --verbose

asabeneh@Asabeneh:~$ pip show --verbose pandas


Name: pandas
Version: 1.2.3
Summary: Powerful data structures for data analysis, time series, and
statistics
Home-page: [Link]
Author: None
Author-email: None
License: BSD
Location: /usr/local/lib/python3.7/site-packages
Requires: numpy, pytz, python-dateutil
Required-by:
Metadata-Version: 2.1
Installer: pip
Classifiers:
Development Status :: 5 - Production/Stable
Environment :: Console
Operating System :: OS Independent
Intended Audience :: Science/Research
Programming Language :: Python
Programming Language :: Python :: 3
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Cython
Topic :: Scientific/Engineering
Entry-points:
[pandas_plotting_backends]
matplotlib = pandas:plotting._matplotlib

PIP Freeze
Generate installed Python packages with their version and the output is
suitable to use it in a requirements file. A [Link] file is a file that
should contain all the installed Python packages in a Python project.

asabeneh@Asabeneh:~$ pip freeze


docutils==0.11
Jinja2==2.7.2
MarkupSafe==0.19
Pygments==1.6
Sphinx==1.2.2

The pip freeze gave us the packages used, installed and their version. We
use it with [Link] file for deployment.

Reading from URL


By now you are familiar with how to read or write on a file located on you
local machine. Sometimes, we would like to read from a website using url or
from an API. API stands for Application Program Interface. It is a means to
exchange structured data between servers primarily as json data. To open a
network connection, we need a package called requests - it allows to open a
network connection and to implement CRUD(create, read, update and
delete) operations. In this section, we will cover only reading ore getting part
of a CRUD.
Let us install requests:

asabeneh@Asabeneh:~$ pip install requests

We will see get, status_code, headers, text and json methods


in requests module:

 get(): to open a network and fetch data from url - it returns a response
object
 status_code: After we fetched data, we can check the status of the
operation (success, error, etc)
 headers: To check the header types
 text: to extract the text from the fetched response object
 json: to extract json data Let's read a txt file from this
website, [Link]

import requests # importing the request module

url = '[Link] # text from a website

response = [Link](url) # opening a network and fetching a data


print(response)
print(response.status_code) # status code, success:200
print([Link]) # headers information
print([Link]) # gives all the text from the page
<Response [200]>
200
{'date': 'Sun, 08 Dec 2019 18:00:31 GMT', 'last-modified': 'Fri, 07 Nov 2003
05:51:11 GMT', 'etag': '"17e9-3cb82080711c0;50c0b26855880-gzip"', 'accept-
ranges': 'bytes', 'cache-control': 'max-age=31536000', 'expires': 'Mon, 07
Dec 2020 18:00:31 GMT', 'vary': 'Accept-Encoding', 'content-encoding':
'gzip', 'access-control-allow-origin': '*', 'content-length': '1616',
'content-type': 'text/plain', 'strict-transport-security': 'max-age=15552000;
includeSubdomains; preload', 'content-security-policy': 'upgrade-insecure-
requests'}

 Let us read from an API. API stands for Application Program Interface. It
is a means to exchange structure data between servers primarily a
json data. An example of an API:[Link] Let
us read this API using requests module.

import requests
url = '[Link] # countries api
response = [Link](url) # opening a network and fetching a data
print(response) # response object
print(response.status_code) # status code, success:200
countries = [Link]()
print(countries[:1]) # we sliced only the first country, remove the slicing
to see all countries
<Response [200]>
200
[{'alpha2Code': 'AF',
'alpha3Code': 'AFG',
'altSpellings': ['AF', 'Afġānistān'],
'area': 652230.0,
'borders': ['IRN', 'PAK', 'TKM', 'UZB', 'TJK', 'CHN'],
'callingCodes': ['93'],
'capital': 'Kabul',
'cioc': 'AFG',
'currencies': [{'code': 'AFN', 'name': 'Afghan afghani', 'symbol': '؋'}],
'demonym': 'Afghan',
'flag': '[Link]
'gini': 27.8,
'languages': [{'iso639_1': 'ps',
'iso639_2': 'pus',
'name': 'Pashto',
'nativeName': '‫}'پښتو‬,
{'iso639_1': 'uz',
'iso639_2': 'uzb',
'name': 'Uzbek',
'nativeName': 'Oʻzbek'},
{'iso639_1': 'tk',
'iso639_2': 'tuk',
'name': 'Turkmen',
'nativeName': 'Türkmen'}],
'latlng': [33.0, 65.0],
'name': 'Afghanistan',
'nativeName': '‫'افغانستان‬,
'numericCode': '004',
'population': 27657145,
'region': 'Asia',
'regionalBlocs': [{'acronym': 'SAARC',
'name': 'South Asian Association for Regional
Cooperation',
'otherAcronyms': [],
'otherNames': []}],
'subregion': 'Southern Asia',
'timezones': ['UTC+04:30'],
'topLevelDomain': ['.af'],
'translations': {'br': 'Afeganistão',
'de': 'Afghanistan',
'es': 'Afganistán',
'fa': '‫'افغانستان‬,
'fr': 'Afghanistan',
'hr': 'Afganistan',
'it': 'Afghanistan',
'ja': 'アフガニスタン',
'nl': 'Afghanistan',
'pt': 'Afeganistão'}}]

We use json() method from response object, if the we are fetching JSON data.
For txt, html, xml and other file formats we can use text.
Creating a Package
We organize a large number of files in different folders and sub-folders based
on some criteria, so that we can find and manage them easily. As you know,
a module can contain multiple objects, such as classes, functions, etc. A
package can contain one or more relevant modules. A package is actually a
folder containing one or more module files. Let us create a package named
mypackage, using the following steps:

Create a new folder named mypacakge inside 30DaysOfPython folder Create


an empty [Link] file in the mypackage folder. Create modules [Link]
and [Link] with following code:

# mypackage/[Link]
# [Link]
def add_numbers(*args):
total = 0
for num in args:
total += num
return total

def subtract(a, b):


return (a - b)

def multiple(a, b):


return a * b

def division(a, b):


return a / b

def remainder(a, b):


return a % b

def power(a, b):


return a ** b
# mypackage/[Link]
# [Link]
def greet_person(firstname, lastname):
return f'{firstname} {lastname}, welcome to 30DaysOfPython Challenge!'

The folder structure of your package should look like this:

─ mypackage
├── __init__.py
├── [Link]
└── [Link]
Now let's open the python interactive shell and try the package we have
created:

asabeneh@Asabeneh:~/Desktop/30DaysOfPython$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from mypackage import arithmetics
>>> arithmetics.add_numbers(1, 2, 3, 5)
11
>>> [Link](5, 3)
2
>>> [Link](5, 3)
15
>>> [Link](5, 3)
1.6666666666666667
>>> [Link](5, 3)
2
>>> [Link](5, 3)
125
>>> from mypackage import greet
>>> greet.greet_person('Asabeneh', 'Yetayeh')
'Asabeneh Yetayeh, welcome to 30DaysOfPython Challenge!'
>>>

As you can see our package works perfectly. The package folder contains a
special file called [Link] - it stores the package's content. If we put [Link] in
the package folder, python start recognizes it as a package. The [Link]
exposes specified resources from its modules to be imported to other python
files. An empty [Link] file makes all functions available when a package is
imported. The [Link] is essential for the folder to be recognized by Python
as a package.

Further Information About Packages


 Database

o SQLAlchemy or SQLObject - Object oriented access to several


different database systems
 pip install SQLAlchemy
 Web Development

o Django - High-level web framework.


 pip install django
o Flask - micro framework for Python based on Werkzeug, Jinja 2.
(It's BSD licensed)
 pip install flask
 HTML Parser
o Beautiful Soup - HTML/XML parser designed for quick turnaround
projects like screen-scraping, will accept bad markup.
 pip install beautifulsoup4
o PyQuery - implements jQuery in Python; faster than
BeautifulSoup, apparently.

 XML Processing

o ElementTree - The Element type is a simple but flexible container


object, designed to store hierarchical data structures, such as
simplified XML infosets, in memory. --Note: Python 2.5 and up
has ElementTree in the Standard Library
 GUI

o PyQt - Bindings for the cross-platform Qt framework.


o TkInter - The traditional Python user interface toolkit.

 Data Analysis, Data Science and Machine learning

o Numpy: Numpy(numeric python) is known as one of the most


popular machine learning library in Python.
o Pandas: is a data analysis, data science and a machine learning
library in Python that provides data structures of high-level and a
wide variety of tools for analysis.
o SciPy: SciPy is a machine learning library for application
developers and engineers. SciPy library contains modules for
optimization, linear algebra, integration, image processing, and
statistics.
o Scikit-Learn: It is NumPy and SciPy. It is considered as one of the
best libraries for working with complex data.
o TensorFlow: is a machine learning library built by Google.
o Keras: is considered as one of the coolest machine learning
libraries in Python. It provides an easier mechanism to express
neural networks. Keras also provides some of the best utilities for
compiling models, processing data-sets, visualization of graphs,
and much more.

 Network:

o requests: is a package which we can use to send requests to a


server(GET, POST, DELETE, PUT)
 pip install requests

[Link]

def add_numbers(*args):
total = 0

for num in args:

total += num

return total

def subtract(a, b):

return (a - b)

def multiple(a, b):

return a * b

def division(a, b):

return a / b

def remainder(a, b):

return a % b

def power(a, b):

return a ** b

[Link]

def greet_person(firstname, lastname):

return f'{firstname} {lastname}, welcome to 30DaysOfPython Challenge!'

Classes and Objects


Python is an object oriented programming language. Everything in Python is
an object, with its properties and methods. A number, string, list, dictionary,
tuple, set etc. used in a program is an object of a corresponding built-in
class. We create class to create an object. A class is like an object
constructor, or a "blueprint" for creating objects. We instantiate a class to
create an object. The class defines attributes and the behavior of the object,
while the object, on the other hand, represents the class.

We have been working with classes and objects right from the beginning of
this challenge unknowingly. Every element in a Python program is an object
of a class. Let us check if everything in python is a class:
asabeneh@Asabeneh:~$ python
Python 3.9.6 (default, Jun 28 2021, 15:26:21)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> num = 10
>>> type(num)
<class 'int'>
>>> string = 'string'
>>> type(string)
<class 'str'>
>>> boolean = True
>>> type(boolean)
<class 'bool'>
>>> lst = []
>>> type(lst)
<class 'list'>
>>> tpl = ()
>>> type(tpl)
<class 'tuple'>
>>> set1 = set()
>>> type(set1)
<class 'set'>
>>> dct = {}
>>> type(dct)
<class 'dict'>

Creating a Class
To create a class we need the key word class followed by the name and
colon. Class name should be CamelCase.

# syntax
class ClassName:
code goes here

Example:

class Person:
pass
print(Person)
<__main__.Person object at 0x10804e510>

Creating an Object
We can create an object by calling the class.

p = Person()
print(p)

Class Constructor
In the examples above, we have created an object from the Person class.
However, a class without a constructor is not really useful in real
applications. Let us use constructor function to make our class more useful.
Like the constructor function in Java or JavaScript, Python has also a built-
in init() constructor function. The init constructor function has self
parameter which is a reference to the current instance of the
class Examples:

class Person:
def __init__ (self, name):
# self allows to attach parameter to the class
[Link] =name

p = Person('Asabeneh')
print([Link])
print(p)
# output
Asabeneh
<__main__.Person object at 0x2abf46907e80>

Let us add more parameters to the constructor function.

class Person:
def __init__(self, firstname, lastname, age, country, city):
[Link] = firstname
[Link] = lastname
[Link] = age
[Link] = country
[Link] = city

p = Person('Asabeneh', 'Yetayeh', 250, 'Finland', 'Helsinki')


print([Link])
print([Link])
print([Link])
print([Link])
print([Link])
# output
Asabeneh
Yetayeh
250
Finland
Helsinki

Object Methods
Objects can have methods. The methods are functions which belong to the
object.

Example:
class Person:
def __init__(self, firstname, lastname, age, country, city):
[Link] = firstname
[Link] = lastname
[Link] = age
[Link] = country
[Link] = city
def person_info(self):
return f'{[Link]} {[Link]} is {[Link]} years old. He
lives in {[Link]}, {[Link]}'

p = Person('Asabeneh', 'Yetayeh', 250, 'Finland', 'Helsinki')


print(p.person_info())
# output
Asabeneh Yetayeh is 250 years old. He lives in Helsinki, Finland

Object Default Methods


Sometimes, you may want to have a default values for your object methods.
If we give default values for the parameters in the constructor, we can avoid
errors when we call or instantiate our class without parameters. Let's see
how it looks:

Example:

class Person:
def __init__(self, firstname='Asabeneh', lastname='Yetayeh', age=250,
country='Finland', city='Helsinki'):
[Link] = firstname
[Link] = lastname
[Link] = age
[Link] = country
[Link] = city

def person_info(self):
return f'{[Link]} {[Link]} is {[Link]} years old. He
lives in {[Link]}, {[Link]}.'

p1 = Person()
print(p1.person_info())
p2 = Person('John', 'Doe', 30, 'Nomanland', 'Noman city')
print(p2.person_info())
# output
Asabeneh Yetayeh is 250 years old. He lives in Helsinki, Finland.
John Doe is 30 years old. He lives in Noman city, Nomanland.

Method to Modify Class Default Values


In the example below, the person class, all the constructor parameters have
default values. In addition to that, we have skills parameter, which we can
access using a method. Let us create add_skill method to add skills to the
skills list.

class Person:
def __init__(self, firstname='Asabeneh', lastname='Yetayeh', age=250,
country='Finland', city='Helsinki'):
[Link] = firstname
[Link] = lastname
[Link] = age
[Link] = country
[Link] = city
[Link] = []

def person_info(self):
return f'{[Link]} {[Link]} is {[Link]} years old. He
lives in {[Link]}, {[Link]}.'
def add_skill(self, skill):
[Link](skill)

p1 = Person()
print(p1.person_info())
p1.add_skill('HTML')
p1.add_skill('CSS')
p1.add_skill('JavaScript')
p2 = Person('John', 'Doe', 30, 'Nomanland', 'Noman city')
print(p2.person_info())
print([Link])
print([Link])
# output
Asabeneh Yetayeh is 250 years old. He lives in Helsinki, Finland.
John Doe is 30 years old. He lives in Noman city, Nomanland.
['HTML', 'CSS', 'JavaScript']
[]

Inheritance
Using inheritance we can reuse parent class code. Inheritance allows us to
define a class that inherits all the methods and properties from parent class.
The parent class or super or base class is the class which gives all the
methods and properties. Child class is the class that inherits from another or
parent class. Let us create a student class by inheriting from person class.

class Student(Person):
pass

s1 = Student('Eyob', 'Yetayeh', 30, 'Finland', 'Helsinki')


s2 = Student('Lidiya', 'Teklemariam', 28, 'Finland', 'Espoo')
print(s1.person_info())
s1.add_skill('JavaScript')
s1.add_skill('React')
s1.add_skill('Python')
print([Link])

print(s2.person_info())
s2.add_skill('Organizing')
s2.add_skill('Marketing')
s2.add_skill('Digital Marketing')
print([Link])
output
Eyob Yetayeh is 30 years old. He lives in Helsinki, Finland.
['JavaScript', 'React', 'Python']
Lidiya Teklemariam is 28 years old. He lives in Espoo, Finland.
['Organizing', 'Marketing', 'Digital Marketing']

We did not call the init() constructor in the child class. If we didn't call it then
we can still access all the properties from the parent. But if we do call the
constructor we can access the parent properties by calling super.
We can add a new method to the child or we can override the parent class
methods by creating the same method name in the child class. When we add
the init() function, the child class will no longer inherit the parent's init()
function.

Overriding parent method


class Student(Person):
def __init__ (self, firstname='Asabeneh', lastname='Yetayeh',age=250,
country='Finland', city='Helsinki', gender='male'):
[Link] = gender
super().__init__(firstname, lastname,age, country, city)
def person_info(self):
gender = 'He' if [Link] =='male' else 'She'
return f'{[Link]} {[Link]} is {[Link]} years old.
{gender} lives in {[Link]}, {[Link]}.'

s1 = Student('Eyob', 'Yetayeh', 30, 'Finland', 'Helsinki','male')


s2 = Student('Lidiya', 'Teklemariam', 28, 'Finland', 'Espoo', 'female')
print(s1.person_info())
s1.add_skill('JavaScript')
s1.add_skill('React')
s1.add_skill('Python')
print([Link])

print(s2.person_info())
s2.add_skill('Organizing')
s2.add_skill('Marketing')
s2.add_skill('Digital Marketing')
print([Link])
Eyob Yetayeh is 30 years old. He lives in Helsinki, Finland.
['JavaScript', 'React', 'Python']
Lidiya Teklemariam is 28 years old. She lives in Espoo, Finland.
['Organizing', 'Marketing', 'Digital Marketing']
We can use super() built-in function or the parent name Person to
automatically inherit the methods and properties from its parent. In the
example above we override the parent method. The child method has a
different feature, it can identify, if the gender is male or female and assign
the proper pronoun(He/She).

🌕 Now, you are fully charged with a super power of programming. Now do
some exercises for your brain and muscles.

💻 Exercises: Day 21

Exercises: Level 1
1. Python has the module called statistics and we can use this module to
do all the statistical calculations. However, to learn how to make
function and reuse function let us try to develop a program, which
calculates the measure of central tendency of a sample (mean,
median, mode) and measure of variability (range, variance, standard
deviation). In addition to those measures, find the min, max, count,
percentile, and frequency distribution of the sample. You can create a
class called Statistics and create all the functions that do statistical
calculations as methods for the Statistics class. Check the output
below.

ages = [31, 26, 34, 37, 27, 26, 32, 32, 26, 27, 27, 24, 32, 33, 27, 25, 26,
38, 37, 31, 34, 24, 33, 29, 26]

print('Count:', [Link]()) # 25
print('Sum: ', [Link]()) # 744
print('Min: ', [Link]()) # 24
print('Max: ', [Link]()) # 38
print('Range: ', [Link]() # 14
print('Mean: ', [Link]()) # 30
print('Median: ', [Link]()) # 29
print('Mode: ', [Link]()) # {'mode': 26, 'count': 5}
print('Standard Deviation: ', [Link]()) # 4.2
print('Variance: ', [Link]()) # 17.5
print('Frequency Distribution: ', data.freq_dist()) # [(20.0, 26), (16.0,
27), (12.0, 32), (8.0, 37), (8.0, 34), (8.0, 33), (8.0, 31), (8.0, 24), (4.0,
38), (4.0, 29), (4.0, 25)]
# you output should look like this
print([Link]())
Count: 25
Sum: 744
Min: 24
Max: 38
Range: 14
Mean: 30
Median: 29
Mode: (26, 5)
Variance: 17.5
Standard Deviation: 4.2
Frequency Distribution: [(20.0, 26), (16.0, 27), (12.0, 32), (8.0, 37), (8.0,
34), (8.0, 33), (8.0, 31), (8.0, 24), (4.0, 38), (4.0, 29), (4.0, 25)]

Exercises: Level 2
1. Create a class called PersonAccount. It has firstname, lastname,
incomes, expenses properties and it has total_income, total_expense,
account_info, add_income, add_expense and account_balance
methods. Incomes is a set of incomes and its description. The same
goes for expenses.

Python Web Scraping

What is Web Scrapping


The internet is full of huge amount of data which can be used for different
purposes. To collect this data we need to know how to scrape data from a
website.

Web scraping is the process of extracting and collecting data from websites
and storing it on a local machine or in a database.

In this section, we will use beautifulsoup and requests package to scrape


data. The package version we are using is beautifulsoup 4.

To start scraping websites you need requests, beautifoulSoup4 and


a website.

pip install requests


pip install beautifulsoup4

To scrape data from websites, basic understanding of HTML tags and CSS
selectors is needed. We target content from a website using HTML tags,
classes or/and ids. Let us import the requests and BeautifulSoup module

import requests
from bs4 import BeautifulSoup

Let us declare url variable for the website which we are going to scrape.

import requests
from bs4 import BeautifulSoup
url = '[Link]
# Lets use the requests get method to fetch the data from url

response = [Link](url)
# lets check the status
status = response.status_code
print(status) # 200 means the fetching was successful
200

Using beautifulSoup to parse content from the page

import requests
from bs4 import BeautifulSoup
url = '[Link]

response = [Link](url)
content = [Link] # we get all the content from the website
soup = BeautifulSoup(content, '[Link]') # beautiful soup will give a
chance to parse
print([Link]) # <title>UCI Machine Learning Repository: Data Sets</title>
print([Link].get_text()) # UCI Machine Learning Repository: Data Sets
print([Link]) # gives the whole page on the website
print(response.status_code)

tables = soup.find_all('table', {'cellpadding':'3'})


# We are targeting the table with cellpadding attribute with the value of 3
# We can select using id, class or HTML tag , for more information check the
beautifulsoup doc
table = tables[0] # the result is a list, we are taking out data from it
for td in [Link]('tr').find_all('td'):
print([Link])

If you run this code, you can see that the extraction is half done. You can
continue doing it because it is part of exercise 1. For reference check
the beautifulsoup documentation

🌕 You are so special, you are progressing everyday. You are left with only
eight days to your way to greatness. Now do some exercises for your brain
and muscles.

Setting up Virtual Environments


To start with project, it would be better to have a virtual environment. Virtual
environment can help us to create an isolated or separate environment. This
will help us to avoid conflicts in dependencies across projects. If you write
pip freeze on your terminal you will see all the installed packages on your
computer. If we use virtualenv, we will access only packages which are
specific for that project. Open your terminal and install virtualenv

asabeneh@Asabeneh:~$ pip install virtualenv

Inside the 30DaysOfPython folder create a flask_project folder.


After installing the virtualenv package go to your project folder and create a
virtual env by writing:

For Mac/Linux:

asabeneh@Asabeneh:~/Desktop/30DaysOfPython/flask_project\$ virtualenv venv

For Windows:

C:\Users\User\Documents\30DaysOfPython\flask_project>python -m venv venv

I prefer to call the new project venv, but feel free to name it differently. Let
us check if the the venv was created by using ls (or dir for windows
command prompt) command.

asabeneh@Asabeneh:~/Desktop/30DaysOfPython/flask_project$ ls
venv/

Let us activate the virtual environment by writing the following command at


our project folder.

For Mac/Linux:

asabeneh@Asabeneh:~/Desktop/30DaysOfPython/flask_project$ source
venv/bin/activate

Activation of the virtual environment in Windows may very on Windows


Power shell and git bash.

For Windows Power Shell:

C:\Users\User\Documents\30DaysOfPython\flask_project> venv\Scripts\activate

For Windows Git bash:

C:\Users\User\Documents\30DaysOfPython\flask_project> venv\Scripts\. activate

After you write the activation command, your project directory will start with
venv. See the example below.

(venv) asabeneh@Asabeneh:~/Desktop/30DaysOfPython/flask_project$

Now, lets check the available packages in this project by writing pip freeze.
You will not see any packages.

We are going to do a small flask project so let us install flask package to this
project.

(venv) asabeneh@Asabeneh:~/Desktop/30DaysOfPython/flask_project$ pip install


Flask

Now, let us write pip freeze to see a list of installed packages in the project:
(venv) asabeneh@Asabeneh:~/Desktop/30DaysOfPython/flask_project$ pip freeze
Click==7.0
Flask==1.1.1
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
Werkzeug==0.16.0

When you finish you should dactivate active project using deactivate.

(venv) asabeneh@Asabeneh:~/Desktop/30DaysOfPython$ deactivate

The necessary modules to work with flask are installed. Now, your project
directory is ready for a flask project. You should include the venv to
your .gitignore file not to push it to github.

💻 Exercises: Day 23
1. Create a project directory with a virtual environment based on the
example given above.

Python for Statistical Analysis

Statistics
Statistics is the discipline that studies
the collection, organization, displaying, analysing, interpretation and present
ation of data. Statistics is a branch of Mathematics that is recommended to
be a prerequisite for data science and machine learning. Statistics is a very
broad field but we will focus in this section only on the most relevant part.
After completing this challenge, you may go onto the web development, data
analysis, machine learning and data science path. Whatever path you may
follow, at some point in your career you will get data which you may work on.
Having some statistical knowledge will help you to make decisions based on
data, data tells as they say.

Data
What is data? Data is any set of characters that is gathered and translated
for some purpose, usually analysis. It can be any character, including text
and numbers, pictures, sound, or video. If data is not put in a context, it
doesn't make any sense to a human or computer. To make sense from data
we need to work on the data using different tools.
The work flow of data analysis, data science or machine learning starts from
data. Data can be provided from some data source or it can be created.
There are structured and unstructured data.

Data can be found in small or big format. Most of the data types we will get
have been covered in the file handling section.

Statistics Module
The Python statistics module provides functions for calculating mathematical
statistics of numerical data. The module is not intended to be a competitor to
third-party libraries such as NumPy, SciPy, or proprietary full-featured
statistics packages aimed at professional statisticians such as Minitab, SAS
and Matlab. It is aimed at the level of graphing and scientific calculators.

NumPy
In the first section we defined Python as a great general-purpose
programming language on its own, but with the help of other popular
libraries as(numpy, scipy, matplotlib, pandas etc) it becomes a powerful
environment for scientific computing.

NumPy is the core library for scientific computing in Python. It provides a


high-performance multidimensional array object, and tools for working with
arrays.

So far, we have been using vscode but from now on I would recommend
using Jupyter Notebook. To access jupyter notebook let's install anaconda. If
you are using anaconda most of the common packages are included and you
don't have install packages if you installed anaconda.

asabeneh@Asabeneh:~/Desktop/30DaysOfPython$ pip install numpy

Importing NumPy
Jupyter notebook is available if your are in favor of jupyter notebook

# How to import numpy


import numpy as np
# How to check the version of the numpy package
print('numpy:', np.__version__)
# Checking the available methods
print(dir(np))
Creating numpy array using

Creating int numpy arrays


# Creating python List
python_list = [1,2,3,4,5]

# Checking data types


print('Type:', type (python_list)) # <class 'list'>
#
print(python_list) # [1, 2, 3, 4, 5]

two_dimensional_list = [[0,1,2], [3,4,5], [6,7,8]]

print(two_dimensional_list) # [[0, 1, 2], [3, 4, 5], [6, 7, 8]]

# Creating Numpy(Numerical Python) array from python list

numpy_array_from_list = [Link](python_list)
print(type (numpy_array_from_list)) # <class '[Link]'>
print(numpy_array_from_list) # array([1, 2, 3, 4, 5])

Creating float numpy arrays


Creating a float numpy array from list with a float data type parameter

# Python list
python_list = [1,2,3,4,5]

numy_array_from_list2 = [Link](python_list, dtype=float)


print(numy_array_from_list2) # array([1., 2., 3., 4., 5.])

Creating boolean numpy arrays


Creating a boolean a numpy array from list

numpy_bool_array = [Link]([0, 1, -1, 0, 0], dtype=bool)


print(numpy_bool_array) # array([False, True, True, False, False])

Creating multidimensional array using numpy


A numpy array may have one or multiple rows and columns

two_dimensional_list = [[0,1,2], [3,4,5], [6,7,8]]


numpy_two_dimensional_list = [Link](two_dimensional_list)
print(type (numpy_two_dimensional_list))
print(numpy_two_dimensional_list)
<class '[Link]'>
[[0 1 2]
[3 4 5]
[6 7 8]]

Converting numpy array to list


# We can always convert an array back to a python list using tolist().
np_to_list = numpy_array_from_list.tolist()
print(type (np_to_list))
print('one dimensional array:', np_to_list)
print('two dimensional array: ', numpy_two_dimensional_list.tolist())
<class 'list'>
one dimensional array: [1, 2, 3, 4, 5]
two dimensional array: [[0, 1, 2], [3, 4, 5], [6, 7, 8]]

Creating numpy array from tuple


# Numpy array from tuple
# Creating tuple in Python
python_tuple = (1,2,3,4,5)
print(type (python_tuple)) # <class 'tuple'>
print('python_tuple: ', python_tuple) # python_tuple: (1, 2, 3, 4, 5)

numpy_array_from_tuple = [Link](python_tuple)
print(type (numpy_array_from_tuple)) # <class '[Link]'>
print('numpy_array_from_tuple: ', numpy_array_from_tuple) #
numpy_array_from_tuple: [1 2 3 4 5]

Shape of numpy array


The shape method provide the shape of the array as a tuple. The first is the
row and the second is the column. If the array is just one dimensional it
returns the size of the array.

nums = [Link]([1, 2, 3, 4, 5])


print(nums)
print('shape of nums: ', [Link])
print(numpy_two_dimensional_list)
print('shape of numpy_two_dimensional_list: ',
numpy_two_dimensional_list.shape)
three_by_four_array = [Link]([[0, 1, 2, 3],
[4,5,6,7],
[8,9,10, 11]])
print(three_by_four_array.shape)
[1 2 3 4 5]
shape of nums: (5,)
[[0 1 2]
[3 4 5]
[6 7 8]]
shape of numpy_two_dimensional_list: (3, 3)
(3, 4)
Data type of numpy array
Type of data types: str, int, float, complex, bool, list, None

int_lists = [-3, -2, -1, 0, 1, 2,3]


int_array = [Link](int_lists)
float_array = [Link](int_lists, dtype=float)

print(int_array)
print(int_array.dtype)
print(float_array)
print(float_array.dtype)
[-3 -2 -1 0 1 2 3]
int64
[-3. -2. -1. 0. 1. 2. 3.]
float64

Size of a numpy array


In numpy to know the number of items in a numpy array list we use size

numpy_array_from_list = [Link]([1, 2, 3, 4, 5])


two_dimensional_list = [Link]([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])

print('The size:', numpy_array_from_list.size) # 5


print('The size:', two_dimensional_list.size) # 3
The size: 5
The size: 9

Mathematical Operation using numpy


NumPy array is not like exactly like python list. To do mathematical
operation in Python list we have to loop through the items but numpy can
allow to do any mathematical operation without looping. Mathematical
Operation:

 Addition (+)
 Subtraction (-)
 Multiplication (*)
 Division (/)
 Modules (%)
 Floor Division(//)
 Exponential(**)
Addition
# Mathematical Operation
# Addition
numpy_array_from_list = [Link]([1, 2, 3, 4, 5])
print('original array: ', numpy_array_from_list)
ten_plus_original = numpy_array_from_list + 10
print(ten_plus_original)
original array: [1 2 3 4 5]
[11 12 13 14 15]

Subtraction
# Subtraction
numpy_array_from_list = [Link]([1, 2, 3, 4, 5])
print('original array: ', numpy_array_from_list)
ten_minus_original = numpy_array_from_list - 10
print(ten_minus_original)
original array: [1 2 3 4 5]
[-9 -8 -7 -6 -5]

Multiplication
# Multiplication
numpy_array_from_list = [Link]([1, 2, 3, 4, 5])
print('original array: ', numpy_array_from_list)
ten_times_original = numpy_array_from_list * 10
print(ten_times_original)
original array: [1 2 3 4 5]
[10 20 30 40 50]

Division
# Division
numpy_array_from_list = [Link]([1, 2, 3, 4, 5])
print('original array: ', numpy_array_from_list)
ten_times_original = numpy_array_from_list / 10
print(ten_times_original)
original array: [1 2 3 4 5]
[0.1 0.2 0.3 0.4 0.5]

Modulus
# Modulus; Finding the remainder
numpy_array_from_list = [Link]([1, 2, 3, 4, 5])
print('original array: ', numpy_array_from_list)
ten_times_original = numpy_array_from_list % 3
print(ten_times_original)
original array: [1 2 3 4 5]
[1 2 0 1 2]

Floor Division
# Floor division: the division result without the remainder
numpy_array_from_list = [Link]([1, 2, 3, 4, 5])
print('original array: ', numpy_array_from_list)
ten_times_original = numpy_array_from_list // 10
print(ten_times_original)

Exponential
# Exponential is finding some number the power of another:
numpy_array_from_list = [Link]([1, 2, 3, 4, 5])
print('original array: ', numpy_array_from_list)
ten_times_original = numpy_array_from_list ** 2
print(ten_times_original)
original array: [1 2 3 4 5]
[ 1 4 9 16 25]

Checking data types


#Int, Float numbers
numpy_int_arr = [Link]([1,2,3,4])
numpy_float_arr = [Link]([1.1, 2.0,3.2])
numpy_bool_arr = [Link]([-3, -2, 0, 1,2,3], dtype='bool')

print(numpy_int_arr.dtype)
print(numpy_float_arr.dtype)
print(numpy_bool_arr.dtype)
int64
float64
bool

Converting types
We can convert the data types of numpy array

1. Int to Float

numpy_int_arr = [Link]([1,2,3,4], dtype = 'float')


numpy_int_arr
array([1., 2., 3., 4.])

2. Float to Int
numpy_int_arr = [Link]([1., 2., 3., 4.], dtype = 'int')
numpy_int_arr
array([1, 2, 3, 4])

3. Int ot boolean

[Link]([-3, -2, 0, 1,2,3], dtype='bool')


array([ True, True, False, True, True, True])

4. Int to str

numpy_float_list.astype('int').astype('str')
array(['1', '2', '3'], dtype='<U21')

Multi-dimensional Arrays
# 2 Dimension Array
two_dimension_array = [Link]([(1,2,3),(4,5,6), (7,8,9)])
print(type (two_dimension_array))
print(two_dimension_array)
print('Shape: ', two_dimension_array.shape)
print('Size:', two_dimension_array.size)
print('Data type:', two_dimension_array.dtype)
<class '[Link]'>
[[1 2 3]
[4 5 6]
[7 8 9]]
Shape: (3, 3)
Size: 9
Data type: int64

Getting items from a numpy array


# 2 Dimension Array
two_dimension_array = [Link]([[1,2,3],[4,5,6], [7,8,9]])
first_row = two_dimension_array[0]
second_row = two_dimension_array[1]
third_row = two_dimension_array[2]
print('First row:', first_row)
print('Second row:', second_row)
print('Third row: ', third_row)
First row: [1 2 3]
Second row: [4 5 6]
Third row: [7 8 9]
first_column= two_dimension_array[:,0]
second_column = two_dimension_array[:,1]
third_column = two_dimension_array[:,2]
print('First column:', first_column)
print('Second column:', second_column)
print('Third column: ', third_column)
print(two_dimension_array)
First column: [1 4 7]
Second column: [2 5 8]
Third column: [3 6 9]
[[1 2 3]
[4 5 6]
[7 8 9]]

Slicing Numpy array


Slicing in numpy is similar to slicing in python list

two_dimension_array = [Link]([[1,2,3],[4,5,6], [7,8,9]])


first_two_rows_and_columns = two_dimension_array[0:2, 0:2]
print(first_two_rows_and_columns)
[[1 2]
[4 5]]

How to reverse the rows and the whole array?


two_dimension_array[::]
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])

Reverse the row and column positions


two_dimension_array = [Link]([[1,2,3],[4,5,6], [7,8,9]])
two_dimension_array[::-1,::-1]
array([[9, 8, 7],
[6, 5, 4],
[3, 2, 1]])

How to represent missing values ?


print(two_dimension_array)
two_dimension_array[1,1] = 55
two_dimension_array[1,2] =44
print(two_dimension_array)
[[1 2 3]
[4 5 6]
[7 8 9]]
[[ 1 2 3]
[ 4 55 44]
[ 7 8 9]]
# Numpy Zeroes
# [Link](shape, dtype=float, order='C')
numpy_zeroes = [Link]((3,3),dtype=int,order='C')
numpy_zeroes
array([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
# Numpy Zeroes
numpy_ones = [Link]((3,3),dtype=int,order='C')
print(numpy_ones)
[[1 1 1]
[1 1 1]
[1 1 1]]
twoes = numpy_ones * 2
# Reshape
# [Link](), [Link]()
first_shape = [Link]([(1,2,3), (4,5,6)])
print(first_shape)
reshaped = first_shape.reshape(3,2)
print(reshaped)
[[1 2 3]
[4 5 6]]
[[1 2]
[3 4]
[5 6]]
flattened = [Link]()
flattened
array([1, 2, 3, 4, 5, 6])
## Horitzontal Stack
np_list_one = [Link]([1,2,3])
np_list_two = [Link]([4,5,6])

print(np_list_one + np_list_two)

print('Horizontal Append:', [Link]((np_list_one, np_list_two)))


[5 7 9]
Horizontal Append: [1 2 3 4 5 6]
## Vertical Stack
print('Vertical Append:', [Link]((np_list_one, np_list_two)))
Vertical Append: [[1 2 3]
[4 5 6]]

Generating Random Numbers


# Generate a random float number
random_float = [Link]()
random_float
0.018929887384753874
# Generate a random float number
random_floats = [Link](5)
random_floats
array([0.26392192, 0.35842215, 0.87908478, 0.41902195, 0.78926418])
# Generating a random integers between 0 and 10

random_int = [Link](0, 11)


random_int
4
# Generating a random integers between 2 and 11, and creating a one row
array
random_int = [Link](2,10, size=4)
random_int
array([8, 8, 8, 2])
# Generating a random integers between 0 and 10
random_int = [Link](2,10, size=(3,3))
random_int
array([[3, 5, 3],
[7, 3, 6],
[2, 3, 3]])

Generationg random numbers


# [Link](mu, sigma, size)
normal_array = [Link](79, 15, 80)
normal_array
array([ 89.49990595, 82.06056961, 107.21445842, 38.69307086,
47.85259157, 93.07381061, 76.40724259, 78.55675184,
72.17358173, 47.9888899 , 65.10370622, 76.29696568,
95.58234254, 68.14897213, 38.75862686, 122.5587927 ,
67.0762565 , 95.73990864, 81.97454563, 92.54264805,
59.37035153, 77.76828101, 52.30752166, 64.43109931,
62.63695351, 90.04616138, 75.70009094, 49.87586877,
80.22002414, 68.56708848, 76.27791052, 67.24343975,
81.86363935, 78.22703433, 102.85737041, 65.15700341,
84.87033426, 76.7569997 , 64.61321853, 67.37244562,
74.4068773 , 58.65119655, 71.66488727, 53.42458179,
70.26872028, 60.96588544, 83.56129414, 72.14255326,
81.00787609, 71.81264853, 72.64168853, 86.56608717,
94.94667321, 82.32676973, 70.5165446 , 85.43061003,
72.45526212, 87.34681775, 87.69911217, 103.02831489,
75.28598596, 67.17806893, 92.41274447, 101.06662611,
87.70013935, 70.73980645, 46.40368207, 50.17947092,
61.75618542, 90.26191397, 78.63968639, 70.84550744,
88.91826581, 103.91474733, 66.3064638 , 79.49726264,
70.81087439, 83.90130623, 87.58555972, 59.95462521])

Numpy and Statistics


import [Link] as plt
import seaborn as sns
[Link]()
[Link](normal_array, color="grey", bins=50)
(array([2., 0., 0., 0., 1., 2., 2., 0., 2., 0., 0., 1., 2., 2., 1., 4.,
3.,
4., 2., 7., 2., 2., 5., 4., 2., 4., 3., 2., 1., 5., 3., 0., 3.,
2.,
1., 0., 0., 1., 3., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 1.]),
array([ 38.69307086, 40.37038529, 42.04769973, 43.72501417,
45.4023286 , 47.07964304, 48.75695748, 50.43427191,
52.11158635, 53.78890079, 55.46621523, 57.14352966,
58.8208441 , 60.49815854, 62.17547297, 63.85278741,
65.53010185, 67.20741628, 68.88473072, 70.56204516,
72.23935959, 73.91667403, 75.59398847, 77.27130291,
78.94861734, 80.62593178, 82.30324622, 83.98056065,
85.65787509, 87.33518953, 89.01250396, 90.6898184 ,
92.36713284, 94.04444727, 95.72176171, 97.39907615,
99.07639058, 100.75370502, 102.43101946, 104.1083339 ,
105.78564833, 107.46296277, 109.14027721, 110.81759164,
112.49490608, 114.17222052, 115.84953495, 117.52684939,
119.20416383, 120.88147826, 122.5587927 ]),
<a list of 50 Patch objects>)

Matrix in numpy
four_by_four_matrix = [Link]([Link]((4,4), dtype=float))
four_by_four_matrix
matrix([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
[Link](four_by_four_matrix)[2] = 2
four_by_four_matrix
matrix([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[2., 2., 2., 2.],
[1., 1., 1., 1.]])

Numpy [Link]()
What is Arrange?

Sometimes, you want to create values that are evenly spaced within a
defined interval. For instance, you want to create values from 1 to 10; you
can use [Link]() function

# creating list using range(starting, stop, step)


lst = range(0, 11, 2)
lst
range(0, 11, 2)
for l in lst:
print(l)
2
4
6
8
10
# Similar to range arange [Link](start, stop, step)
whole_numbers = [Link](0, 20, 1)
whole_numbers
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19])
natural_numbers = [Link](1, 20, 1)
natural_numbers
odd_numbers = [Link](1, 20, 2)
odd_numbers
array([ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19])
even_numbers = [Link](2, 20, 2)
even_numbers
array([ 2, 4, 6, 8, 10, 12, 14, 16, 18])

Creating sequence of numbers using linspace


# [Link]()
# [Link]() in Python with Example
# For instance, it can be used to create 10 values from 1 to 5 evenly spaced.
[Link](1.0, 5.0, num=10)
array([1. , 1.44444444, 1.88888889, 2.33333333, 2.77777778,
3.22222222, 3.66666667, 4.11111111, 4.55555556, 5. ])
# not to include the last value in the interval
[Link](1.0, 5.0, num=5, endpoint=False)
array([1. , 1.8, 2.6, 3.4, 4.2])
# LogSpace
# LogSpace returns even spaced numbers on a log scale. Logspace has the same
parameters as [Link].

# Syntax:

# [Link](start, stop, num, endpoint)

[Link](2, 4.0, num=4)


array([ 100. , 464.15888336, 2154.43469003, 10000. ])
# to check the size of an array
x = [Link]([1,2,3], dtype=np.complex128)
x
array([1.+0.j, 2.+0.j, 3.+0.j])
[Link]
16
# indexing and Slicing NumPy Arrays in Python
np_list = [Link]([(1,2,3), (4,5,6)])
np_list
array([[1, 2, 3],
[4, 5, 6]])
print('First row: ', np_list[0])
print('Second row: ', np_list[1])
First row: [1 2 3]
Second row: [4 5 6]
print('First column: ', np_list[:,0])
print('Second column: ', np_list[:,1])
print('Third column: ', np_list[:,2])
First column: [1 4]
Second column: [2 5]
Third column: [3 6]

NumPy Statistical Functions with Example


NumPy has quite useful statistical functions for finding minimum, maximum,
mean, median, percentile,standard deviation and variance, etc from the
given elements in the array. The functions are explained as follows −
Statistical function Numpy is equipped with the robust statistical function as
listed below

 Numpy Functions
o Min [Link]()
o Max [Link]()
o Mean [Link]()
o Median [Link]()
o Varience
o Percentile
o Standard deviation [Link]()

np_normal_dis = [Link](5, 0.5, 100)


np_normal_dis
## min, max, mean, median, sd
print('min: ', two_dimension_array.min())
print('max: ', two_dimension_array.max())
print('mean: ',two_dimension_array.mean())
# print('median: ', two_dimension_array.median())
print('sd: ', two_dimension_array.std())
min: 1
max: 55
mean: 14.777777777777779
sd: 18.913709183069525
min: 1
max: 55
mean: 14.777777777777779
sd: 18.913709183069525
print(two_dimension_array)
print('Column with minimum: ', [Link](two_dimension_array,axis=0))
print('Column with maximum: ', [Link](two_dimension_array,axis=0))
print('=== Row ==')
print('Row with minimum: ', [Link](two_dimension_array,axis=1))
print('Row with maximum: ', [Link](two_dimension_array,axis=1))
[[ 1 2 3]
[ 4 55 44]
[ 7 8 9]]
Column with minimum: [1 2 3]
Column with maximum: [ 7 55 44]
=== Row ==
Row with minimum: [1 4 7]
Row with maximum: [ 3 55 9]

How to create repeating sequences?


a = [1,2,3]

# Repeat whole of 'a' two times


print('Tile: ', [Link](a, 2))

# Repeat each element of 'a' two times


print('Repeat: ', [Link](a, 2))
Tile: [1 2 3 1 2 3]
Repeat: [1 1 2 2 3 3]
How to generate random numbers?
# One random number between [0,1)
one_random_num = [Link]()
one_random_in = [Link]
print(one_random_num)
0.6149403282678213
0.4763968133790438
0.4763968133790438
# Random numbers between [0,1) of shape 2,3
r = [Link](size=[2,3])
print(r)
[[0.13031737 0.4429537 0.1129527 ]
[0.76811539 0.88256594 0.6754075 ]]
print([Link](['a', 'e', 'i', 'o', 'u'], size=10))
['u' 'o' 'o' 'i' 'e' 'e' 'u' 'o' 'u' 'a']
['i' 'u' 'e' 'o' 'a' 'i' 'e' 'u' 'o' 'i']
['iueoaieuoi']
## Random numbers between [0, 1] of shape 2, 2
rand = [Link](2,2)
rand
array([[0.97992598, 0.79642484],
[0.65263629, 0.55763145]])
rand2 = [Link](2,2)
rand2
array([[ 1.65593322, -0.52326621],
[ 0.39071179, -2.03649407]])
# Random integers between [0, 10) of shape 2,5
rand_int = [Link](0, 10, size=[5,3])
rand_int
array([[0, 7, 5],
[4, 1, 4],
[3, 5, 3],
[4, 3, 8],
[4, 6, 7]])
from scipy import stats
np_normal_dis = [Link](5, 0.5, 1000) # mean, standard deviation,
number of samples
np_normal_dis
## min, max, mean, median, sd
print('min: ', [Link](np_normal_dis))
print('max: ', [Link](np_normal_dis))
print('mean: ', [Link](np_normal_dis))
print('median: ', [Link](np_normal_dis))
print('mode: ', [Link](np_normal_dis))
print('sd: ', [Link](np_normal_dis))
min: 3.557811005458804
max: 6.876317743643499
mean: 5.035832048106663
median: 5.020161980441937
mode: ModeResult(mode=array([3.55781101]), count=array([1]))
sd: 0.489682424165213
[Link](np_normal_dis, color="grey", bins=21)
[Link]()

# [Link](): Dot Product in Python using Numpy


# Dot Product
# Numpy is powerful library for matrices computation. For instance, you can
compute the dot product with [Link]

# Syntax

# [Link](x, y, out=None)

Linear Algebra
1. Dot Product

## Linear algebra
### Dot product: product of two arrays
f = [Link]([1,2,3])
g = [Link]([4,5,3])
### 1*4+2*5 + 3*6
[Link](f, g) # 23

NumPy Matrix Multiplication with [Link]()


### Matmul: matruc product of two arrays
h = [[1,2],[3,4]]
i = [[5,6],[7,8]]
### 1*5+2*7 = 19
[Link](h, i)
array([[19, 22],
[43, 50]])
## Determinant 2*2 matrix
### 5*8-7*[Link](i)
[Link](i)
-1.999999999999999
Z = [Link]((8,8))
Z[1::2,::2] = 1
Z[::2,1::2] = 1
Z
array([[0., 1., 0., 1., 0., 1., 0., 1.],
[1., 0., 1., 0., 1., 0., 1., 0.],
[0., 1., 0., 1., 0., 1., 0., 1.],
[1., 0., 1., 0., 1., 0., 1., 0.],
[0., 1., 0., 1., 0., 1., 0., 1.],
[1., 0., 1., 0., 1., 0., 1., 0.],
[0., 1., 0., 1., 0., 1., 0., 1.],
[1., 0., 1., 0., 1., 0., 1., 0.]])
new_list = [ x + 2 for x in range(0, 11)]
new_list
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
np_arr = [Link](range(0, 11))
np_arr + 2

array([ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])

We use linear equation for quantities which have linear relationship. Let's
see the example below:

temp = [Link]([1,2,3,4,5])
pressure = temp * 2 + 5
pressure

array([ 7, 9, 11, 13, 15])

[Link](temp,pressure)
[Link]('Temperature in oC')
[Link]('Pressure in atm')
[Link]('Temperature vs Pressure')
[Link]([Link](0, 6, step=0.5))
[Link]()

To draw the Gaussian normal distribution using numpy. As you can see
below, the numpy can generate random numbers. To create random sample,
we need the mean(mu), sigma(standard deviation), mumber of data points.

mu = 28
sigma = 15
samples = 100000

x = [Link](mu, sigma, samples)


ax = [Link](x);
[Link](xlabel="x", ylabel='y')
[Link]()

Summary
To summarize, the main differences with python lists are:

1. Arrays support vectorized operations, while lists don’t.


2. Once an array is created, you cannot change its size. You will have to
create a new array or overwrite the existing one.
3. Every array has one and only one dtype. All items in it should be of
that dtype.
4. An equivalent numpy array occupies much less space than a python
list of lists.
5. numpy arrays support boolean indexing.

💻 Exercises: Day 24
1. Repeat all the examples

Pandas
Pandas is an open source, high-performance, easy-to-use data structures
and data analysis tools for the Python programming language. Pandas adds
data structures and tools designed to work with table-like data which
is Series and Data Frames. Pandas provides tools for data manipulation:

 reshaping
 merging
 sorting
 slicing
 aggregation
 imputation. If you are using anaconda, you do not have install pandas.

Installing Pandas
For Mac:

pip install conda


conda install pandas

For Windows:

pip install conda


pip install pandas

Pandas data structure is based on Series and DataFrames.


A series is a column and a DataFrame is a multidimensional table made up of
collection of series. In order to create a pandas series we should use numpy
to create a one dimensional arrays or a python list. Let us see an example of
a series:

Names Pandas Series

Countries Series

Cities Series
As you can see, pandas series is just one column of data. If we want to have
multiple columns we use data frames. The example below shows pandas
DataFrames.

Let us see, an example of a pandas data frame:

Data frame is a collection of rows and columns. Look at the table below; it
has many more columns than the example above:

Next, we will see how to import pandas and how to create Series and
DataFrames using pandas

Importing Pandas
import pandas as pd # importing pandas as pd
import numpy as np # importing numpy as np

Creating Pandas Series with Default Index


nums = [1, 2, 3, 4,5]
s = [Link](nums)
print(s)
0 1
1 2
2 3
3 4
4 5
dtype: int64

Creating Pandas Series with custom index


nums = [1, 2, 3, 4, 5]
s = [Link](nums, index=[1, 2, 3, 4, 5])
print(s)
1 1
2 2
3 3
4 4
5 5
dtype: int64
fruits = ['Orange','Banana','Mango']
fruits = [Link](fruits, index=[1, 2, 3])
print(fruits)
1 Orange
2 Banana
3 Mango
dtype: object

Creating Pandas Series from a Dictionary


dct = {'name':'Asabeneh','country':'Finland','city':'Helsinki'}
s = [Link](dct)
print(s)
name Asabeneh
country Finland
city Helsinki
dtype: object

Creating a Constant Pandas Series


s = [Link](10, index = [1, 2, 3])
print(s)
1 10
2 10
3 10
dtype: int64

Creating a Pandas Series Using Linspace


s = [Link]([Link](5, 20, 10)) # linspace(starting, end, items)
print(s)
0 5.000000
1 6.666667
2 8.333333
3 10.000000
4 11.666667
5 13.333333
6 15.000000
7 16.666667
8 18.333333
9 20.000000
dtype: float64

DataFrames
Pandas data frames can be created in different ways.

Creating DataFrames from List of Lists


data = [
['Asabeneh', 'Finland', 'Helsink'],
['David', 'UK', 'London'],
['John', 'Sweden', 'Stockholm']
]
df = [Link](data, columns=['Names','Country','City'])
print(df)

Names Country City

0 Asabeneh Finland Helsink

1 David UK London

2 John Sweden Stockholm

Creating DataFrame Using Dictionary


data = {'Name': ['Asabeneh', 'David', 'John'], 'Country':[
'Finland', 'UK', 'Sweden'], 'City': ['Helsiki', 'London', 'Stockholm']}
df = [Link](data)
print(df)

Name Country City

0 Asabeneh Finland Helsiki

1 David UK London

2 John Sweden Stockholm


Creating DataFrames from a List of Dictionaries
data = [
{'Name': 'Asabeneh', 'Country': 'Finland', 'City': 'Helsinki'},
{'Name': 'David', 'Country': 'UK', 'City': 'London'},
{'Name': 'John', 'Country': 'Sweden', 'City': 'Stockholm'}]
df = [Link](data)
print(df)

Name Country City

0 Asabeneh Finland Helsinki

1 David UK London

2 John Sweden Stockholm

Reading CSV File Using Pandas


To download the CSV file, what is needed in this example, console/command
line is enough:

curl -O [Link]
data/[Link]

Put the downloaded file in your working directory.

import pandas as pd

df = pd.read_csv('[Link]')
print(df)

Data Exploration
Let us read only the first 5 rows using head()

print([Link]()) # give five rows we can increase the number of rows by


passing argument to the head() method

Gender Height Weight

0 Male 73.847017 241.893563

1 Male 68.781904 162.310473


Gender Height Weight

2 Male 74.110105 212.740856

3 Male 71.730978 220.042470

4 Male 69.881796 206.349801

Let us also explore the last recordings of the dataframe using the tail()
methods.

print([Link]()) # tails give the last five rows, we can increase the rows by
passing argument to tail method

Gender Height Weight

999
Female 66.172652 136.777454
5

999
Female 67.067155 170.867906
6

999
Female 63.867992 128.475319
7

999
Female 69.034243 163.852461
8

999
Female 61.944246 113.649103
9

As you can see the csv file has three rows: Gender, Height and Weight. If the
DataFrame would have a long rows, it would be hard to know all the
columns. Therefore, we should use a method to know the colums. we do not
know the number of rows. Let's use shape meathod.

print([Link]) # as you can see 10000 rows and three columns


(10000, 3)
Let us get all the columns using columns.

print([Link])
Index(['Gender', 'Height', 'Weight'], dtype='object')

Now, let us get a specific column using the column key

heights = df['Height'] # this is now a series


print(heights)
0 73.847017
1 68.781904
2 74.110105
3 71.730978
4 69.881796
...
9995 66.172652
9996 67.067155
9997 63.867992
9998 69.034243
9999 61.944246
Name: Height, Length: 10000, dtype: float64
weights = df['Weight'] # this is now a series
print(weights)
0 241.893563
1 162.310473
2 212.740856
3 220.042470
4 206.349801
...
9995 136.777454
9996 170.867906
9997 128.475319
9998 163.852461
9999 113.649103
Name: Weight, Length: 10000, dtype: float64
print(len(heights) == len(weights))
True

The describe() method provides a descriptive statistical values of a dataset.

print([Link]()) # give statisical information about height data


count 10000.000000
mean 66.367560
std 3.847528
min 54.263133
25% 63.505620
50% 66.318070
75% 69.174262
max 78.998742
Name: Height, dtype: float64
print([Link]())
count 10000.000000
mean 161.440357
std 32.108439
min 64.700127
25% 135.818051
50% 161.212928
75% 187.169525
max 269.989699
Name: Weight, dtype: float64
print([Link]()) # describe can also give statistical information from a
dataFrame

Height Weight

count 10000.000000 10000.000000

mean 66.367560 161.440357

std 3.847528 32.108439

min 54.263133 64.700127

25% 63.505620 135.818051

50% 66.318070 161.212928

75% 69.174262 187.169525

max 78.998742 269.989699

Similar to describe(), the info() method also give information about the
dataset.

Modifying a DataFrame
Modifying a DataFrame: * We can create a new DataFrame * We can create a
new column and add it to the DataFrame, * we can remove an existing
column from a DataFrame, * we can modify an existing column in a
DataFrame, * we can change the data type of column values in the
DataFrame

Creating a DataFrame
As always, first we import the necessary packages. Now, lets import pandas
and numpy, two best friends ever.

import pandas as pd
import numpy as np
data = [
{"Name": "Asabeneh", "Country":"Finland","City":"Helsinki"},
{"Name": "David", "Country":"UK","City":"London"},
{"Name": "John", "Country":"Sweden","City":"Stockholm"}]
df = [Link](data)
print(df)

Name Country City

0 Asabeneh Finland Helsinki

1 David UK London

2 John Sweden Stockholm

Adding a column to a DataFrame is like adding a key to a dictionary.

First let's use the previous example to create a DataFrame. After we create
the DataFrame, we will start modifying the columns and column values.

Adding a New Column


Let's add a weight column in the DataFrame

weights = [74, 78, 69]


df['Weight'] = weights
df

Name Country City Weight

0 Asabeneh Finland Helsinki 74

1 David UK London 78
Name Country City Weight

2 John Sweden Stockholm 69

Let's add a height column into the DataFrame aswell

heights = [173, 175, 169]


df['Height'] = heights
print(df)

Countr
Name City Weight Height
y

0 Asabeneh Finland Helsinki 74 173

1 David UK London 78 175

2 John Sweden Stockholm 69 169

As you can see in the DataFrame above, we did add new columns, Weight
and Height. Let's add one additional column called BMI(Body Mass Index) by
calculating their BMI using thier mass and height. BMI is mass divided by
height squared (in meters) - Weight/Height * Height.

As you can see, the height is in centimeters, so we shoud change it to


meters. Let's modify the height row.

Modifying column values


df['Height'] = df['Height'] * 0.01
df

Countr
Name City Weight Height
y

0 Asabeneh Finland Helsinki 74 1.73

1 David UK London 78 1.75

2 John Sweden Stockholm 69 1.69


# Using functions makes our code clean, but you can calculate the bmi without
one
def calculate_bmi ():
weights = df['Weight']
heights = df['Height']
bmi = []
for w,h in zip(weights, heights):
b = w/(h*h)
[Link](b)
return bmi

bmi = calculate_bmi()
df['BMI'] = bmi
df

Countr Heigh
Name City Weight BMI
y t

0 Asabeneh Finland Helsinki 74 1.73 24.725183

1 David UK London 78 1.75 25.469388

2 John Sweden Stockholm 69 1.69 24.158818

Formating DataFrame columns


The BMI column values of the DataFrame are float with many significant
digits after decimal. Let's change it to one significant digit after point.

df['BMI'] = round(df['BMI'], 1)
print(df)

Countr Heigh
Name City Weight BMI
y t

0 Asabeneh Finland Helsinki 74 1.73 24.7

1 David UK London 78 1.75 25.5

2 John Sweden Stockholm 69 1.69 24.2

The information in the DataFrame seems not yet complete, let's add birth
year and current year columns.
birth_year = ['1769', '1985', '1990']
current_year = [Link](2020, index=[0, 1,2])
df['Birth Year'] = birth_year
df['Current Year'] = current_year
df

Birt
Countr Weigh Heigh BM Curren
Name City h
y t t I t Year
Year

Asabene
0 Finland Helsinki 74 1.73 24.7 1769 2020
h

1 David UK London 78 1.75 25.5 1985 2020

Stockhol
2 John Sweden 69 1.69 24.2 1990 2020
m

Checking data types of Column values


print([Link])
dtype('int64')
df['Birth Year'].dtype # it gives string object , we should change this to
number
df['Birth Year'] = df['Birth Year'].astype('int')
print(df['Birth Year'].dtype) # let's check the data type now
dtype('int32')

Now same for the current year:

df['Current Year'] = df['Current Year'].astype('int')


df['Current Year'].dtype
dtype('int32')

Now, the column values of birth year and current year are integers. We can
calculate the age.

ages = df['Current Year'] - df['Birth Year']


ages
0 251
1 35
2 30
dtype: int32
df['Ages'] = ages
print(df)

Birt
Curre
Count Weig Heig BM h Ag
Name City nt
ry ht ht I Yea es
Year
r

Asaben Finlan 24. 176


0 Helsinki 74 1.73 2019 250
eh d 7 9

25. 198
1 David UK London 78 1.75 2019 34
5 5

Swede Stockho 24. 199


2 John 69 1.69 2019 29
n lm 2 0

The person in the first row lived so far for 251 years. It is unlikely for
someone to live so long. Either it is a typo or the data is cooked. So lets fill
that data with average of the columns without including outlier.

mean = (35 + 30)/ 2

mean = (35 + 30)/ 2


print('Mean: ',mean) #it is good to add some description to the output, so
we know what is what
Mean: 32.5

Boolean Indexing
print(df[df['Ages'] > 120])

Birt
Curre
Count Weig Heig BM h Age
Name City nt
ry ht ht I Yea s
Year
r

Asaben Finlan Helsin 24. 176


0 74 1.73 2020 251
eh d ki 7 9

print(df[df['Ages'] < 120])


Birt
Curre
Nam Count Weig Heig BM h Age
City nt
e ry ht ht I Yea s
Year
r

Davi 25. 198


1 UK London 78 1.75 2020 35
d 5 5

Swede Stockhol 24. 199


2 John 69 1.69 2020 30
n m 2 0

Exercises: Day 25
1. Read the hacker_news.csv file from data directory
2. Get the first five rows
3. Get the last five rows
4. Get the title column as pandas series
5. Count the number of rows and columns
o Filter the titles which contain python
o Filter the titles which contain JavaScript
o Explore the data and make sense of it

Python for Web


Python is a general purpose programming language and it can be used for
many places. In this section, we will see how we use Python for the web.
There are many Python web frame works. Django and Flask are the most
popular ones. Today, we will see how to use Flask for web development.

Flask
Flask is a web development framework written in Python. Flask uses Jinja2
template engine. Flask can be also used with other modern front libraries
such as React.

If you did not install the virtualenv package yet install it first. Virtual
environment will allows to isolate project dependencies from the local
machine dependencies.

Folder structure
After completing all the step, your project file structure should look like this:

├── Procfile
├── [Link]
├── env
│ ├── bin
├── [Link]
├── static
│ └── css
│ └── [Link]
└── templates
├── [Link]
├── [Link]
├── [Link]
├── [Link]
└── [Link]

Setting up your project directory


Follow the following steps to get started with Flask.

Step 1: install virtualenv using the following command.

pip install virtualenv

Step 2:

asabeneh@Asabeneh:~/Desktop$ mkdir python_for_web


asabeneh@Asabeneh:~/Desktop$ cd python_for_web/
asabeneh@Asabeneh:~/Desktop/python_for_web$ virtualenv venv
asabeneh@Asabeneh:~/Desktop/python_for_web$ source venv/bin/activate
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ pip freeze
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ pip install Flask
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ pip freeze
Click==7.0
Flask==1.1.1
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
Werkzeug==0.16.0
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$

We created a project director named python_for_web. Inside the project we


created a virtual environment venv which could be any name but I prefer to
call it venv. Then we activated the virtual environment. We used pip freeze
to check the installed packages in the project directory. The result of pip
freeze was empty because a package was not installed yet.

Now, let's create [Link] file in the project directory and write the following
code. The [Link] file will be the main file in the project. The following code
has flask module, os module.
Creating routes
The home route.

# let's import the flask


from flask import Flask
import os # importing operating system module

app = Flask(__name__)

@[Link]('/') # this decorator create the home route


def home ():
return '<h1>Welcome</h1>'

@[Link]('/about')
def about():
return '<h1>About us</h1>'

if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)

To run the flask application, write python [Link] in the main flask application
directory.

After you run python [Link] check local host 5000.

Let us add additional route. Creating about route

# let's import the flask


from flask import Flask
import os # importing operating system module

app = Flask(__name__)

@[Link]('/') # this decorator create the home route


def home ():
return '<h1>Welcome</h1>'

@[Link]('/about')
def about():
return '<h1>About us</h1>'

if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)

Now, we added the about route in the above code. How about if we want to
render an HTML file instead of string? It is possible to render HTML file using
the function render_templae. Let us create a folder called templates and
create [Link] and [Link] in the project directory. Let us also import
the render_template function from flask.

Creating templates
Create the HTML files inside templates folder.

[Link]

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Home</title>
</head>

<body>
<h1>Welcome Home</h1>
</body>
</html>

[Link]

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>About</title>
</head>

<body>
<h1>About Us</h1>
</body>
</html>

Python Script
[Link]

# let's import the flask


from flask import Flask, render_template
import os # importing operating system module

app = Flask(__name__)

@[Link]('/') # this decorator create the home route


def home ():
return render_template('[Link]')
@[Link]('/about')
def about():
return render_template('[Link]')

if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)

As you can see to go to different pages or to navigate we need a navigation.


Let's add a link to each page or let's create a layout which we use to every
page.

Navigation
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>

Now, we can navigate between the pages using the above link. Let us create
additional page which handle form data. You can call it any name, I like to
call it [Link].

We can inject data to the HTML files using Jinja2 template engine.

# let's import the flask


from flask import Flask, render_template, request, redirect, url_for
import os # importing operating system module

app = Flask(__name__)

@[Link]('/') # this decorator create the home route


def home ():
techs = ['HTML', 'CSS', 'Flask', 'Python']
name = '30 Days Of Python Programming'
return render_template('[Link]', techs=techs, name = name, title =
'Home')

@[Link]('/about')
def about():
name = '30 Days Of Python Programming'
return render_template('[Link]', name = name, title = 'About Us')

@[Link]('/post')
def post():
name = 'Text Analyzer'
return render_template('[Link]', name = name, title = name)

if __name__ == '__main__':
# for deployment
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)

Let's see the templates too:

[Link]

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Home</title>
</head>

<body>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
<h1>Welcome to {{name}}</h1>
<ul>
{% for tech in techs %}
<li>{{tech}}</li>
{% endfor %}
</ul>
</body>
</html>

[Link]

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>About Us</title>
</head>

<body>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
<h1>About Us</h1>
<h2>{{name}}</h2>
</body>
</html>

Creating a layout
In the template files, there are lots of repeated codes, we can write a layout
and we can remove the repetition. Let's create [Link] inside the
templates folder. After we create the layout we will import to every file.

Serving Static File

Create a static folder in your project directory. Inside the static folder create
CSS or styles folder and create a CSS stylesheet. We use the url_for module
to serve the static file.

[Link]

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
href="[Link]
Nunito:300,400|Raleway:300,400,500&display=swap"
rel="stylesheet"
/>
<link
rel="stylesheet"
href="{{ url_for('static', filename='css/[Link]') }}"
/>
{% if title %}
<title>30 Days of Python - {{ title}}</title>
{% else %}
<title>30 Days of Python</title>
{% endif %}
</head>

<body>
<header>
<div class="menu-container">
<div>
<a class="brand-name nav-link" href="/">30DaysOfPython</a>
</div>
<ul class="nav-lists">
<li class="nav-list">
<a class="nav-link active" href="{{ url_for('home') }}">Home</a>
</li>
<li class="nav-list">
<a class="nav-link active"
href="{{ url_for('about') }}">About</a>
</li>
<li class="nav-list">
<a class="nav-link active" href="{{ url_for('post') }}"
>Text Analyzer</a
>
</li>
</ul>
</div>
</header>
<main>
{% block content %} {% endblock %}
</main>
</body>
</html>

Now, lets remove all the repeated code in the other template files and import
the [Link]. The href is using url_for function with the name of the route
function to connect each navigation route.

[Link]

{% extends '[Link]' %} {% block content %}


<div class="container">
<h1>Welcome to {{name}}</h1>
<p>
This application clean texts and analyse the number of word, characters
and
most frequent words in the text. Check it out by click text analyzer at
the
menu. You need the following technologies to build this web application:
</p>
<ul class="tech-lists">
{% for tech in techs %}
<li class="tech">{{tech}}</li>

{% endfor %}
</ul>
</div>

{% endblock %}

[Link]

{% extends '[Link]' %} {% block content %}


<div class="container">
<h1>About {{name}}</h1>
<p>
This is a 30 days of python programming challenge. If you have been
coding
this far, you are awesome. Congratulations for the job well done!
</p>
</div>
{% endblock %}

[Link]

{% extends '[Link]' %} {% block content %}


<div class="container">
<h1>Text Analyzer</h1>
<form action="[Link]
method="POST">
<div>
<textarea rows="25" name="content" autofocus></textarea>
</div>
<div>
<input type="submit" class="btn" value="Process Text" />
</div>
</form>
</div>

{% endblock %}

Request methods, there are different request methods(GET, POST, PUT,


DELETE) are the common request methods which allow us to do
CRUD(Create, Read, Update, Delete) operation.

In the post, route we will use GET and POST method alternative depending
on the type of request, check how it looks in the code below. The request
method is a function to handle request methods and also to access form
data. [Link]

# let's import the flask


from flask import Flask, render_template, request, redirect, url_for
import os # importing operating system module

app = Flask(__name__)
# to stop caching static file
[Link]['SEND_FILE_MAX_AGE_DEFAULT'] = 0

@[Link]('/') # this decorator create the home route


def home ():
techs = ['HTML', 'CSS', 'Flask', 'Python']
name = '30 Days Of Python Programming'
return render_template('[Link]', techs=techs, name = name, title =
'Home')

@[Link]('/about')
def about():
name = '30 Days Of Python Programming'
return render_template('[Link]', name = name, title = 'About Us')

@[Link]('/result')
def result():
return render_template('[Link]')

@[Link]('/post', methods= ['GET','POST'])


def post():
name = 'Text Analyzer'
if [Link] == 'GET':
return render_template('[Link]', name = name, title = name)
if [Link] =='POST':
content = [Link]['content']
print(content)
return redirect(url_for('result'))
if __name__ == '__main__':
# for deployment
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)

So far, we have seen how to use template and how to inject data to
template, how to a common layout. Now, lets handle static file. Create a
folder called static in the project director and create a folder called css.
Inside css folder create [Link]. Your main. css file will be linked to the
[Link].

You don't have to write the css file, copy and use it. Let's move on to
deployment.

Deployment

Creating Heroku account

Heroku provides a free deployment service for both front end and fullstack
applications. Create an account on heroku and install the heroku CLI for you
machine. After installing heroku write the following command

Login to Heroku

asabeneh@Asabeneh:~$ heroku login


heroku: Press any key to open up the browser to login or q to exit:

Let's see the result by clicking any key from the keyboard. When you press
any key from you keyboard it will open the heroku login page and click the
login page. Then you will local machine will be connected to the remote
heroku server. If you are connected to remote server, you will see this.

asabeneh@Asabeneh:~$ heroku login


heroku: Press any key to open up the browser to login or q to exit:
Opening browser to [Link]
4458-a2c2-ba2ce7f41610
Logging in... done
Logged in as asabeneh@[Link]
asabeneh@Asabeneh:~$

Create requirements and Procfile

Before we push our code to remote server, we need requirements

 [Link]
 Procfile
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ pip freeze
Click==7.0
Flask==1.1.1
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
Werkzeug==0.16.0
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ touch [Link]
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ pip freeze >
[Link]
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ cat [Link]
Click==7.0
Flask==1.1.1
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
Werkzeug==0.16.0
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ touch Procfile
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$ ls
Procfile env/ static/
[Link] [Link] templates/
(env) asabeneh@Asabeneh:~/Desktop/python_for_web$

The Procfile will have the command which run the application in the web
server in our case on Heroku.

web: python [Link]

Pushing project to heroku

Now, it is ready to be deployed. Steps to deploy the application on heroku

1. git init
2. git add .
3. git commit -m "commit message"
4. heroku create 'name of the app as one word'
5. git push heroku master
6. heroku open(to launch the deployed application)

After this step you will get an application like this

Exercises: Day 26
1. You will build this application. Only the text analyser part is left

Python with MongoDB


Python is a backend technology and it can be connected with different data
base applications. It can be connected to both SQL and noSQL databases. In
this section, we connect Python with MongoDB database which is noSQL
database.

MongoDB
MongoDB is a NoSQL database. MongoDB stores data in a JSON like
document which make MongoDB very flexible and scalable. Let us see the
different terminologies of SQL and NoSQL databases. The following table will
make the difference between SQL versus NoSQL databases.

SQL versus NoSQL

In this section, we will focus on a NoSQL database MongoDB. Lets sign up


on mongoDB by click on the sign in button then click register on the next
page.
Complete the fields and click continue
Select the free plan

Choose the proximate free region and give any name for you cluster.
Now, a free sandbox is created
All local host access
Add user and password
Create a mongoDB uri link
Select Python 3.6 or above driver
Getting Connection String(MongoDB URI)
Copy the connection string link and you will get something like this:

mongodb+srv://asabeneh:<password>@[Link]/test?
retryWrites=true&w=majority

Do not worry about the url, it is a means to connect your application with
mongoDB. Let us replace the password placeholder with the password you
used to add a user.

Example:

mongodb+srv://asabeneh:123123123@[Link]/test?
retryWrites=true&w=majority
Now, I replaced everything and the password is 123123 and the name of the
database is thirty_days_python. This is just an example, your password must
be stronger than the example password.

Python needs a mongoDB driver to access mongoDB database. We will


use pymongo with dnspython to connect our application with mongoDB
base . Inside your project directory install pymongo and dnspython.

pip install pymongo dnspython

The "dnspython" module must be installed to use mongodb+srv:// URIs. The


dnspython is a DNS toolkit for Python. It supports almost all record types.

Connecting Flask application to MongoDB Cluster


# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
print(client.list_database_names())

app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)

When we run the above code we get the default mongoDB databases.

['admin', 'local']

Creating a database and collection


Let us create a database, database and collection in mongoDB will be
created if it doesn't exist. Let's create a data base
name thirty_days_of_python and students collection.

To create a database:

db = client.name_of_databse # we can create a database like this or the


second way
db = client['name_of_database']
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
# Creating database
db = client.thirty_days_of_python
# Creating students collection and inserting a document
[Link].insert_one({'name': 'Asabeneh', 'country': 'Finland', 'city':
'Helsinki', 'age': 250})
print(client.list_database_names())

app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)

After we create a database, we also created a students collection and we


used insert_one() method to insert a document. Now, the
database thirty_days_of_python and students collection have been created
and the document has been inserted. Check your mongoDB cluster and you
will see both the database and the collection. Inside the collection, there will
be a document.

['thirty_days_of_python', 'admin', 'local']

If you see this on the mongoDB cluster, it means you have successfully
created a database and a collection.
If you have seen on the figure, the document has been created with a long id
which acts as a primary key. Every time we create a document mongoDB
create and unique id for it.

Inserting many documents to collection


The insert_one() method inserts one item at a time if we want to insert many
documents at once either we use insert_many() method or for loop. We can
use for loop to inset many documents at once.

# let's import the flask


from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)

students = [
{'name':'David','country':'UK','city':'London','age':34},
{'name':'John','country':'Sweden','city':'Stockholm','age':28},
{'name':'Sami','country':'Finland','city':'Helsinki','age':25},
]
for student in students:
[Link].insert_one(student)

app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)

MongoDB Find
The find() and findOne() methods are common method to find data in a
collection in mongoDB database. It is similar to the SELECT statement in a
MySQL database. Let us use the find_one() method to get a document in a
database collection.

 *find_one({"_id": ObjectId("id"}): Gets the first occurrence if an id is


not provided

# let's import the flask


from flask import Flask, render_template
import os # importing operating system module
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
student = [Link].find_one()
print(student)

app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country':
'Helsinki', 'city': 'Helsinki', 'age': 250}

The above query returns the first entry but we can target specific document
using specific _id. Let us do one example, use David's id to get David object.
'_id':ObjectId('5df68a23f106fe2d315bbc8c')

# let's import the flask


from flask import Flask, render_template
import os # importing operating system module
from [Link] import ObjectId # id object
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
student = [Link].find_one({'_id':ObjectId('5df68a23f106fe2d315bbc8c')})
print(student)

app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country':
'UK', 'city': 'London', 'age': 34}

We have seen, how to use find_one() using the above examples. Let's move
one to find()

 find(): returns all the occurrence from a collection if we don't pass a


query object. The object is [Link] object.

# let's import the flask


from flask import Flask, render_template
import os # importing operating system module

MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
students = [Link]()
for student in students:
print(student)

app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country':
'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country':
'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country':
'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country':
'Finland', 'city': 'Helsinki', 'age': 25}

We can specify which fields to return by passing second object in


the find({}, {}). 0 means not include and 1 means include but we can not
mix 0 and 1, except for _id.

# let's import the flask


from flask import Flask, render_template
import os # importing operating system module

MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
students = [Link]({}, {"_id":0, "name": 1, "country":1}) # 0 means
not include and 1 means include
for student in students:
print(student)

app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)
{'name': 'Asabeneh', 'country': 'Finland'}
{'name': 'David', 'country': 'UK'}
{'name': 'John', 'country': 'Sweden'}
{'name': 'Sami', 'country': 'Finland'}

Find with Query


In mongoDB find take a query object. We can pass a query object and we
can filter the documents we like to filter out.

# let's import the flask


from flask import Flask, render_template
import os # importing operating system module

MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database

query = {
"country":"Finland"
}
students = [Link](query)

for student in students:


print(student)

app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country':
'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country':
'Finland', 'city': 'Helsinki', 'age': 25}

Query with modifiers

# let's import the flask


from flask import Flask, render_template
import os # importing operating system module
import pymongo

MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database

query = {
"city":"Helsinki"
}
students = [Link](query)
for student in students:
print(student)

app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country':
'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country':
'Finland', 'city': 'Helsinki', 'age': 25}

Find query with modifier


# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
import pymongo

MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
query = {
"country":"Finland",
"city":"Helsinki"
}
students = [Link](query)
for student in students:
print(student)

app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country':
'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country':
'Finland', 'city': 'Helsinki', 'age': 25}

Query with modifiers

# let's import the flask


from flask import Flask, render_template
import os # importing operating system module
import pymongo

MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
query = {"age":{"$gt":30}}
students = [Link](query)
for student in students:
print(student)

app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country':
'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country':
'UK', 'city': 'London', 'age': 34}
# let's import the flask
from flask import Flask, render_template
import os # importing operating system module
import pymongo

MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
query = {"age":{"$gt":30}}
students = [Link](query)
for student in students:
print(student)
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country':
'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country':
'Finland', 'city': 'Helsinki', 'age': 25}

Limiting documents
We can limit the number of documents we return using the limit() method.

# let's import the flask


from flask import Flask, render_template
import os # importing operating system module
import pymongo

MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
[Link]().limit(3)

Find with sort


By default, sort is in ascending order. We can change the sorting to
descending order by adding -1 parameter.

# let's import the flask


from flask import Flask, render_template
import os # importing operating system module
import pymongo

MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
students = [Link]().sort('name')
for student in students:
print(student)

students = [Link]().sort('name',-1)
for student in students:
print(student)

students = [Link]().sort('age')
for student in students:
print(student)

students = [Link]().sort('age',-1)
for student in students:
print(student)

app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)

Ascending order

{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country':


'Finland', 'city': 'Helsinki', 'age': 250}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country':
'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country':
'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country':
'Finland', 'city': 'Helsinki', 'age': 25}

Descending order

{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country':


'Finland', 'city': 'Helsinki', 'age': 25}
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country':
'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country':
'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country':
'Finland', 'city': 'Helsinki', 'age': 250}

Update with query


We will use update_one() method to update one item. It takes two object one
is a query and the second is the new object. The first person, Asabeneh got a
very implausible age. Let us update Asabeneh's age.

# let's import the flask


from flask import Flask, render_template
import os # importing operating system module
import pymongo

MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database

query = {'age':250}
new_value = {'$set':{'age':38}}

[Link].update_one(query, new_value)
# lets check the result if the age is modified
for student in [Link]():
print(student)

app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country':
'Finland', 'city': 'Helsinki', 'age': 38}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country':
'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a23f106fe2d315bbc8d'), 'name': 'John', 'country':
'Sweden', 'city': 'Stockholm', 'age': 28}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country':
'Finland', 'city': 'Helsinki', 'age': 25}

When we want to update many documents at once we


use upate_many() method.

Delete Document
The method delete_one() deletes one document. The delete_one() takes a
query object parameter. It only removes the first occurrence. Let us remove
one John from the collection.

# let's import the flask


from flask import Flask, render_template
import os # importing operating system module
import pymongo
MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database

query = {'name':'John'}
[Link].delete_one(query)

for student in [Link]():


print(student)
# lets check the result if the age is modified
for student in [Link]():
print(student)

app = Flask(__name__)
if __name__ == '__main__':
# for deployment we use the environ
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)
{'_id': ObjectId('5df68a21f106fe2d315bbc8b'), 'name': 'Asabeneh', 'country':
'Finland', 'city': 'Helsinki', 'age': 38}
{'_id': ObjectId('5df68a23f106fe2d315bbc8c'), 'name': 'David', 'country':
'UK', 'city': 'London', 'age': 34}
{'_id': ObjectId('5df68a23f106fe2d315bbc8e'), 'name': 'Sami', 'country':
'Finland', 'city': 'Helsinki', 'age': 25}

As you can see John has been removed from the collection.

When we want to delete many documents we use delete_many() method, it


takes a query object. If we pass an empty query object to delete_many({}) it
will delete all the documents in the collection.

Drop a collection
Using the drop() method we can delete a collection from a database.

# let's import the flask


from flask import Flask, render_template
import os # importing operating system module
import pymongo

MONGODB_URI = 'mongodb+srv://asabeneh:your_password_goes_here@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database
[Link]()

Now, we have deleted the students collection from the database.


Application Programming
Interface(API)
API
API stands for Application Programming Interface. The kind of API we will
cover in this section is going to be Web APIs. Web APIs are the defined
interfaces through which interactions happen between an enterprise and
applications that use its assets, which also is a Service Level Agreement
(SLA) to specify the functional provider and expose the service path or URL
for its API users.

In the context of web development, an API is defined as a set of


specifications, such as Hypertext Transfer Protocol (HTTP) request messages,
along with a definition of the structure of response messages, usually in an
XML or a JavaScript Object Notation (JSON) format.

Web API has been moving away from Simple Object Access Protocol (SOAP)
based web services and service-oriented architecture (SOA) towards more
direct representational state transfer (REST) style web resources.

Social media services, web APIs have allowed web communities to share
content and data between communities and different platforms.

Using API, content that is created in one place dynamically can be posted
and updated to multiple locations on the web.

For example, Twitter's REST API allows developers to access core Twitter
data and the Search API provides methods for developers to interact with
Twitter Search and trends data.

Many applications provide API end points. Some examples of API such as the
countries API, cat's breed API.

In this section, we will cover a RESTful API that uses HTTP request methods
to GET, PUT, POST and DELETE data.

Building API
RESTful API is an application program interface (API) that uses HTTP requests
to GET, PUT, POST and DELETE data. In the previous sections, we have
learned about python, flask and mongoDB. We will use the knowledge we
acquire to develop a RESTful API using Python flask and mongoDB database.
Every application which has CRUD(Create, Read, Update, Delete) operation
has an API to create data, to get data, to update data or to delete data from
a database.

To build an API, it is good to understand HTTP protocol and HTTP request and
response cycle.

HTTP(Hypertext Transfer Protocol)


HTTP is an established communication protocol between a client and a
server. A client in this case is a browser and server is the place where you
access data. HTTP is a network protocol used to deliver resources which
could be files on the World Wide Web, whether they are HTML files, image
files, query results, scripts, or other file types.

A browser is an HTTP client because it sends requests to an HTTP server


(Web server), which then sends responses back to the client.

Structure of HTTP
HTTP uses client-server model. An HTTP client opens a connection and sends
a request message to an HTTP server and the HTTP server returns response
message which is the requested resources. When the request response cycle
completes the server closes the connection.

The format of the request and response messages are similar. Both kinds of
messages have

 an initial line,
 zero or more header lines,
 a blank line (i.e. a CRLF by itself), and
 an optional message body (e.g. a file, or query data, or query output).
Let us an example of request and response messages by navigating this
site:[Link] This site has been
deployed on Heroku free dyno and in some months may not work because of
high request. Support this work to make the server run all the time.

Initial Request Line(Status Line)


The initial request line is different from the response. A request line has
three parts, separated by spaces:

 method name(GET, POST, HEAD)


 path of the requested resource,
 the version of HTTP being used. eg GET / HTTP/1.1

GET is the most common HTTP that helps to get or read resource and POST
is a common request method to create resource.

Initial Response Line(Status Line)


The initial response line, called the status line, also has three parts separated
by spaces:

 HTTP version
 Response status code that gives the result of the request, and a reason
which describes the status code. Example of status lines are: HTTP/1.0
200 OK or HTTP/1.0 404 Not Found Notes:

The most common status codes are: 200 OK: The request succeeded, and
the resulting resource (e.g. file or script output) is returned in the message
body. 500 Server Error A complete list of HTTP status code can be
found here. It can be also found here.

Header Fields
As you have seen in the above screenshot, header lines provide information
about the request or response, or about the object sent in the message
body.

GET / HTTP/1.1
Host: [Link]
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36
Sec-Fetch-User: ?1
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/
apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Referer: [Link]
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9,fi-FI;q=0.8,fi;q=0.7,en-CA;q=0.6,en-
US;q=0.5,fr;q=0.4

The message body


An HTTP message may have a body of data sent after the header lines. In a
response, this is where the requested resource is returned to the client (the
most common use of the message body), or perhaps explanatory text if
there's an error. In a request, this is where user-entered data or uploaded
files are sent to the server.

If an HTTP message includes a body, there are usually header lines in the
message that describe the body. In particular,

The Content-Type: header gives the MIME-type of the data in the


body(text/html, application/json, text/plain, text/css, image/gif). The Content-
Length: header gives the number of bytes in the body.

Request Methods
The GET, POST, PUT and DELETE are the HTTP request methods which we are
going to implement an API or a CRUD operation application.

1. GET: GET method is used to retrieve and get information from the
given server using a given URI. Requests using GET should only
retrieve data and should have no other effect on the data.

2. POST: POST request is used to create data and send data to the server,
for example, creating a new post, file upload, etc. using HTML forms.

3. PUT: Replaces all current representations of the target resource with


the uploaded content and we use it modify or update data.

4. DELETE: Removes data

💻 Exercises: Day 28
1. Read about API and HTTP

Building API
In this section, we will cove a RESTful API that uses HTTP request methods to
GET, PUT, POST and DELETE data.
RESTful API is an application program interface (API) that uses HTTP requests
to GET, PUT, POST and DELETE data. In the previous sections, we have
learned about python, flask and mongoDB. We will use the knowledge we
acquire to develop a RESTful API using python flask and mongoDB. Every
application which has CRUD(Create, Read, Update, Delete) operation has an
API to create data, to get data, to update data or to delete data from
database.

The browser can handle only get request. Therefore, we have to have a tool
which can help us to handle all request methods(GET, POST, PUT, DELETE).

Examples of API

 Countries API: [Link]


 Cats breed API: [Link]

Postman is a very popular tool when it comes to API development. So, if you
like to do this section you need to download postman. An alternative of
Postman is Insomnia.
Structure of an API
An API end point is a URL which can help to retrieve, create, update or delete
a resource. The structure looks like this:
Example: [Link] Returns the
members of the specified list. Private list members will only be shown if the
authenticated user owns the specified list. The name of the company name
followed by version followed by the purpose of the API. The methods: HTTP
methods & URLs
The API uses the following HTTP methods for object manipulation:

GET Used for object retrieval


POST Used for object creation and object actions
PUT Used for object update
DELETE Used for object deletion

Let us build an API which collects information about 30DaysOfPython


students. We will collect the name, country, city, date of birth, skills and bio.

To implement this API, we will use:

 Postman
 Python
 Flask
 MongoDB

Retrieving data using get


In this step, let us use dummy data and return it as a json. To return it as
json, will use json module and Response module.

# let's import the flask

from flask import Flask, Response


import json

app = Flask(__name__)

@[Link]('/api/v1.0/students', methods = ['GET'])


def students ():
student_list = [
{
'name':'Asabeneh',
'country':'Finland',
'city':'Helsinki',
'skills':['HTML', 'CSS','JavaScript','Python']
},
{
'name':'David',
'country':'UK',
'city':'London',
'skills':['Python','MongoDB']
},
{
'name':'John',
'country':'Sweden',
'city':'Stockholm',
'skills':['Java','C#']
}
]
return Response([Link](student_list), mimetype='application/json')
if __name__ == '__main__':
# for deployment
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)

When you request the [Link] url on the


browser you will get this:
When you request the [Link] url on the
browser you will get this:

In stead of displaying dummy data let us connect the flask application with
MongoDB and get data from mongoDB database.

# let's import the flask

from flask import Flask, Response


import json
import pymongo
app = Flask(__name__)

#
MONGODB_URI='mongodb+srv://asabeneh:your_password@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database

@[Link]('/api/v1.0/students', methods = ['GET'])


def students ():

return Response([Link](student), mimetype='application/json')

if __name__ == '__main__':
# for deployment
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)

By connecting the flask, we can fetch students collection data from the
thirty_days_of_python database.

[
{
"_id": {
"$oid": "5df68a21f106fe2d315bbc8b"
},
"name": "Asabeneh",
"country": "Finland",
"city": "Helsinki",
"age": 38
},
{
"_id": {
"$oid": "5df68a23f106fe2d315bbc8c"
},
"name": "David",
"country": "UK",
"city": "London",
"age": 34
},
{
"_id": {
"$oid": "5df68a23f106fe2d315bbc8e"
},
"name": "Sami",
"country": "Finland",
"city": "Helsinki",
"age": 25
}
]
Getting a document by id
We can access signle document using an id, let's access Asabeneh using his
id. [Link]

# let's import the flask

from flask import Flask, Response


import json
from [Link] import ObjectId
import json
from bson.json_util import dumps
import pymongo

app = Flask(__name__)

#
MONGODB_URI='mongodb+srv://asabeneh:your_password@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database

@[Link]('/api/v1.0/students', methods = ['GET'])


def students ():

return Response([Link](student), mimetype='application/json')


@[Link]('/api/v1.0/students/<id>', methods = ['GET'])
def single_student (id):
student = [Link]({'_id':ObjectId(id)})
return Response(dumps(student), mimetype='application/json')

if __name__ == '__main__':
# for deployment
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)
[
{
"_id": {
"$oid": "5df68a21f106fe2d315bbc8b"
},
"name": "Asabeneh",
"country": "Finland",
"city": "Helsinki",
"age": 38
}
]

Creating data using POST


We use the POST request method to create data
# let's import the flask

from flask import Flask, Response


import json
from [Link] import ObjectId
import json
from bson.json_util import dumps
import pymongo
from datetime import datetime

app = Flask(__name__)

#
MONGODB_URI='mongodb+srv://asabeneh:your_password@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database

@[Link]('/api/v1.0/students', methods = ['GET'])


def students ():

return Response([Link](student), mimetype='application/json')


@[Link]('/api/v1.0/students/<id>', methods = ['GET'])
def single_student (id):
student = [Link]({'_id':ObjectId(id)})
return Response(dumps(student), mimetype='application/json')
@[Link]('/api/v1.0/students', methods = ['POST'])
def create_student ():
name = [Link]['name']
country = [Link]['country']
city = [Link]['city']
skills = [Link]['skills'].split(', ')
bio = [Link]['bio']
birthyear = [Link]['birthyear']
created_at = [Link]()
student = {
'name': name,
'country': country,
'city': city,
'birthyear': birthyear,
'skills': skills,
'bio': bio,
'created_at': created_at

}
[Link].insert_one(student)
return ;
def update_student (id):
if __name__ == '__main__':
# for deployment
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)
Updating using PUT
# let's import the flask

from flask import Flask, Response


import json
from [Link] import ObjectId
import json
from bson.json_util import dumps
import pymongo
from datetime import datetime

app = Flask(__name__)

#
MONGODB_URI='mongodb+srv://asabeneh:your_password@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database

@[Link]('/api/v1.0/students', methods = ['GET'])


def students ():

return Response([Link](student), mimetype='application/json')


@[Link]('/api/v1.0/students/<id>', methods = ['GET'])
def single_student (id):
student = [Link]({'_id':ObjectId(id)})
return Response(dumps(student), mimetype='application/json')
@[Link]('/api/v1.0/students', methods = ['POST'])
def create_student ():
name = [Link]['name']
country = [Link]['country']
city = [Link]['city']
skills = [Link]['skills'].split(', ')
bio = [Link]['bio']
birthyear = [Link]['birthyear']
created_at = [Link]()
student = {
'name': name,
'country': country,
'city': city,
'birthyear': birthyear,
'skills': skills,
'bio': bio,
'created_at': created_at

}
[Link].insert_one(student)
return
@[Link]('/api/v1.0/students/<id>', methods = ['PUT']) # this decorator
create the home route
def update_student (id):
query = {"_id":ObjectId(id)}
name = [Link]['name']
country = [Link]['country']
city = [Link]['city']
skills = [Link]['skills'].split(', ')
bio = [Link]['bio']
birthyear = [Link]['birthyear']
created_at = [Link]()
student = {
'name': name,
'country': country,
'city': city,
'birthyear': birthyear,
'skills': skills,
'bio': bio,
'created_at': created_at

}
[Link].update_one(query, student)
# return Response(dumps({"result":"a new student has been created"}),
mimetype='application/json')
return
def update_student (id):
if __name__ == '__main__':
# for deployment
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)

Deleting a document using Delete


# let's import the flask

from flask import Flask, Response


import json
from [Link] import ObjectId
import json
from bson.json_util import dumps
import pymongo
from datetime import datetime

app = Flask(__name__)

#
MONGODB_URI='mongodb+srv://asabeneh:your_password@30daysofpython-
[Link]/test?retryWrites=true&w=majority'
client = [Link](MONGODB_URI)
db = client['thirty_days_of_python'] # accessing the database

@[Link]('/api/v1.0/students', methods = ['GET'])


def students ():

return Response([Link](student), mimetype='application/json')


@[Link]('/api/v1.0/students/<id>', methods = ['GET'])
def single_student (id):
student = [Link]({'_id':ObjectId(id)})
return Response(dumps(student), mimetype='application/json')
@[Link]('/api/v1.0/students', methods = ['POST'])
def create_student ():
name = [Link]['name']
country = [Link]['country']
city = [Link]['city']
skills = [Link]['skills'].split(', ')
bio = [Link]['bio']
birthyear = [Link]['birthyear']
created_at = [Link]()
student = {
'name': name,
'country': country,
'city': city,
'birthyear': birthyear,
'skills': skills,
'bio': bio,
'created_at': created_at

}
[Link].insert_one(student)
return
@[Link]('/api/v1.0/students/<id>', methods = ['PUT']) # this decorator
create the home route
def update_student (id):
query = {"_id":ObjectId(id)}
name = [Link]['name']
country = [Link]['country']
city = [Link]['city']
skills = [Link]['skills'].split(', ')
bio = [Link]['bio']
birthyear = [Link]['birthyear']
created_at = [Link]()
student = {
'name': name,
'country': country,
'city': city,
'birthyear': birthyear,
'skills': skills,
'bio': bio,
'created_at': created_at

}
[Link].update_one(query, student)
# return Response(dumps({"result":"a new student has been created"}),
mimetype='application/json')
return
@[Link]('/api/v1.0/students/<id>', methods = ['PUT']) # this decorator
create the home route
def update_student (id):
query = {"_id":ObjectId(id)}
name = [Link]['name']
country = [Link]['country']
city = [Link]['city']
skills = [Link]['skills'].split(', ')
bio = [Link]['bio']
birthyear = [Link]['birthyear']
created_at = [Link]()
student = {
'name': name,
'country': country,
'city': city,
'birthyear': birthyear,
'skills': skills,
'bio': bio,
'created_at': created_at

}
[Link].update_one(query, student)
# return Response(dumps({"result":"a new student has been created"}),
mimetype='application/json')
return ;
@[Link]('/api/v1.0/students/<id>', methods = ['DELETE'])
def delete_student (id):
[Link].delete_one({"_id":ObjectId(id)})
return
if __name__ == '__main__':
# for deployment
# to make it work for both production and development
port = int([Link]("PORT", 5000))
[Link](debug=True, host='[Link]', port=port)

💻 Exercises: Day 29
1. Implement the above example and develop this

You might also like