Python programming advanced
Contents
%%html
<!-- The customized css for the slides -->
<link rel="stylesheet" type="text/css" href="../styles/python-programming-introduction.css"/>
<link rel="stylesheet" type="text/css" href="../styles/basic.css"/>
# Install the necessary dependencies
import os
import sys
!{sys.executable} -m pip install --quiet pandas scikit-learn numpy matplotlib jupyterlab_myst ipython
43.3. Python programming advanced#
43.3.1. Table of Content#
Control flow
if
,for
,range
,while
,break
,continue
Functions
Default argument values, keyword arguments, arbitrary argument lists, unpacking argument lists
Lambda expressions, documentation strings, function annotations, function decorators
Classes
Class, object, method, inheritance, multiple inheritance
Modules
import
, Packages
Errors and exceptions
43.3.2. Control flow#
43.3.2.1. The if
statement#
Used for conditional execution
If a condition is true, we run a block of statements
There can be zero or more
elif
partsThe
else
part is optionalAn
if … elif … elif …
sequence is a substitute for the switch or case statements found in other languages
number = 15
if number < 0:
print('Number is less than zero')
elif number == 0:
print('Number equals to zero')
elif number < 1:
print('Number is greater than zero but less than one')
else:
print('Number bigger than or equal to one')
Number bigger than or equal to one
43.3.3. Control flow#
43.3.3.1. The for
statement#
Sequence: an ordered collection of items
A looping statement which iterates over a sequence of objects, i.e. go through each item in a sequence
An
else
clause is optional, when included, it is always executed once after the for loop is over unless a break statement is encountered.
words = ['cat', 'window', 'a', 'defenestrate']
for word in words:
print(len(word))
3
6
1
12
words = ['cat', 'window', 'a', 'defenestrate']
for word in words:
if len(word) == 1:
break
print(len(word))
else:
print('All words are printed!')
3
6
43.3.4. Control flow#
43.3.4.1. The for
statement#
The for
statement can be used in tandem with:
range()
: to iterate over a sequence of numbers
iterated_numbers = []
for number in range(5):
iterated_numbers.append(number)
print(iterated_numbers)
[0, 1, 2, 3, 4]
43.3.5. Control flow#
43.3.5.1. The for
statement#
The for
statement can be used in tandem with:
enumerate()
: to get a counter and the value from the iterable at the same time
words = ['Mary', 'goes', 'to', 'school']
for word_index, word in enumerate(words):
print(str(word_index) + ' ' + word)
0 Mary
1 goes
2 to
3 school
43.3.6. Control flow#
43.3.6.1. The for
statement#
The for
statement can be used in tandem with:
items()
: to loop through dictionariesthe key and corresponding value can be retrieved at the same time
student_admission = {'Ming': 'Shanghai University', 'Hong': 'Peking University'}
names = []
universities = []
for key, value in student_admission.items():
names.append(key)
universities.append(value)
print(names)
print(universities)
['Ming', 'Hong']
['Shanghai University', 'Peking University']
43.3.7. Control flow#
43.3.7.1. The while
statement#
Repeatedly executes a block of statements as long as a condition is true
True
andFalse
Any non-zero integer value is true; zero is false
number = 2
power = 5
result = 1
while power > 0: # or, while power:
result *= number
power -= 1
# 2^5 = 32
assert result == 32
43.3.8. Control flow#
43.3.8.1. The break
statement#
Breaks out of the innermost enclosing “for” or “while” loop
number_to_be_found = 42
# This variable will record how many time we've entered the "for" loop.
number_of_iterations = 0
for number in range(100):
if number == number_to_be_found:
# Break here and don't continue the loop.
break
else:
number_of_iterations += 1
assert number_of_iterations == 42
43.3.9. Control flow#
43.3.9.1. The continue
statement#
Continues with the next iteration of the loop
even_numbers = []
for number in range(0, 10):
if number % 2 == 0:
even_numbers.append(number)
continue
print(even_numbers)
[0, 2, 4, 6, 8]
43.3.10. Functions#
A function is a group of statements that exist within a program for the purpose of performing a specific task
Since the beginning of the session, we have been using a number of Python’s built-in functions, including:
len()
range()
print()
The keyword
def
introduces a function definition, which is followed by the function name and the parenthesized list of formal parameters
43.3.11. Functions#
43.3.11.1. Defining a function#
def myfunction():
print ("Printed from inside a function")
43.3.11.2. Calling the function#
myfunction()
Printed from inside a function
# Defining a function
def greet(name):
return 'Hello, ' + name
# Calling the function
print(greet('John'))
Hello, John
# Defining a function
def greet(name):
return 'Hello, ' + name
# Assign functions to variables
greet_someone = greet
# Calling the function
print(greet_someone('John'))
Hello, John
# Define functions inside other functions
def greet_again(name):
def get_message():
return 'Hello, '
result = get_message() + name
return result
print(greet_again('John'))
Hello, John
# Functions can be passed as parameters to other functions
def greet_one_more(name):
return 'Hello, ' + name
def call_func(func):
other_name = 'John'
return func(other_name)
print(call_func(greet_one_more))
Hello, John
43.3.12. Functions#
43.3.12.1. Scopes of variables inside functions#
Local variable:
Variables that are defined inside a function are considered “local” to that function
Objects outside the “scope” of the function will not be able to access that variable
Different functions can have their own local variables that use the same variable name
These local variables will not overwrite one another since they exist in different “scopes”
def count_bugs():
numbugs = 1000
print ("Shanghai has", numbugs, "bugs")
count_bugs()
Shanghai has 1000 bugs
43.3.13. Functions#
43.3.13.1. Scopes of variables inside functions#
Global Variables:
When a variable is created outside all of your functions it is considered a “global variable”
Global variables can be accessed by any statement in your program file, including by statements in any function
If you want to be able to change a global variable inside a function you must first tell Python that you wish to do this using the “global” keyword inside your function
name = 'Mary'
def show_name():
global name
print("Function 1:", name)
name = 'John'
print("Function 2:", name)
print("Before calling the function:", name)
show_name()
print("After calling the function:", name)
Before calling the function: Mary
Function 1: Mary
Function 2: John
After calling the function: John
# Passing Arguments to a function
def square(num):
print(num ** 2)
square(5)
25
# Passing Multiple Arguments to a function
def average(num1, num2, num3):
sum = num1 + num2 + num3
avg = sum / 3
print(avg)
average(2, 4, 9)
5.0
# A function can return multiple values
def myfunction():
x = 5
y = 10
return x, y
p, q = myfunction()
print(p)
print(q)
5
10
# Default argument values
def power_of(number, power=2):
""" Raises number to specific power.
You may notice that by default the function raises number to the power of two.
"""
return number ** power
print(power_of(3))
print(power_of(2, 4))
print(power_of(2, power=4))
9
16
16
# Keyword arguments
def my_function(first_name, last_name, age):
print(first_name, last_name, age)
my_function(age=22, last_name="John", first_name="James")
James John 22
# Arbitrary argument lists
def product(*numbers):
total = 1
for n in numbers:
total *= n
return total
print(product(2, 4))
print(product(3, 4))
print(product(4, 5, 2))
8
12
40
# Arbitrary argument lists with keyword arguments
def product(*numbers, initial=1):
total = initial
for n in numbers:
total *= n
return total
print(product(2, 4))
print(product(3, 4, initial=1))
print(product(4, 5, 2, initial=3))
8
12
120
43.3.14. Unpacking argument lists (*
and **
statements)#
def fun(a, b, c, d):
print(a, b, c, d)
my_list = [1, 2, 3, 4]
# This doesn't work
fun(my_list)
43.3.14.1. Code output:#
TypeError: fun()
takes exactly 4 arguments (1 given)
43.3.15. Unpacking argument lists (*
and **
statements)#
*args
(Non-keyword arguments)**kwargs
(Keyword arguments)
# Unpacking argument lists (`*` and `**` statements)
def print_four_numbers(a, b, c, d):
print(a, b, c, d)
my_list = [1, 2, 3, 4]
# Unpacking list into four arguments
print_four_numbers(*my_list)
1 2 3 4
# Unpacking argument lists (`*` and `**` statements)
def print_four_numbers(a, b, c, d):
print(a, b, c, d)
my_list = [1, 2, 3, 4, 5]
# Unpacking list into four arguments
print_four_numbers(*my_list)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_30912\2198447506.py in <module>
8 # Unpacking list into four arguments
9
---> 10 print_four_numbers(*my_list)
TypeError: print_four_numbers() takes 4 positional arguments but 5 were given
def fun(*args):
for arg in args:
print(arg)
fun('Hello', 'Welcome', 'to', 'Open', 'Academy', 'Machine', 'Learning')
Hello
Welcome
to
Open
Academy
Machine
Learning
# Unpacking argument lists (`*` and `**` statements)
def fun(a, b, c):
print(a, b, c)
d = {'a' : 2, 'b' : 4, 'c' : 10}
fun(**d)
2 4 10
# Unpacking argument lists (`*` and `**` statements)
def fun(first_word, second_word):
return first_word + ', ' + second_word + '!'
dict_1 = {'first_word': 'Hello', 'second_word': 'World'}
print(fun(**dict_1))
dict_2 = {'second_word': 'World', 'first_word': 'Hello'}
print(fun(**dict_2))
Hello, World!
Hello, World!
# Lambda expressions
x = lambda a : a + 10
print(x(5))
15
# Lambda expressions
x = lambda a, b : a * b
print(x(5, 6))
30
# Lambda expressions
pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
pairs.sort(key=lambda pair: pair[1])
print(pairs)
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
# Using lambda() Function with filter()
# Example 1: Filter out all odd numbers using filter() and lambda function
li = [5, 7, 22, 97, 54, 62, 77, 23, 73, 61]
final_list = list(filter(lambda x: (x % 2 != 0), li))
print(final_list)
[5, 7, 97, 77, 23, 73, 61]
# Using lambda() Function with filter()
# Example 1: Example 2: Filter all people having age more than 18, using lambda and filter() function
ages = [13, 90, 17, 59, 21, 60, 5]
adults = list(filter(lambda age: age > 18, ages))
print(adults)
[90, 59, 21, 60]
# Using lambda() Function with map()
# Example 1: Multiply all elements of a list by 2 using lambda and map() function
li = [5, 7, 22, 97, 54]
final_list = list(map(lambda x: x * 2, li))
print(final_list)
[10, 14, 44, 194, 108]
# Using lambda() Function with map()
# Example 2: Transform all elements of a list to upper case using lambda and map() function
animals = ['dog', 'cat', 'parrot', 'rabbit']
uppered_animals = list(map(lambda animal: animal.upper(), animals))
print(uppered_animals)
['DOG', 'CAT', 'PARROT', 'RABBIT']
43.3.16. Functions#
43.3.16.1. Documentation strings (docstring)#
“Code is more often read than written.”
— Guido van Rossum
A docstring is a string literal that occurs as the first statement in a module, function, class, or method definition.
Such a docstring becomes the
__doc__
special attribute of that object.
# Documentation strings
def square(n):
'''Takes in a number n, returns the square of n'''
return n**2
print(square.__doc__)
Takes in a number n, returns the square of n
# Documentation strings
print(print.__doc__)
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.
# Documentation strings
import pickle
print(pickle.__doc__)
Create portable serialized representations of Python objects.
See module copyreg for a mechanism for registering custom picklers.
See module pickletools source for extensive comments.
Classes:
Pickler
Unpickler
Functions:
dump(object, file)
dumps(object) -> string
load(file) -> object
loads(string) -> object
Misc variables:
__version__
format_version
compatible_formats
help(print)
Help on built-in function print in module builtins:
print(...)
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.
43.3.17. Functions#
43.3.17.1. Function annotations#
Function annotations are completely optional metadata information about the types used by user-defined functions.
# Function annotations
def breakfast(ham: str, eggs: str = 'eggs') -> str:
return ham + ' and ' + eggs
print(breakfast.__annotations__)
{'ham': <class 'str'>, 'eggs': <class 'str'>, 'return': <class 'str'>}
43.3.18. Functions#
43.3.18.1. Function decorators#
Wrappers to existing functions
Dynamically alter the functionality of a function
Ideal when you need to extend the functionality of functions that you don’t want to modify
# Function decorators
def greeting(name):
return "Hello, {0}!".format(name)
def decorate_with_p(func):
def function_wrapper(name):
return "<p>{0}</p>".format(func(name))
return function_wrapper
my_get_text = decorate_with_p(greeting)
print(greeting('John'))
print(my_get_text('John'))
Hello, John!
<p>Hello, John!</p>
# Function decorators
def decorate_with_p(func):
def function_wrapper(name):
return "<p>{0}</p>".format(func(name))
return function_wrapper
@decorate_with_p
def greeting(name):
return "Hello, {0}!".format(name)
print(greeting('John'))
<p>Hello, John!</p>
# Function decorators
def decorate_with_div(func):
def function_wrapper(text):
return "<div>{0}</div>".format(func(text))
return function_wrapper
@decorate_with_div
def greeting(name):
return "Hello, {0}!".format(name)
print(greeting('John'))
@decorate_with_div
@decorate_with_p
def greeting(name):
return "Hello, {0}!".format(name)
print(greeting('John'))
<div>Hello, John!</div>
<div><p>Hello, John!</p></div>
43.3.19. Classes#
To group data and functions belonging together to form custom data types
A Class is like an object constructor or a “blueprint” for creating objects
# Classes
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def say_hello(self):
print("Hello my name is " + self.name + ", I am " + str(self.age) + " years old.")
p1 = Person("John", 36)
p1.say_hello()
p2 = Person("Mary", 25)
p2.say_hello()
p1.age = 39
p1.say_hello()
Hello my name is John, I am 36 years old.
Hello my name is Mary, I am 25 years old.
Hello my name is John, I am 39 years old.
43.3.20. Classes#
43.3.20.1. Inheritance#
Allows a derived class to reuse the same code and modify it accordingly
Derived classes may override methods of their base classes.
# Inheritance
class Person:
def __init__(self, name):
self.name = name
def get_name(self):
return self.name
class Employee(Person):
def __init__(self, name, staff_id):
Person.__init__(self, name) # super().__init__(name)
self.staff_id = staff_id
def get_full_id(self):
return self.get_name() + ', ' + self.staff_id
employee = Employee('John', 'A23')
print(employee.get_full_id())
John, A23
# Multiple inheritance
class Clock:
time = '11:23 PM'
def get_time(self):
return self.time
class Calendar:
date = '12/08/2018'
def get_date(self):
return self.date
class CalendarClock(Clock, Calendar):
pass
calendar_clock = CalendarClock()
print(calendar_clock.get_date())
print(calendar_clock.get_time())
12/08/2018
11:23 PM
43.3.21. Modules#
As your program gets longer, you may want to split it into several files for easier maintenance
Python has a way to put definitions in a file and use them in a script or in an interactive instance of the interpreter
Such a file is called a module
A module is a file containing Python definitions and statements
A Package is a way of structuring Python’s module namespace by using “dotted module names”
# Modules
import sys
sys.path
['C:\\Users\\lunde\\PycharmProjects\\machine-learning-ocademy-ai\\open-machine-learning-jupyter-book\\slides\\python-programming',
'd:\\programs\\python3_7_4\\python37.zip',
'd:\\programs\\python3_7_4\\DLLs',
'd:\\programs\\python3_7_4\\lib',
'd:\\programs\\python3_7_4',
'',
'C:\\Users\\lunde\\AppData\\Roaming\\Python\\Python37\\site-packages',
'd:\\programs\\python3_7_4\\lib\\site-packages',
'd:\\programs\\python3_7_4\\lib\\site-packages\\docloud-1.0.257-py3.7.egg',
'd:\\programs\\python3_7_4\\lib\\site-packages\\win32',
'd:\\programs\\python3_7_4\\lib\\site-packages\\win32\\lib',
'd:\\programs\\python3_7_4\\lib\\site-packages\\Pythonwin',
'C:\\Users\\lunde\\AppData\\Roaming\\Python\\Python37\\site-packages\\IPython\\extensions',
'C:\\Users\\lunde\\.ipython']
# Packages
# import only pi from math module
from math import pi
print("The value of pi is", pi)
The value of pi is 3.141592653589793
# Packages
# import all names from the standard module math
from math import *
print("The value of pi is", pi)
print("The value of sin(pi) is", sin(pi))
The value of pi is 3.141592653589793
The value of sin(pi) is 1.2246467991473532e-16
43.3.22. Let’s try with our own module#
We write those code into the file my_module.py
:
def my_sum(a, b):
return a + b
%%writefile my_module.py
def my_sum(a, b):
return a + b
Writing my_module.py
from my_module import my_sum
print(my_sum(3, 5))
8
!rm my_module.py
43.3.23. Errors and exceptions#
Even if a statement or expression is syntactically correct, it may cause an error when an attempt is made to execute it
Errors detected during execution are called exceptions and are not unconditionally fatal
try:
result = 10 * (1 / 0) # division by zero
print("Result: ", result)
except ZeroDivisionError:
print("Error: division by zero")
Error: division by zero
try:
result = 10
print("Result: ", result)
result += 'a'
print("Result: ", result)
except ZeroDivisionError:
print("Error: division by zero")
except:
# We should get here because of division by zero.
print("Error: unexpected error")
Result: 10
Error: unexpected error
43.3.24. Your turn! 🚀#
Practice the Python programming (advanced) by following the assignment
43.3.25. References:#
https://www.geeksforgeeks.org/packing-and-unpacking-arguments-in-python/
https://cs.nyu.edu/courses/summer16/CSCI-UA.0002-002/slides/Python_Functions.pdf
https://moodle2.units.it/pluginfile.php/375147/mod_resource/content/2/python_3_2021.pdf
https://www.geeksforgeeks.org/python-lambda-anonymous-functions-filter-map-reduce/