Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 760

Introduction to Python

Carlo Lisi
CAATTs Team

1
GETTING STARTED

2
Overview
 Navigate to the sections below by clicking on the links
 Introduction to Python
 VARIABLES
 STRINGS
 List and Tuples
 Decimal module
 Fractions Module
 SETS
 Python IF ELSE
 Python Loops
 Dictionaries
 Python File I/O
 Python Directory and Files Management
 Python Errors and Built-in Exceptions
 Python Functions
 Python Custom Exceptions

3
Overview (cont)
 Python Namespace and Scope
 Python Objects and Class
 Class Inheritance
 Multiple Inheritance
 Operator Overloading
 DATE TIME
 Iterators
 Generators
 Closures
 Decorators
 @property
 Review Questions
 FINAL EXAM
 Quiz Solutions

4
What is Python
 Executive Summary
 Python is an interpreted, object-oriented, high-level programming
language with dynamic semantics
 Its high-level built in data structures, combined with dynamic
typing and dynamic binding, make it very attractive for Rapid
Application Development, as well as for use as a scripting or glue
language to connect existing components together
 Python's simple, easy to learn syntax emphasizes readability
and therefore reduces the cost of program maintenance
 Python supports modules and packages, which encourages program
modularity and code reuse
 The Python interpreter and the extensive standard library are
available in source or binary form without charge for all major
platforms, and can be freely distributed

5
History of Python
 Python is a very new language; in fact it was released by its
designer, Guido Van Rossum, in February 1991 while working for
CWI also known as Stichting Mathematisch Centrum
 Many of Python's features originated from an interpreted language
called ABC (I’ve never used ABC)
 Rossum wanted to correct some of ABC's problems and keep some
of its features
 At the time he was working on the Amoeba distributed operating
system group and was looking for a scripting language with a
syntax like ABC but with the access to the Amoeba system calls, so
he decided to create a language that was generally extensible
 Since he had some experience with using Modula-2+, he decided to
talk with the designers of Modula-3. Modula-3 is the origin of the
syntax and semantics used for exceptions, and some other Python
features
 In 1989, during the Christmas holidays, he decided to give it a try
and design a language which he later called Python
6
History of Python(cont)
 Just in case you're wondering how the language got its name, well
it's not from those dangerous reptiles
 Python actually got is name from a BBC comedy series from the
seventies "Monty Python's Flying Circus“
 The designer needed a name that was short, unique, and slightly
mysterious
 Since he was a fan of the show, he thought this name was great
 Guido Van Rossum

7
Zen of Python

 Type import this


into your terminal

8
Where to get Python
 You can get Python from www.python.org
 Latest version is 3.9
 For this course we will use Python 3

 Python has been packaged and available from the order desk

9
Python Distributions
 One of the most popular distributions of Python is Anaconda
 Anaconda comes with over 400 python modules pre-installed so
you don’t have to load them in yourself
 Anaconda distribution can be obtained at
 https://www.anaconda.com/download/

10
Anaconda
 Anaconda distribution comes with the Spyder IDE (my favorite)
 Screenshot below

11
Other IDEs
 There are many IDEs useful for Python
 Pycharm (not my favourite)
 WingIDE
 Eclipse
 Thonny

 You can find more of them at


 https://wiki.python.org/moin/IntegratedDevelopmentEnvironments

 The IDE that comes with Python distribution from www.python.org


is the IDLE – it’s pretty good
 For this course, feel free to use the IDE you prefer

12
WinPython
 Another distribution is winpython from source forge
 winpython is another distribution that is completely self-contained
 It can be downloaded at http://winpython.github.io/#releases
 It also comes with the Spyder IDE

 winpython does not require administrative privileges to


install
13
Programming Basics
 code or source code: The sequence of instructions in a program.

 syntax: The set of legal structures and commands that can be


used in a particular programming language

 output: The messages printed to the user by a program

 console: The text box onto which output is printed


 Some source code editors pop up the console as an external window,
and others contain their own console window

14
Compiling and Interpreting
 Many languages require you to compile (translate) your program
into a form that the machine understands
compile execute
source code byte code output
Hello.java Hello.class

 Python is instead directly interpreted into machine instructions

interpret
source code output
Hello.py

15
Math Commands
 Python has useful commands for performing calculations.
Command name Description Constant Description
abs(value) absolute value e 2.7182818...
ceil(value) rounds up pi 3.1415926...
cos(value) cosine, in radians
floor(value) rounds down
log(value) logarithm, base e
log10(value) logarithm, base 10
max(value1, value2) larger of two values
min(value1, value2) smaller of two values
round(value) nearest whole number
sin(value) sine, in radians

To use many of these


 sqrt(value) squarecommands,
root you must write the following at
the top of your Python program:
from math import *
Note: it’s not always advisable to import everything that
comes with a package
16
Python Data Types

17
EXPRESSIONS, VARIABLES AND
ASSIGNMENTS

 Let’s start with something familiar


 We will use the Python IDE interactive shell as a calculator to
evaluate Python expressions, starting with simple algebraic
expressions
 Our goal is to illustrate how Python is intuitive and usually behaves
the way you would expect
 Algebraic Expressions and Functions
 At the interactive shell prompt
 >>> , we type an algebraic expression, such as 3 + 7, and hit the
Enter key on the keyboard to view the result of evaluating the
expression:
 3+7
 10

18
EXPRESSIONS, VARIABLES AND
ASSIGNMENTS
 Let’s try expressions that use different algebraic operators:
 3*2
 6
 5/2
 2.5
 4/2
 2.0
 In the first expression, integers are added or multiplied, and the result is
an integer, which is what you expect
 In the second expression, an integer is divided by another and the result is
shown in decimal point notation
 This is because when an integer is divided by another, the result is not
necessarily an integer
 The rule in Python is to return a number with a decimal point and a
fractional part, even when the result is an integer
 This is illustrated in the last expression, where integer 4 is divided by 2
and the result shown is 2.0 rather than 2

19
EXPRESSIONS, VARIABLES AND
ASSIGNMENTS
 Values without the decimal point are said to be of type integer or
simply int
 Values with decimal points and fractional parts are said to be of
type floating point or simply float
 Let look at evaluating expressions using values of both types:
 2*3+1
 7
 (3 + 1) * 3
 12
 4.321 / 3 + 10
 11.440333333333333
 4.321 / (3 + 10)
 0.3323846153846154
 Multiple operators are used in these expressions, standard algebra
precedence rules apply in Python (BEDMAS or PEDMAS)

20
EXPRESSIONS, VARIABLES AND
ASSIGNMENTS
 BEDMAS/PEDMAS (order of operations)
 Brackets/Parenthesis Division and Multiplication
 Exponents have the same
precedence
 Division
Same for Multiplication
 Multiplication and Division.
 Addition PEDMAS is easier to
 Subtraction remember 
 The two types of number values, int and float, have somewhat
different properties
 For example, when two int values are added, subtracted, or
multiplied, the result is an int value
 If at least one float value appears in the expression, however, the
result is always a float value
 Note that a float value is also obtained when two integer values
(e.g., 4 and 2) are divided (Python 3, Python 2 will give you an
integer)
21
EXPRESSIONS, VARIABLES AND
ASSIGNMENTS
 Operator Precedence (Python)
Operator Precedence

Order Operators Description


1 () Parentheses
2 ** Exponent
3 -x, +x Unary minus or Unary plus
4 *,/,//,% Multiplication,division,floor division,modulus
5 +,- Addition or subtraction
 Operators with same precedence are solved by their associativity
order
Associativity Operators Example
Left-to-right (), **, *, /, //, %, +, – 5%2 =1
Right-to-left ** 2**2**3 = 256
 This means that any expression will follow this order for resolution
 First, the order in the Operator Precedence table, then by their
associativity order

22
EXPRESSIONS, VARIABLES AND
ASSIGNMENTS
 Self-Increment (unary + , unary – and others)
 With Python, it is necessary to increment a variable
 There is a small shortcut to perform this using the operators seen
before
 The shortcut operations and their representation are shown below

Self Increment

Operator Example Equivalent Expression

+= x+=2 x=x+2

-= x-=1 x=x-1

*= x*=2 x=x*2

"/=" x/=2 x=x/2

%/ x%/2 x=x%2

23
EXPRESSIONS, VARIABLES AND
ASSIGNMENTS
 Exponentiation is done using **
 So, 2 to the power of 4, i.e., 2^4(not with Python) is
2**4(Python)
 In order to obtain the integer quotient and the remainder when two
integer values are divided, operators // and % are used
 The // operator in expression a//b returns the integer
quotient obtained when integer a is divided by integer b
 The % operator in expression a%b computes the remainder
obtained when integer a is divided by integer b
 For example, 14//3 is 4 because 3 goes into 14 , 4 times
 14%3 is 2 because the remainder dividing 3 into 14 is 2
 Python also supports mathematical functions of the kind you have
used in an algebra class
 Recall that, in algebra, the notation f(x) = x + 1
 is used to define function f() that takes an input, denoted by x,
and returns a value, which is x + 1 in this case
24
EXPRESSIONS, VARIABLES AND
ASSIGNMENTS
 In order to use this function on input value 3, for example, you
would use the notation f(3), which evaluates to 4
 Python functions are similar
 For example, the Python function abs() can be used to
 compute the absolute value of a number value:
 abs(-4)
 4
 abs(4)
 4
 abs(-3.2)
 3.2

25
EXPRESSIONS, VARIABLES AND
ASSIGNMENTS
 Some other functions that Python makes available are min() and
max(), which return the minimum or maximum, respectively, of
the input values

 min(6, -2)
 -2
 max(6, -2)
 6
 min(2, -4, 6, -2)
 -4
 max(12, 26.5, 3.5)
 26.5
 For a fun exercise write the code to find these in another
programming language you used to use

26
EXPRESSIONS, VARIABLES AND
ASSIGNMENTS
 Boolean Expressions and Operators
 Algebraic expressions evaluate to a number, whether of type int or
float or one of the other number types that Python supports
 In algebra class, expressions other than algebraic expressions are
also common
 For example, the expression 2 < 3 does not evaluate to a
number; it evaluates to either True or False (True in this
case)
 Comparison operators (such as < or >) are commonly used
operators in Boolean expressions
 For example: 2 < 3 returns
 True
 3 < 2 returns
 False
 5 - 1 > 2 + 1 returns
 True
27
EXPRESSIONS, VARIABLES AND
ASSIGNMENTS
 The previous expression illustrates that algebraic expressions on
either side of a comparison operators are evaluated before the
comparison is made
 Algebraic operators take precedence over comparison operators
 In order to check equality between values, the comparison operator
== is used (two equal signs side by side)
 3 == 3 returns True
 3 + 5 == 4 + 4 returns True
 3 == 5 - 3 returns False

28
EXPRESSIONS, VARIABLES AND
ASSIGNMENTS
 There are a few other logical comparison operators:
 3 <= 4 returns True
 3 >= 4 returns False
 3 != 4 (!= means not equal to) returns True

 Boolean expressions can be combined using Boolean operators


and , or , and not to form larger Boolean expressions

 The and operator applied to two Boolean expressions will evaluate


to True if both expressions evaluate to True; if either expression
evaluates to False, then it will evaluate to False

29
EXPRESSIONS, VARIABLES AND
ASSIGNMENTS
 2 < 3 and 4 > 5 returns False
 2 < 3 and True returns True

 The not operator is a unary Boolean operator, which means that it


is applied to a single Boolean expression
 not (3 < 4) returns False
 Boolean Algebra

Boolean Algebra is the algebra of values true and false. Boolean algebra includes opeators and, or, and not which can be used to create
Boolean expressions, expressions that evaluae to true or false. Here are the truth tables below

p q p and q p q p or q p not p
TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
TRUE FALSE FALSE TRUE FALSE TRUE FALSE TRUE
FALSE TRUE FALSE FALSE TRUE TRUE
FALSE FALSE FALSE FALSE FALSE FALSE

30
EXPRESSIONS, VARIABLES AND
ASSIGNMENTS
 You can do mathematical operations on Booleans (oh yes you can)
 Operations between bool and int/float are automatically converted
to the numeric type (int/float) in which True is 1 and False is 0
 Example:
 Type the following into your Python console
 1 + True
 False + True
 2*True

31
Quiz 0

32
Quiz 0
 1. Which is the correct operator for performing the
mathematical operation of X to the power of y?
 A X^y
 B X^^y
 C X**y
 D A and C
 E None of the above

 2. Which one of these is floor division?


 A /
 B //
 C %
 D A and B
 E None of the above

33
Quiz 0
 3. What is the order of precedence in python?
 i Parentheses
 ii Exponential
 iii Multiplication
 iv Division
 v Addition
 vi Subtraction

 A i,ii,iii,iv,v,vi
 B ii,i,iii,iv,v,vi
 C vi,v,iv,iii,ii,i
 D A,B
 E A, B, C
 E None of the above

34
Quiz 0
 4. What is answer of this expression, 22 % 3 is?
 A 7
 B 1
 C 0
 D 5

 5. Mathematical operations can be performed on a string.


State whether true or false
 A True
 B False

35
Quiz 0
 6. Operators with the same precedence are evaluated in
which manner?
 A Left to Right
 B Right to Left
 C Doesn’t matter
 D None of the above

 7. What is the output of this expression, 3*1**3?


 A 1
 B 9
 C 27
 D 3
 E error

36
Quiz 0
 8. Which one of the following have the same precedence?
 A Addition and Subtraction
 B Multiplication and Division
 C Exponentiation and division
 D Brackets and Division
 E A and B
 F A, B, C and D

 9. The expression int(False) is converted to an integer.


State whether True or False

 A True
 B False

37
Quiz 0
 10. Which one of the following have the highest precedence
in an algebraic expression?

 A Multiplication
 B Addition
 C Parenthesis
 D Division
 E All the above have the same precedence

38
VARIABLES

39
Variables
 We know from algebra that is useful to assign names to variables
 We can assign 3 to x by x = 3
 The same can be done with Python
 Type x =3 in the Python console
 print(x)
 The statement x = 3 is an assignment statement
 General format is
 <variable> = <expression>
 Once a value has been assigned to a variable, the variable can be
used in a Python expression
 Type 4*x*x in the Python Console
 An expression involving variables may appear on the right side of
an assignment statement

40
Variables(cont)
 In statement counter = 4 * x, x is first evaluated to 3, then the
expression 4 * 3 is evaluated to 12, and then 12 gets assigned to
variable counter
 So far, we have defined two variable names: x with value 4 and
counter with value 12
 What about, say, the value of variable z that has not been assigned
yet?
 Type z into the console
 z
 Traceback (most recent call last):

 File "<ipython-input-22-a8a78d0ff555>", line 1, in <module>


 z

 NameError: name 'z' is not defined

41
Variables(cont)
 It turns out that if a variable—z in this case—has not been assigned
a value, it just does not exist

 When Python tries to evaluate an unassigned name, an error will


occur and a message (such as name 'z' is not defined) is printed
out

 You may remember from algebra that the value of a variable can
change
 The same is true with Python variables
 For example, suppose that the value of variable x is initially 4
 We can change x to 7 by assigning 7 to x
 Type x = 7 into the console
 print(x) will output 7

42
Variables(cont)
 Assignment and Equality Operators !
 Be careful to distinguish the assignment statement = and the
equality operator ==
 This is an assignment statement that assigns 7 to variable
 x=7
 The following, however, is a Boolean expression that compares the
value of variable x with number 7 and returns True if they are
equal:
 x == 7 will return True if x has been assigned 7
 The expression evaluates to True because variable x has value 7.

43
Variable Names
 Variable Names
 The characters making up a variable name can be lowercase and
uppercase letters from the alphabet (a through z and A through Z),
the underscore character (_), and, except for the first character,
digits 0 through 9:
 myList and _list are OK, but 5list is not
 list6 and l_2 are OK, but list-3 is not
 mylist and myList are different variable names – Python is case
sensitive !!!
 Even when a variable name is “legal” (i.e., follows the rules), it
might not be a “good” name
 Here are some generally accepted conventions for designing good
names

44
Naming Variables Convention
 A name should be meaningful: Name price is better than name p
(this is my opinion)
 For a multiple-word name, use either the underscore as the
delimiter (e.g., temp_var and interest_rate) or camelCase
capitalization (e.g., tempVar, interestRate) or PascalCase (TempVar,
InterestRate); pick one style and use it consistently throughout
your code
 Shorter meaningful names are better than longer ones (again -
that’s my opinion)
 Names below are reserved keywords of the Python Language
 You can not use them as names of variables

45
ID Function
 id() function in Python
 Introduction
 id() is an inbuilt function in Python.
 Syntax:
 id(object)
 The function accepts a single parameter and is used to return the
identity of an object
 This identity must be unique and constant for this object during the
lifetime
 Two objects with non-overlapping lifetimes may have the same id()
value
 If we relate this to the C programming language, then they are
actually the memory address, here in Python it is the unique
id

46
ID Function(cont)
 The output is the identity of the object passed
 This is random but when running in the same program, it
generates unique and same identity

 str1 = “hello"
 print(id(str1))

 str2 = “hello"
 print(id(str2))

 # This will return True


 print(id(str1) == id(str2))

 “hello” is the object and


 str1, str2, are the references to it
47
PEP8 Standard
 PEP-8 or the Python Enhancement Proposal presents some of
the key points that you can use to make your code more organized
and readable

 As Python creator Guido Van Rossum says:

 The code is read much more often than it is written

 The Python programming language has evolved over time as one of


the most popular programming languages

 Python language is relatively easy to learn than most other


programming languages (I know this is debatable)

48
PEP8 Standard(cont)
 The naming conventions of Python's library are a bit of a mess, and
will never be completely consistent

 However, here are the currently recommended naming standards

 New modules and packages (including third party) should be


written to these standards, but where an existing library has a
different style, internal consistency is preferred

49
PEP8 Standard(cont)
 Descriptive: Naming Styles
 There are a lot of different naming styles
 It helps to be able to recognize what naming style is being used,
independently from what they are used for

 The following naming styles are commonly distinguished:


 b (single lowercase letter)
 B (single uppercase letter)
 lowercase
 lower_case_with_underscores
 UPPERCASE
 UPPER_CASE_WITH_UNDERSCORES

50
PEP8 Standard(cont)
 CapitalizedWords (or CapWords, or CamelCase -- so named
because of the bumpy look of its letters)

 This is also sometimes known as StudlyCaps

 Note: When using acronyms in CapWords, capitalize all the letters


of the acronym  Thus HTTPServerError is better than
HttpServerError

 mixedCase (differs from CapitalizedWords by initial lowercase


character!)
 i.e., captializedWords

51
PEP8 Standard(cont)
 Prescriptive: Naming Conventions
 Names to Avoid
 Never use the characters 'l' (lowercase letter el), 'O' (uppercase
letter oh), or 'I' (uppercase letter eye) as single character variable
names
 With some fonts, these characters are indistinguishable from the
numerals one and zero
 When tempted to use ‘l’ (lowercase letter el), use 'L' instead
 Package and Module Names
 Modules should have short, all-lowercase names
 Underscores can be used in the module name if it improves
readability
 Python packages should also have short, all-lowercase names,
although the use of underscores is discouraged

52
PEP8 Standard(cont)
 Variable and Function Names
 Function names should be lowercase, with words separated by
underscores as necessary to improve readability
 mixedCase is allowed only in contexts where that's already the
prevailing style

 Variables
 Use the function naming rules ; lowercase with words separated by
underscores as necessary to improve readability

53
Quiz 1

54
Quiz 1
 1. In Python, a variable must be declared before it is
assigned a value:

 A True

 B False

55
Quiz 1
 2. Which of the following statements (there might be more
than one) assigns the value 100 to the variable x in Python:

 A x ← 100

 B x = 100

 C x := 100

 D x << 100

 E let x = 100

56
Quiz 1
 3. In Python, a variable may be assigned a value of one
type, and then later assigned a value of a different type:

 A False

 B True

57
Quiz 1
 4. Consider the following sequence of statements:
 n = 500
 m=n
 Following execution of these statements, Python has created how
many objects and how many references?

 A Two objects, two references


 B One object, one reference
 C One object, two references
 D Two objects, one reference
 E None of the above

58
Quiz 1
 5. What Python built-in function returns the unique
identifier assigned to an object:

 A identity()

 B id()

 C refnum()

 D ref()

59
Quiz 1
 6. Which of the following are valid Python variable names:
 Select all that apply

 A. 4square

 B. home_address

 C. return

 D. ver1.3

 E. route66

 F. Age

60
Quiz 1
 7. You are reading Python code, and these statements
appear scattered in different locations throughout the code:
 vendornumber = 00050

 VendorNumber = 00050

 vendorNumber = 00050

 Choose the correct statement below

 A These statements refer to different variables.

 B These statements refer to the same variable.

61
Quiz 1
 8. Which of the following is false about naming styles from
PEP8 (there may be more than one)

 A Function names should be lowercase, with words separated


by underscores as necessary to improve readability

 B mixedCase is allowed only in contexts where that's already


the prevailing style (e.g., threading.py), to retain backwards
compatibility

 C Modules should have short, all-lowercase names ,


underscores are not allowed

 D Lower case L and/or lower case I are encouraged to be used

62
Quiz 1
 9. Which of the following are Python reserved words
(keywords) (there may be more than one)?

 A None

 B and

 C default

 D goto

 E class

63
Quiz 1
 10. PEP 8 recommends that all python package names be
lower case

 A True
 B False

64
STRINGS

65
Strings
 Strings
 In addition to number and Boolean types, Python supports a large
number of other, more complex, types
 The Python string type, denoted str, is used to represent and
manipulate text data or, in other words, a sequence of characters,
including blanks, punctuation, and various symbols
 A string value is represented as a sequence of characters that is
enclosed within quotes Warning: Python will let you
 s = ‘hello’ or assign a value to str, i.e.,
 s = “hello” str=1
 String Operators Never assign anything to str
 Python provides operators to process text (i.e., string values)
 Like numbers, strings can be compared using comparison
operators: ==, !=, < , >, and so on
 Operator ==, for example, returns True if the strings on either side
of the operator have the same value
66
Strings(cont)
 s == 'hello’ returns True
 t = 'world’
 s != t returns True
 s == t return False

 While == and != test whether or not two strings are equal, the
comparison operators < and > compare strings using the dictionary
order:
 s < t returns True
 s > t returns False
 The + operator, when applied to two strings, evaluates to a new
string that is the concatenation (i.e., the joining) of the two strings
 s + t returns 'helloworld’
 s + ' ' + t returns 'hello world'

67
Strings(cont)
 If we can add two strings, can we, perhaps, multiply them?
 'hello ' * 'world’
 If you type this into the Python Console, you will get the following
result
 'hello' *'world’

 Traceback (most recent call last):

 File "<ipython-input-26-ea581ed49756>", line 1, in <module>


 'hello' *'world'

 TypeError: can't multiply sequence by non-int of type 'str'

68
Strings(cont)
 Well . . . it doesn’t look like we can
 If you take a moment and think about it, it is not really clear what
multiplying two strings would mean anyway

 Adding them (i.e., concatenating them) makes more sense


 Overall, the design of the Python programming language and the
meaning of the standard operators (+, *, /, etc.) for various types
of values (integer, floating point, Boolean, string, etc.) is intuitive
 So, intuitively, what do you think should happen when a string gets
multiplied by an integer?

 Type 3*’A’ into the Python Console


 3*’A’
 returns 'AAA’

69
Strings(cont)
 hello ' * 2 returns 'hello hello ‘
 30 * '-’ returns '------------------------------’
 Multiplying a string s by an integer k gives us a string obtained by
concatenating k copies of string s
 Note how we easily obtained a line (useful for presenting your
simple text output, say) by multiplying string '-' 30 times.
 Another useful operator is the ‘in’ operator
 With the in operator, we can check whether a character appears in
a string
 s = 'hello’
 'h' in s returns True
 'g' in s returns False
 ‘car’ in ‘carmichael’ returns True
 Class Question : What about ‘Car’ in ‘Carmichael’? What is
returned?

70
Strings(cont)
 Below are some string operators with usage and explanation

 s = ‘hello’
 s[0] = ‘h’ (python indexing starts at 0 unlike R which starts at 1)
 The length of a string can be computed using the len() function
 len(s) returns 5

71
Strings(cont)
 Indexing Operator
 The individual characters of a string can be accessed using the
indexing operator []
 We define the concept of an index first
 The index of a character in a string is the character’s offset (i.e.,
position in the string) with respect to the first character
 The first character has index 0, the second has index 1 (because it
is one away from the first character), the third character has index
2, and so on
 The indexing operator [] takes a nonnegative index i and returns a
string consisting of the single character at index i
 s[0] returns 'h’
 s[1] returns 'e’
 s[4] returns 'o'

72
Strings(cont)

73
Strings(cont)
 Negative indexes may be used to access the characters from the
back (right side) of the string
 For example, the last character and second to last can be retrieved
using negative indexes −1 and −2, respectively
 s[-1] returns 'o’
 s[-2] returns 'l’

74
Strings(cont)
 I have only scratched the surface of the text-processing capabilities
of Python
 There is much more you can do with strings
 Class Question:
 What would s[1:3] return?
 Type s[1:3] into the console
 This returns string ‘el’ : you get the starting index, everything in
between but not the end index, in this case 3
 If you want to remove leading and trailing spaces in a string, use
the strip method
 s=“ hello “
 s.strip() return “hello”
 Class Question:
 What would s[2:2] return? Why do you get this result?
 Now let's move to other Python string functions

75
Strings(cont)
 Class Questions:

 What does s[-1] return?

 What does s[-2:-1] return?

 How about s[-4:] ?

 How do I return the last three letters?

76
Strings(cont)
 Now you might be thinking, if I can slice a string, can I use that to
change a character of a string?
 Execute the code below
 s = ‘hello’
 print(s)

 Can we change “o” to the letter “b” using indexing?


 Type this into your python console
 s[-1] =‘b’

77
Strings(cont)
 The error message “’str’ object doesn’t support item assignment” is
telling us that you can’t use slicing to make changes to a string
 Later in the course I will show you how to do this after we finish
with lists
 For now, we will have to do it manually, by retyping s as ‘hellb’ ,
i.e., s =‘hellb’
 strings are immutable in python, i.e., they can’t be changed

78
Strings(cont)
 rfind method
 Description:
 The method rfind() returns the last index where the substring
substr is found, or -1 if no such index exists, optionally restricting
the search to string[beg:end]
 Syntax
 Following is the syntax for rfind() method
 str.rfind(substr, beg=0 end=len(string))
 Parameters
 substr − This specifies the string/substring to be searched
 beg − This is the starting index, by default its 0
 end − This is the ending index, by default its equal to the length of
the string
 Return Value
 This method returns last index if found and -1 otherwise.

79
Strings(cont)
str1 = "this is really cool"

str2 = "is"

print (str1.rfind(str2))

print (str1.rfind(str2, 0, 10))

print (str1.rfind(str2, 10, 15))

#output is -1, because “is” is not between the 10th and 15th
characters.

80
Strings(cont)
 Class Exercise
 1.
 str1 =‘Topology’
 print(str1.rfind(“og”))
 print(str1.rfind(“y”))

 2.
 type dir(str1) in your console
 Look for the dunder method __len__
 What do you think str1.__len__() will output
 Type into the console and see what happens

81
Strings(cont)

82
Strings(cont)
 Python String replace() Method
 Description
 The method replace() returns a copy of the string in which the
occurrences of old have been replaced with new, optionally
restricting the number of replacements to max

 Syntax
 Following is the syntax for replace() method
 str.replace(old, new[, max])

 Parameters
 old − This is old substring to be replaced
 new − This is new substring, which would replace old substring
 max − If this optional argument max is given, only the first max
count occurrences are replaced

83
Strings(cont)
 Example:
 str1 = "Hello World"
 print(str1.replace("l","s",1)) #replace first l
 print(str1.replace("l","s",2)) #replace first two l’s
 print(str1.replace("l","s",3)) #replace first three l’s
 print(str1.replace("World","Python"))

84
Strings(cont)
 Python String join() Method
 Description
 The method join() returns a string in which the string elements of
sequence have been joined by str separator
 Syntax
 Following is the syntax for join() method −
 str.join(sequence)

 Parameters
 sequence − This is a sequence of the elements to be joined.
 Return Value
 This method returns a string, which is the concatenation of the
strings in the sequence seq
 The separator between elements is the string providing this
method.

85
Strings(cont)
 Example
 sep = "-"
 mystrings = ["a", "b", "c"]

 # This is list of mystrings


 print (sep.join( mystrings ))
 #Another way
 print("-".join(mystrings))

 Class Exercise:
 What should use for sep if we want no spaces between the letters
“a”, “b” and “c”?

86
Strings(cont)
 Let’s look at some other string functions
 Python string method center() returns a centered string of length
width with padding being done with specified fillchar
 Default filler is a space
 Syntax
 str1.center(width[, fillchar]) where str1 is a string

 Parameters:

 width − This is the total width of the string


 fillchar − This is the filler character

 If the width is less than the length of the str, the str will be the
output

87
Strings(cont)
 Example:
 str = "this is string”
 str.center(5,*)
The string str has 14
characters including
spaces
Five (5) is less than 14
so the original str is
returned
 Let's try
 str.center(20,*)

The padding is as
symmetrical as possible

88
Strings(cont)
 Class Exercise
 str.center(21,”*”)

 Another string function which is really useful is split()


 We will cover Python lists later in the course

 Example
 str1 = “Python is really cool”
 str1.split()

89
Strings(cont)
 Python String capitalize() method returns a copy of the string
with only its first character capitalized
 Syntax
 str1.capitalize()
 There are no inputs
 Example:
 str1 =‘this is my string’
 str1.capitalize()

 Class Exercise:
 Do this with str1=‘this is my STRING’
 What happens?
90
Strings(cont)
 Class Exercise – Lets see what happens with directory paths

 s =‘C:/Users/python’
 print(s)

 s =‘C:\\Users\\python’
 print(s)

 What is the print statement doing to the extra back-slashes?

 Class Exercise - Reversing a string

 s=‘python is the best’


 print(s[::-1])
 What is this doing?
91
Strings(cont)
 Class Exercise

 Using the “\n”


 str =‘hello \n world’
 print(str)
 What is the “\n” doing
 print(“\n Hello World”)

92
Strings(cont)
 Python Raw String
 Let's say we want to print a string “Hello \n World”

 If we run the code below:

 print(“Hello\nWorld”)
 we will get Hello , a blank line and the word “Hello”

 What can we do if we want “Hello\nWorld” as the output?

 Python offers you an option if you just want the raw string

93
String(cont)
 If you put the character R or r before the string, it will print the
raw string
 Example
 print(r’Hello \n World’)

 Try
 print(“C:\Users\Python”)

 Now Try
 print(R”C:\Users\Python”)

94
Quiz 2

95
Quiz 2
 1. Which of the following is the output of the below Python
code?

 str=‘Moon Light'
 str[4]='-'
 print (str)

 A Moo- Light
 B Moon-Light
 C 'str' object does not support item assignment
 D Moon Light
 E None of the above

96
Quiz 2
 2. Which of the following is the output of the below Python
code?

 str='Hello World’
 print (str.replace('l','n',2))

 A Hello World
 B Helno World
 C Henno Wornd
 D Henno World
 E None of the above

97
Quiz 2
 3. Which of the following statements can be used to return
the length of the given String, mystr? (There might be more
than one)

 A mystr._len_()
 B size(mystr)
 C len(mtstr)
 D mystr.size()
 E None of the above

98
Quiz 2
 4. Which of the answers would print the output as given
below? (there may be more than one)
 C:\Common\TestString.doc

 A
 str='C:\\Common\TestString.doc'
 print (str)
 B
 str='C:\\Commo\n\TestSt\ring.doc'
 print (str)
 C
 str='C:\Common\TestStri\ng.doc'
 print (str)
 D
 str='''C:\\Common\TestString.doc'''
 print (str)

99
Quiz 2
 5. What is the output when following statement is
executed?

 print (‘Hell' + ‘Boy’)

 A Hell
 B Boy
 C HellBoy
 D Hell Boy
 E None of the above

100
Quiz 2
 6. What is the output when following code will be executed?

 str='Recurssion'
 print (str.rfind('s’))

 A 6
 B 2
 C 4
 D 5
 E None of the above

101
Quiz 2
 7. Which of the following is the output of the below Python
code?

 str='example'
 print (str.center(2,'*’))

 A m
 B example
 C *example*
 D Error will be generated
 E None of the above

102
Quiz 2
 8. Which of the following operators can be used with
Strings?

 a) +
 b) *
 c) -
 d) in

 A a, b
 B a, b, d
 C a, b, c
 D a, b, c, d
 E None of the above

103
Quiz 2
 9. What is the output when following statement is
executed?

 print (‘Hello’ ‘World’)

 A Hello
 B World
 C HelloWorld
 D Hello World
 E Error

104
Quiz 2
 10. What is the output when following statement is
executed?

 str='good-BYE'
 print (str.capitalize())

 A GOOD-BYE
 B Good-Bye
 C Good-bye
 D GOOD-bye
 E None of the above

105
Quiz 2
 11. What is the output when following statement is
executed?

 print (’Hello\nWorld’)

 A ‘Hello' then ‘World’ in a New line


 B ‘rHello' then ‘World' in a New line
 C Hello World
 D Hello\nWorld
 E None of the above

106
Quiz 2
 12. Which of the following is the output of the below Python
code?

 str=‘Moon Beam'
 print (str[::-1])

 A maeBnooM
 B maeB nooM
 C Moon Beam
 D Moon
 E Beam

107
List and Tuples

108
List and Tuples
 Lists and Tuples
 In many situations we organize data into a list - a shopping list, a
list of courses, a list of contacts on your cell phone, a list of songs
in your audio player, and so on
 In Python, lists are usually stored in a type of object called a list
 A list is a sequence of objects
 The objects can be of any type- numbers, strings, even other lists
For example, here is how we would assign to the variable pets the
list of strings representing several pets
 pets = ['goldfish', 'cat', 'dog’]

109
List and Tuples(cont)
 In Python, a list is represented as a comma-separated sequence of
objects enclosed within square brackets
 An empty list is represented as []
 Lists can contain items of different types
 For example, the list named things, things = ['one', 2, [3, 4]] has
three items: the first is string 'one', the second is integer 2, and
the third item is list [3, 4]
 List Operators
 Most of the string operators we have used can be used on lists in
similar ways
 For example, the items in the list may be accessed individually
using the indexing operator, just as individual characters can be
accessed in a string

110
List and Tuples(cont)
 pets[0] returns 'goldfish’ and
 pets[2] return 'dog’
 Negative indexes can be used too
 pets[-1] returns 'dog’

111
List and Tuples(cont)
 Following is a set of list operators and functions

 Try some of these,


 ‘x’ in [‘x’,’y’,’abc’] returns true
 [‘1’,’2’,’3’] + [1,2,3] returns [‘1’,’2’,’3’,1,2,3]

112
List and Tuples(cont)
 Like strings, lists can be “added,” meaning that they can be
concatenated
 They can also be “multiplied” by an integer k, which means that k
copies of the list are concatenated
 pets + pets returns ['goldfish', 'cat', 'dog', 'goldfish', 'cat', 'dog’]
 pets * 2 returns ['goldfish', 'cat', 'dog', 'goldfish', 'cat', 'dog’]

 If you want to check whether string 'rabbit' is in the list, you can
use the in operator in a Boolean expression that evaluates to True if
string 'rabbit' appears in list pets

 'rabbit' in pets returns False


 'dog' in pets return True

113
List and Tuples(cont)
 Functions min(), max(), and sum(), which can take a list as input
and return the smallest item, the largest item, or the sum of the
items, respectively, in the list
 lst = [8, 12, 34, 120]
 min(lst) returns 8
 max(lst) returns 120
 sum(lst) returns 174
 Lists Are Mutable, Strings Are Not

 An important property of lists is that they are mutable


 What this means is that the content of a list can be changed
 For example, suppose that we want to be more specific about the
type of cat in list pets
 We would like pets[1] to evaluate to 'cymric cat' instead of just
plain 'cat’

114
List and Tuples(cont)
 To do this, we assign 'cymric cat' to pets[1]
 pets[1] = ‘cymric cat’
 pets returns ['goldfish', 'cymric cat', 'dog’]

 So, the list no longer contains the string 'cat' at index 1; instead, it
contains the string 'cymric cat’
 While lists are mutable, strings are not
 What that means is that we cannot change the individual
characters of a string value
 For example, suppose that we misspelled the type of cat
 myCat = 'cymric bat'

115
List and Tuples(cont)
 Try to correct the mistake by changing the character at index 7
from 'b' to a 'c’
 myCat[7] = ‘c’
 Traceback (most recent call last):
 File "<ipython-input-39-396d887ac518>", line 1, in <module>
 myCat[7] ='c'

 TypeError: 'str' object does not support item assignment


 The error message essentially says that individual characters
(items) of a string cannot be changed (assigned to)
 Strings are immutable
 Does that mean that we are stuck with a misspelled value for
myCat?
 We can simply reassign a brand-new value to variable myCat, i.e.,
myCat = 'cymric cat'

116
List and Tuples(cont)
 In addition to lists, Python also supports tuples which, in many
ways, behave like lists except that tuples are immutable
 A tuple object contains a sequence of values separated by commas
and enclosed in parentheses (( )) instead of brackets ([ ])

 days = ('Mo', 'Tu', 'We’)


 print(days) outputs (‘Mo’,’Tu’,’We’)

 The parentheses are optional in simple expressions like this


assignment
 days = 'Mo', 'Tu', 'We', 'Th’
 print(days) output ('Mo', 'Tu', 'We', 'Th’)
 My preference is with the brackets

117
List and Tuples(cont)
 The operators we used on lists can be used on tuples
 Example
 days = (‘Mo’,’Tu’,’We’)
 ‘Fr’ in days outputs False
 Concatenating on tuples
 days + (‘Th’,’Fr’,’Sa’,’Su’)
 outputs (‘Mo’,’Tu’,’We’,Th’,’Fr’,’Sa’,’Su’)
 Using index, we can access the elements of a tuple
 Example
 days[0]
 output ‘Mo’
 any attempt to change a tuple results in an error:
 days[4] = ‘xy’
 will result in an error

118
List and Tuples(cont)
 So, as in lists, items in tuples are ordered and can be accessed
using an index (offset)
 Unlike lists, tuples are immutable: once a tuple is created, it cannot
be changed
 Remember – With python, indexing starts at zero

 What about a one item tuple? Can we do this?

 Suppose we need to create a one-item tuple, such as


 days = ('Mo')
 Let’s evaluate the value and type of the object days:
 print(days) outputs 'Mo’
 type(days) outputs <class 'str’>
 What happened? It appears the parenthesis were ignored

119
List and Tuples(cont)
 Even if we used a numeric, the same would happen
 For example
 t = (3)
 print(t) outputs 3
 type(t)
 outputs int
 How do we create a one element tuple?
 What differentiates the parentheses in a general tuple from
parentheses in an expression is that enclosed in the tuple
parentheses will be comma-separated items
 So, the commas make the difference, and all we need to do is add
a comma after the first, and only, item to get a one-item tuple
object:
 days = ('Mo’,)
 print(days) outputs (‘Mo’,)
 type(days) outputs tuple
120
List and Tuple methods
 List and Tuple Methods
 We have seen functions that operate on lists such as, for example,
the min() function:
 numbers = [6, 9, 4, 22]
 min(numbers)
 outputs 4

 In expression min(numbers), we say that function min() is called


with one input argument, the list numbers
 There are also functions called on lists
 For example, the append function
 Example
 lst =[‘a’,’b’,’c’]
 lst.append(‘d’) outputs [‘a’,’b’,’c’,’d’]
 We can do this again, lst.append[‘e’] outputs [‘a’,’b’,’c’,’d’,’e’]

121
List and Tuple methods(cont)
 Note how the way append was called

 For example
 lst.append(‘d’) should be interpreted as follows
 Apply the function append is called on the list with the input ‘d’

122
List and Tuple methods(cont)
 The effect of executing the statement lst.append(‘d') is
 that the input argument ‘d' is added at the end of list lst
 **Important**
 The function append() is a list function
 What this means is that function append() cannot be called on its
own; it always has to be called on some list, lst, using the notation
lst.append()
 We will refer to such functions as methods
 Another example of a list method is the count() method
 When called on a list with an input argument, it returns the number
of times the input argument appears in the list
 Example
 lst = [‘a’,’a’,’a’,’b’,’b’,’c’]
 lst.count(‘a’) outputs 3

123
List and Tuple methods(cont)
 The list method reverse() reverses the order of the objects
 Example
 lst = [1,2,3,4,5]
 lst.reverse()
 print(lst)
 outputs [5,4,3,2,1]
 You can view a listing of all list methods in the interactive shell
using the help() documentation function
 The sort() method sorts the items in the list in increasing order,
using the ordering that “naturally” applies to the objects in the list
 Example
 pets =[‘dog’,’cat’,’goldfish’,’guinea pig’]
 pets.sort()
 pets
 outputs ['cat', 'dog', 'goldfish', 'guinea pig’]

124
List and Tuple methods(cont)
 A list of numbers would be sorted using the usual increasing
number order:
 lst = [4,2,8,5]
 lst.sort()
 lst outputs [2,4,5,8]
 If you want to sort descending, use lst.sort(reverse = True)
 lst.sort(reverse = True)
 lst outputs [8,5,4,2]

 Question: what happens if you try to sort a list with letters and
numbers?
 lst = [‘a’,’b’,’c’,1,2,3]
 lst.sort() outputs an error

125
List and Tuple methods(cont)
 Class Exercise:
 What happens if you sort a list with numbers represented by
strings?
 lst = [‘1’,’a’,’g’,’2’,’3’,’z’]
 Type lst.sort() and see what you get
 Try it again with lst =[’23’,’45’,’100’, ‘apple’,’pear’,’strawberry’]
 How is Python sorting the list?

 Example:
 Using the lst.insert() method?
 lst = [‘1’,’a’,’g’,’2’,’3’,’z’]
 Replace g with the t
 Now g occupied the second index of the lst
 lst.insert(2,”t”)
 g will be replaced with t
126
List and Tuple methods(cont)
 Extend method
 The method extend() appends the contents of a sequence to a list
 Syntax
 Following is the syntax for extend() method −
 list.extend(sequence)
 Parameters
 sequence − a list to add
 This method adds content to an existing list
 Example:
 List1 = [‘abc’,’123’]
 List2 = [4,5,6, ‘hello’];
 List1.extend(List2)
 print ("Extended List : ", List1 )

127
Append vs Extend
 So, what is the difference between the methods extend and append
 append: Appends object at the end

 a = [1, 2, 3]
 a.append([4, 5])
 print (a)
 Output is [1, 2, 3, [4, 5]]

 extend: Extends list by appending elements from the iterable


 a = [1, 2, 3]
 a.extend([4, 5])
 print (a)
 Output is [1, 2, 3, 4, 5]

128
List Comprehension
 List comprehension is powerful and must know the concept in
Python
 Mastering this concept would help you in two ways

 You would start writing shorter and effective codes


 Hence, your code will execute faster
 List Comprehensions are 35% faster than FOR loop and 45% faster
than map function?
 Let’s look at some examples:

 1. [x**2 for x in range(0,10)]


 2. [x for x in range(1,20) if x%2==0 ]
 3. [x for x in 'MATHEMATICS' if x in ['A','E','I','O','U']]

129
List Comprehension(cont)
 [x**2 for x in range(0,10)]

 This will output a list of the numbers squared from 0 to 9


(remember python does include the number of the right)
 You can type [x**2 for x in range(0,10)] in your python console
and run it

 Type list(range(0,10)) in your python console


 Without a list comprehension, how would you do this?
 You could use a for loop (I know we haven’t covered this yet)

 z =[] # initialize a blank list


 for j in range(0,10):
 z.append(j**2) # oh yes, indenting is important(that’s how
python knows that z.append(j**2) belongs to the loop)

130
List Comprehension(cont)
 If you are familiar with Python 2’s filter, map, reduce, lambda
functions, you could use the map function
 lambda functions are anonymous functions – don’t need to give
them a name
 z = list(range(0,10))
 list(map(lambda x:x**2, a))

 lambda x:x**2 is an anonymous function which squares a number


input
 Equivalent to
 def squared_num(x):
 return x**2

 In my opinion, list comprehension is easier to use

131
List Comprehension(cont)
 Let’s look at the second example:
 [x for x in range(1,20) if x%2==0 ]

 This will output numbers from 1 to 19 that are divisible by 2

 Try typing [x for x in range(1,20) if x%2==0 ] into your console


and run it

 As an exercise you can try to do with it a loop and conditionals


(we’ll cover this later in the course)

 If you were using Python 2, we would need to use the filter


function

 z = list(range(1,20))
 list(filter(lambda x: x%2,z))
132
List Comprehension(cont)
 Last example:
 [x for x in 'MATHEMATICS' if x in ['A','E','I','O','U’]]
 This will output all the vowels (you remember the song for vowels
right?, a,e,i,o,u and sometimes y ) in the word ‘MATHEMATICS’
 Type [x for x in 'MATHEMATICS' if x in ['A','E','I','O','U’]] in your
python console

 Homework exercise, try doing with filter or with a loop and if


conditional (you can wait until we cover loops in the course)

 Can comprehensions get complicated?


 You bet they can

133
List Comprehension(cont)
 Class Exercise:
 What does this list comprehension output?
 [(x,y,z) for x in range(1,30) for y in range(x,30) for z in
range(y,30) if x**2 + y**2 == z**2]

 Remember , Pythagorean theorem?


 x**2 + y**2 = z**2 (sides of a right-angled triangle?)

 Output will be the set of Pythagorean triples for integers between 1


and 30
134
List Comprehension(cont)
 Solution to the exercise
 Run the code in your console
 [(x,y,z) for x in range(1,30) for y in range(x,30) for z in
range(y,30) if x**2 + y**2 == z**2]

135
List Comprehension(cont)
 Before going to the quiz, I want to present a method that you will
most likely use with lists and it’s called the pop() method
 The pop() method removes the item at the given index from the
list and returns the removed item
 The syntax of the pop() method is:
 list.pop(index)

 Example:
 myarray=[1,2,3,4,5]
 myarray.pop()
 output is 5
 print(myarray)
 If no index is provided, pop() will remove the last element in the
list and the list is changed

136
List Comprehension(cont)
 Example

 myarray = [1,2,3,4,5,6,7,8]

 print(myarray.pop(0))
 print(myarray.pop(1))
 print(myarray.pop(2))
 print(myarray)

137
Quiz 3

138
Quiz 3
 1. What will be the output of the following code snippet?
 a=[1,2,3,4,5,6,7,8,9]
 print(a[::2])

 A [1,2]
 B [8,9]
 C [1,3,5,7,9]
 D [1,2,3]
 E None of the above

139
Quiz 3
 2. What will be the output of the following code snippet?
 a=[1,2,3,4,5]
 print(a[3:0:-1])

 A Syntax error
 B [4, 3, 2]
 C [4, 3]
 D [4, 3, 2, 1]
 E None of the above

140
Quiz 3
 3. What will be the output of the following code snippet?
 arr = [[1, 2, 3, 4],
 [4, 5, 6, 7],
 [8, 9, 10, 11],
 [12, 13, 14, 15]]
 print(arr[0].pop())
 print(arr[1].pop())
 print(arr[2].pop())
 print(arr[3].pop())

 A 1234
 B 1 4 8 12
 C 4 7 11 15
 D 12,13,14,15

141
Quiz 3
 4. What will be the output of the following code snippet?
 init_tuple = ()
 print (init_tuple.__len__())
 Hint # remember what dunder methods do

 A None
 B 1
 C 0
 D Exception
 E None of the above

142
Quiz 3
 5. What will be the output of the following code snippet?
 init_tuple_a = 'a', 'b'
 init_tuple_b = ('a', 'b')

 print (init_tuple_a == init_tuple_b)

 A 0
 B 1
 C False
 D True
 E None of the above

143
Quiz 3
 6. What will be the output of the following code snippet?
 init_tuple_a = '1', '2'
 init_tuple_b = ('3', '4')

 print (init_tuple_a + init_tuple_b)

 A (1, 2, 3, 4)
 B (‘1’, ‘2’, ‘3’, ‘4’)
 C [‘1’, ‘2’, ‘3’, ‘4’]
 D None

144
Quiz 3
 7. What will be the output of the following code snippet?
 init_tuple = (1,) * 3

 init_tuple[0] = 2

 print(init_tuple)

 A (1, 1, 1)
 B (2, 2, 2)
 C (2, 1, 1)
 D TypeError: ‘tuple’ object does not support item assignment

145
Quiz 3
 8. Which of the following statements given below is/are
true? (there may be more than one)

 A Tuples and lists have order (order matters)


 B Tuples are homogeneous, lists are heterogeneous
 C Tuples are immutable, lists are mutable
 D B and C
 E None of the above

146
Quiz 3
 9. What is the output of the following code snippet?
 [x**2 for x in (0,1,2,3,4,5)]

 A syntax error
 B {0 ,1,4,9,16,25}
 C [0,2,4,6,8,10]
 D [0,1,4,9,16,26]
 E None of the above

147
Quiz 3
 10. What is the output of the following code snippet?
 A =[1,8,5,3,2,0]
 print(A.pop(0))
 print(A.pop(0))

 A 8,5
 B 1,8
 C 2,0
 D 3,2
 E None of the above

148
Python Decimal Module

14
Decimal module(cont)
 Decimal “is based on a floating-point model which was designed
with people in mind, and has a paramount guiding principle –
computers must provide an arithmetic that works in the same way
as the arithmetic that people learn at school
 Decimal numbers can be represented exactly
 In contrast, numbers like 1.1 and 2.2 do not have exact
representations in binary floating point
 End users typically would not expect 1.1 + 2.2 to display as
3.3000000000000003 as it does with binary floating point
 The exactness carries over into arithmetic
 In decimal floating point, 0.1 + 0.1 + 0.1 - 0.3 is exactly equal to
zero
 In binary floating point, the result is 5.5511151231257827e-
017, although this is very close to zero, it’s not actually zero so
comparisons will fail

150
Decimal module
 If you want floating point calculations to display properly,
calculations to be precise so that comparisons can be performed
then use the decimal package
 a = 0.1
 b = 0.2
 a +b outputs 0.30000000000000004
 Why does this happen?
 Representation error refers to the fact that some (most,
actually) decimal fractions cannot be represented exactly as binary
(base 2) fractions
 This is the main reason why Python (or Perl, C, C++, Java, Fortran,
and many others) often won’t display the exact decimal number
you expect

151
Decimal Module(cont)
 Binary Fractions
 If you are not familiar how binary fractions work, see below
 They are very similar to base 10 (the one that we are used to)
 Let’s compare base 10 to base 2

 This is how computers store integer numbers internally


 And for fractional numbers in positional notation, they do the same
thing:

152
Decimal Module(cont)
 Problems
 While they work the same in principle, binary fractions are
different from decimal fractions in what numbers they can
accurately represent with a given number of digits, and thus also in
what numbers result in rounding errors:
 Specifically, binary can only represent those numbers as a finite
fraction where the denominator is a power of 2
 Unfortunately, this does not include most of the numbers that can
be represented as finite fraction in base 10, like 0.1

153
Decimal Module(cont)
 And this is how you already get a rounding error when you just
write down a number like 0.1 and run it through your interpreter or
compiler

 It’s not as big as 3/80 and may be invisible because computers cut
off after 23 or 52 binary digits rather than 4

 But the error is there and will cause problems eventually if you just
ignore it

154
Decimal Module(cont)
 Why use Binary?
 At the lowest level, computers are based on billions of electrical
elements that have only two states, (usually low and high
voltage)
 By interpreting these two states as 0 and 1, it’s very easy to build
circuits for storing binary numbers and doing calculations with
them
 While it’s possible to simulate the behaviour of decimal numbers
with binary circuits as well, it’s less efficient
 If computers used decimal numbers internally, they’d have
less memory and be slower at the same level of technology
 Since the difference in behaviour between binary and decimal
numbers is not important for most applications, the logical choice
is to build computers based on binary numbers and live with the
fact that some extra care and effort are necessary for applications
that require decimal-like behaviour

155
Decimal Module(cont)
 Let’s see a sample of decimal module in action
 The Python decimal module incorporates a notion of significant
places so that 1.30 + 1.20 is 2.50
 The trailing zero is kept to indicate significance
 The decimal module has a user alterable precision (defaulting to
28 places) which can be as large as needed for a given problem
 To use the decimal module, you will need to import it
 import decimal
 To create a decimal type object, use the Decimal() constructor
 from decimal import *
 Let’s try a calculation with a precision of 5
 getcontext().prec = 5
 Decimal(1)/Decimal(7) outputs Decimal(‘0.14286’)

156
PopQuiz Decimals
 1. What is the output of the following code snippet?
 from decimal import getcontext, Decimal
 getcontext().prec = 1
 Decimal(0.1) + Decimal(0.2)

 A Decimal(‘0.30’)
 B 0.3000000004
 C Decimal(‘0.300’)
 D Decimal(‘0.3’)
 E None of the above

157
PopQuiz Decimals
 2. What is the output of the following code snippet?
 from decimal import getcontext, Decimal
 getcontext().prec = 2
 Decimal(‘0.10’) + Decimal(‘0.20’)

 A Decimal(‘0.30’)
 B ‘0.30’
 C Decimal(0.300)
 D Decimal(‘0.21’)
 E None of the above

158
Python Fractions Module

15
Fractions Module
 Guess what?
 There is a module called fractions in python
 The fractions module makes available a new type of number: the
Fraction type
 The Fraction type is used to represent fractions and do rational
arithmetic, such as: ½ + ¾ = 5/4
 To use the fractions module, you need to import it,
 import fractions
 To create a fractions object, use the Fraction() constructor
 To add ½ + ¾
 a = fractions.Fraction(1,2)
 b = fractions.Fraction(3,4)
 We can a and b
 c = a + b outputs Fraction(5,4) not 1.25

160
Fractions Module(cont)
 Note that fractions.Fraction(5,4) does not evaluate to 1.25
 fractions.Fraction will convert a decimal to a fraction
 Examples:
 fractions.Fraction(4.5) will output Fraction(9,2)
 fractions.Fraction(0.5) will output Fraction(1,2)

 What is the difference between the float type and the


fractions ,Fraction type?
 Float values are stored in the computer using a limited number of
bits, typically 64 of them
 That means that the range of values that float objects can store is
limited
 For example, try 0.5**2000 will output 0, however
 fractions.Fraction(1,2) **2000 will output

161
Fractions Module(cont)
 Fraction(1,
114813069527425452423283320117768198402231770208869520
047764273682576626139237031385665948631650626991844596
463898746277344711896086305533142593135616665318539129
989145312280000688779148240044871428926990063486244781
615463646388363947317026040466353970904996558162398808
944629605623311649536164221970332681344168908984458505
602379484807914058900934776500429002716706625830522008
132236281291761267883317206598995396418127021779858404
042159853183251540889433902091920554957783589672039160
081957216630582755380425583726015528348786419432054508
915275783882625175435528800822842770817965453762184851
149029376)

162
Fractions Module(cont)
 Why not always use the fractions.Fraction type?

 Because expressions involving float values evaluate much, much


faster than expressions involving fractions.Fraction values

163
PopQuiz Fractions
 1. What is the output of the following code snippet?
 from fractions import Fraction
 print(Fraction(2.5))
 print(Fraction(1.75))

 A Fraction(5,2)
 Fraction(9,4)

 B Fraction(2.5)
 Fraction(1.75)

 C 5/2
 7/4

 D None of the above



164
PopQuiz Fractions
 2. What is the output of the following code snippet?
 from fractions import Fraction
 print(Fraction(2.2) + Fraction(2.3))

 A Fraction(9,2)
 B Fraction(18,4)
 C Fraction(4.5)
 D Fraction(7,2)
 E 9/2

165
SETS

16
Python Sets
 Python Sets

 A set is an unordered collection of items


 Every element is unique (no duplicates) and must be immutable
(which cannot be changed)
 However, the set itself is mutable
 We can add or remove items from it
 Sets can be used to perform mathematical set operations like
union, intersection, symmetric difference etc.…

167
Python Sets(cont)
 How to create a set?
 A set is created by placing all the items (elements) inside curly
braces {}, separated by comma or by using the built-in function
set()
 It can have any number of items and they may be of different
types (integer, float, tuple, string etc.)
 But a set cannot have a mutable element, like list, set or dictionary,
as its element (we’ll talk about dictionaries later in this tutorial)
 Example
 # set of integers
 my_set = {1, 2, 3}
 print(my_set)
 #Example(myset1.py)
 # set of mixed data types my
 my_set = {1.0, "Hello", (1, 2, 3)}
 print(my_set)
168
Python Sets(cont)

169
Python Sets(cont)
 Try this example
 # sets do not have duplicates
 my_set = {1,2,3,4,3,2}
 print(my_set)
 # set cannot have mutable items
 # here [3, 4] is a mutable list
 # If you uncomment line #
 ,# this will cause an error.
 '#my_set = {1, 2, [3, 4]}
 # TypeError: unhashable type: 'list'#my_set = {1, 2, [3, 4]}
 # we can make set from a list
 my_set = set([1,2,3,2])
 print(my_set)

170
Python Sets(cont)
 Creating an empty set is a bit tricky
 Empty curly braces {} will make an empty dictionary in Python
 To make a set without any elements we use the set() function
without any argument
 empty_set = set()
 Example
 # initialize a with {}
 a = {}
 # check data type of a
 print(type(a))
 # initialize a with set()
 a = set()
 # check data type of a
 print(type(a))

171
Python Sets(cont)
 Here is the output

172
Python Sets(cont)
 How to change a set in Python?
 Sets are mutable
 But since they are unordered, indexing has no meaning
 We cannot access or change an element of set using indexing or
slicing
 Set does not support it (no indexing allowed)
 We can add single element using the add() method and multiple
elements using the update() method
 The update() method can take tuples, lists, strings or other sets as
its argument
 In all cases, duplicates are avoided

173
Python Sets(cont)
 Example
 # initialize my_set
 my_set = {1,3}
 print(my_set)
 #my_set[0]
 # add an element
 my_set.add(2)
 print(my_set)
 # add multiple elements
 my_set.update([2,3,4])
 print(my_set)
 # add list and set
 my_set.update([4,5], {1,6,8})
 print(my_set)

174
Python Sets(cont)

175
Python Sets(cont)
 How to remove elements from a set?
 A particular item can be removed from set using methods,
discard() and remove()
 The only difference between the two is that, while using discard() if
the item does not exist in the set, it remains unchanged
 But remove() will raise an error in such condition

 Example
 my_set = {1,2,3}
 my_set.discard(2)
 print(my_set)
 my_set = {1,2,3}
 my_set.remove(2)
 print(my_set)
 print(my_set.discard(0))
 print(my_set.remove(0))

176
Python Sets(cont)
 Similarly, we can remove and return an item using the pop()
method (like with lists)
 But sets being unordered, there is no way of determining which
item will be popped
 It is completely arbitrary

 We can also remove all items from a set using clear()


 Example
 my_set ={1,2,3,4}
 my_set.pop()
 print(my_set)
 my_set.clear()
 print(my_set)

177
Python Set Operations
 Python Set Operations
 Sets can be used to carry out mathematical set operations like
union, intersection, difference and symmetric difference
 We can do this with operators or methods
 Let us consider the following two sets for the following operations
 A = {1, 2, 3, 4, 5}
 B = {4, 5, 6, 7, 8}

178
Python Set Operations(cont)
 Union of A and B is a set of all elements from both sets
 Union is performed using | operator
 Same can be accomplished using the method union()
 Example (type into Python console)
 # initialize A and B
 A = {1, 2, 3, 4, 5}
 B = {4, 5, 6, 7, 8}
 # use | operator
 print(A | B)
 # use union method
 A.union(B)
 B.union(A)

179
Python Set Operations(cont)
 Set Intersection

 Set intersection is performed using & operator


 Same can be accomplished using the method intersection()

180
Python Set Operations(cont)
 Example (Type in python console)
 # initialize A and B
 A = {1, 2, 3, 4, 5}
 B = {4, 5, 6, 7, 8}
 # use & operator
 print(A & B)
 #use intersection function on A
 A.intersection(B)
 # use intersection function on B
 B.intersection(A)
 #output {4, 5}

181
Python Set Operations(cont)
 Set Difference

182
Python Set Operations(cont)
 Difference is performed using – operator
 Same can be accomplished using the method difference()
 Example
 # initialize A and B
 A = {1, 2, 3, 4, 5}
 B = {4, 5, 6, 7, 8}
 # use - operator on A
 print(A - B)
 #use difference function on A
 A.difference(B)
 # use - operator on B
 B-A
 # use difference function on B
 B.difference(A)

183
Python Set Operations(cont)
 Set Symmetric Difference

 Symmetric difference is performed using ^ operator


 Same can be accomplished using the method
symmetric_difference()

184
Python Set Operations(cont)
 Example
 # initialize A and B
 A = {1, 2, 3, 4, 5}
 B = {4, 5, 6, 7, 8}
 # use ^ operator
 print(A ^ B)
 #use symmetric_difference function on A
 A.symmetric_difference(B)
 {1, 2, 3, 6, 7, 8}

 # use symmetric_difference function on B


 B.symmetric_difference(A)
 {1, 2, 3, 6, 7, 8}

185
Python Set Methods

186
Python Set Methods(cont)

187
Other Set Operations
 Set Membership Test
 We can test if an item exists in a set or not, using the keyword in
 Example(Type in python console)
 # initialize my_set
 my_set = set("apple")
 # check if 'a' is present
 # Output: True
 print('a' in my_set)
 # check if 'p' is present
 # Output: False
 print('p' not in my_set)

188
Other Set Operations(cont)
 Iterating Through a Set
 Using a for loop, we can iterate though each item in a set

 Example
 for letter in set("apple"):
 print(letter)

189
Frozenset
 Python Frozenset
 Frozenset is a new class that has the characteristics of a set, but
its elements cannot be changed once assigned
 While tuples are immutable lists, frozensets are immutable sets
 Sets being mutable are unhashable, so they can't be used as
dictionary keys
 On the other hand, frozensets are hashable and can be used as
keys to a dictionary
 Frozensets can be created using the function frozenset()
 Example
 # initialize A and B
 A = frozenset([1, 2, 3, 4])
 B = frozenset([3, 4, 5, 6])

190
Frozenset(cont)
 This datatype supports methods like copy(), difference(),
intersection(), isdisjoint(), issubset(), issuperset(),
symmetric_difference() and union()
 Being immutable it does not have method that add or remove
elements
 Let’s try some
 A.isdisjoint(B)
 #output is false
 A.issubset(B)
 #output is false
 A.issuperset(B)
 #output is false
 A.union(B)
 #output is frozenset({1, 2, 3, 4, 5, 6})
 A.symmetric_difference(B)
 #ouput is frozenset({1, 2, 5, 6})

191
Hashable
 An aside here, as you will be seeing this a lot with Python
 Hashable:
 From the Python glossary:
 An object is hashable if it has a hash value which never changes
during its lifetime (it needs a __hash__() method), and can be
compared to other objects (it needs an __eq__() or __cmp__()
method)
 Hashable objects which compare equal must have the same hash
value
 Hash-ability makes an object usable as a dictionary key and a set
member, because these data structures use the hash value
internally
 All of Python’s immutable built-in objects are hashable, while no
mutable containers (such as lists or dictionaries) are
 Objects which are instances of user-defined classes are hashable by
default; they all compare unequal, and their hash value is their id()
192
Hashable
 Alright, you must be wondering what that means
 In simpler terms
 Anything that is not mutable (mutable means, likely to change)
can be hashed
 You can test any python object by using the hash function
 Example
 s =[1,2,3]
 t = (1,2,3)
 print(hash(t))
 print(hash(s))

193
Hashable
 Type these into your python console
 x = hash(set([1,2])) #set unhashable
 x = hash(frozenset([1,2])) #hashable
 x = hash(([1,2], [2,3])) #tuple of mutable objects, unhashable
 x = hash((1,2,3)) #tuple of immutable objects, hashable
 x = hash({1,2}) #list of mutable objects, unhashable
 x = hash([1,2,3]) #list of immutable objects, unhashable

 List of immutable types:


 int, float, decimal, complex, bool, string, tuple, range, frozenset,
bytes

 List of mutable types:


 list, dict, set, bytearray, user-defined classes

194
Quiz 4

195
Quiz 4
 1. Which of the following about a set is not true?

 A Mutable data type


 B Does not support Indexing
 C Allows duplicate values
 D Data type with unordered values
 E Immutable data type

 2. Which of the following is not the correct syntax for


creating a set?
 A set([[1,2],[3,4]])
 B set([1,2,2,3,4])
 C set((1,2,3,4))
 D {1,2,3,4}

196
Quiz 4
 3. What is the output of the following code?

 nums = set([1,1,2,3,3,3,4,4])
 print(len(nums))

 A. 7
 B. Error, invalid syntax for formation of set
 C. 4
 D. 8
 E. None of the above

197
Quiz 4
 4. Which of the following statements is used to create an
empty set? (there may be more than one)

 A {}
 B set()
 C []
 D ()
 E All of the above

198
Quiz 4
 5. What is the output of the following piece of code when
executed in the python shell?
 a={6,7}
 b={1,2,6,7}
 print(a.issubset(b))

 A {1,2}
 B True
 C False
 D Invalid operation

199
Quiz 4
 6. If a={5,6,7,8}, which of the following statements can be
executed without an error

 A print(len(a))
 B print(min(a))
 C a.remove(5)
 D a[2]=45
 E All of the above will execute with no error

200
Quiz 4
 7. What is the output of the following code?
 a={4,5,6}
 b={2,8,6}
 a+b

 A {4,5,6,2,8}
 B {4,5,6,2,8,6}
 C Error as unsupported operand type for sets
 D Error as the duplicate item 6 is present in both sets
 E {6,13,12}

201
Quiz 4
 8. If a={5,6,7} , what happens when a.add(5) is executed?

 A a={5,5,6,7}
 B a={5,6,7}
 C Error as there is no add function for set data type
 D Error as 5 already exists in the set
 E. [{5,6,7}]

202
Quiz 4
 9. What is the output of the following code?
 a={4,5,6}
 b={2,8,6}
 a-b

 A {4,5}
 B {6}
 C Error as unsupported operand type for set data type
 D Error as the duplicate item 6 is present in both sets
 E {2,-3,0}

203
Quiz 4
 10. What is the output of the following piece of code?
 a={5,6,7,8}
 b={7,8,10,11}
 a^b

 A {5,6,7,8,10,11}
 B {7,8}
 C Error as unsupported operand type of set data type
 D {5,6,10,11}
 E None of the above

204
Quiz 4
 11. What is the output of the following code?
 s={5,6}
 s*3

 A Error as unsupported operand type for set data type


 B {5,6,5,6,5,6}
 C {5,6}
 D Error as multiplication creates duplicate elements which isn’t
allowed
 E None of the above

205
Quiz 4
 12. What is the output of the following piece of code?
 a={9,10,11,12}
 b={11,12,9,10}
 a==b

 A True
 B False

206
Quiz 4
 13. What is the output of the following piece of code?
 a={3,4,5}
 b={5,6,7}
 a|b

 A Invalid operation
 B {3, 4, 5, 6, 7}
 C {5}
 D {3,4,6,7}

207
Quiz 4
 14. Is the following piece of code valid?
 a={3,4,{7,5}}
 print(a[2][0])

 A Yes, 7 is printed
 B Error, elements of a set can’t be printed
 C Error, subsets aren’t allowed
 D Yes, {7,5} is printed

 15. Which statement is false (select one)

 A Frozen sets are mutable


 B Frozen sets are hashable
 C Myset = frozenset([3, 4, 5, 6]) defines a frozen set
 D Frozenset data supports the method copy and union

208
Python IF ELSE

209
Python IF ELSE(cont)
 Python If ... Else

 Python Conditions and If statements


 Python supports the usual logical conditions from mathematics:
 Equals: a == b
 Not Equals: a != b
 Less than: a < b
 Less than or equal to: a <= b
 Greater than: a > b
 Greater than or equal to: a >= b
 These conditions can be used in several ways, most commonly in
"if statements" and loops
 An "if statement" is written by using the if keyword.

210
Python IF ELSE(cont)
 Example
 If statement:
 a = 10
 b = 20
Indentation
 if b > a: Python relies on indentation, using whitespace, to
 print("b is greater than a") define scope in the code. Other programming
languages often use curly-brackets for this
purpose.

211
Python IF ELSE(cont)
 elif
 The elif keyword is python’s way of saying "if the previous
conditions were not true, then try this condition".
 Example
 a = 10
 b = 10
 if b > a:
 print("b is greater than a")
 elif a == b:
 print("a and b are equal“)

 In this example a is equal to b, the first condition is not true, but the elif condition is true, so we
print to screen that "a and b are equal"

212
Python IF ELSE(cont)
 else
 The else keyword catches anything which isn't caught by the
preceding conditions
 Example
 a = 30
 b = 20
 if b > a:
 print("b is greater than a")
 elif a == b:
 print("a and b are equal")
 else:
 print("a is greater than b")
 In this example a is greater than b, so the first condition is not true, also the elif condition is not
true either, so the else condition is executed and "a is greater than b“ is printed

213
Python IF ELSE(cont)
 You can also have an else without the elif:
 Example
 a = 20
 b = 30
 if b > a:
 print("b is greater than a")
 else:
 print("b is not greater than a")

214
Python IF ELSE(cont)
 Short Hand If
 If you have only one statement to execute, you can put it on the
same line as the if statement
 Example
 One line if statement:
 if a > b: print("a is greater than b")
 Example
 a = 20
 b = 10
 if a > b: print("a is greater than b")

215
Python IF ELSE(cont)
 Short Hand If ... Else
 If you have only one statement to execute, one for if, and one for
else, you can put it all on the same line:
 Example
 One line if else statement:
 print(“Yes") if a > b else print(“No")
 Example
 a = 20
 b = 10
 print(“Yes") if a > b else print(“No")

216
Python IF ELSE(cont)
 You can also have multiple else statements on the same line (I
knew someone would ask!)
 Example
 One line if else statement, with 3 conditions:
 print(“Yes") if a > b else print("=") if a == b else print(“NO")
 Example
 a = 20
 b = 10
 print(“Yes") if a > b else print("=") if a == b else print(“NO")

217
Python IF ELSE(cont)
 Or
 The or keyword is a logical operator, and is used to combine
conditional statements:
 Example
 Test if a is greater than b, OR if a is greater than c:
 if a > b or a > c:
 print("At least one of the conditions is True")
 Example
 a = 20
 b = 10
 c = 50
 if a > b or a > c:
 print("At least one of the conditions is True")

218
Python IF ELSE(cont)
 And
 The and keyword is a logical operator, and is used to combine
conditional statements:
 Example
 Test if a is greater than b, AND if c is greater than a:
 if a > b and c > a:
 print("Both conditions are True")
 Example
 a = 20
 b = 10
 c = 50
 if a > b and c > a:
 print("Both conditions are True")

219
Quiz 5

220
Quiz 5
 1. Which one of the following if statements will not execute
successfully:

 A. if (1, 2): print(‘hello’)

 B. if (1, 2):
 print(‘hello’)

 C. if (1, 2):

 print(‘hello’)

 D. if (1, 2):
print(‘hello’)

 E. if (1, 2):
 print(‘hello')

221
Quiz 5
 2. What signifies the end of a statement block or suite in
Python?

 A. a line that is indented less than the previous line

 B. end

 C. }

 D. a comment line

222
Quiz 5
 3. What is the output of the following code snippet?

 if 'bar' in ['foo','bar','hello','python']:
 print(1)
 print(2)
 if 'a' in 'qux':
 print(3)
 print(4)

 A It doesn’t generate any output


 B 1234
 C 124
 D 4
 E None of the above

223
Quiz 5
 4. Suppose you have the following variables defined:
 a = 100
 b = 50
 Which Python if/else statement below assigns a variable m
to the smaller of a and b
 A. if a < b:
 m=a
 else:
 m= b
 B. if a > b:
 m=a
 else:
 m=b
 C. if a>b: m=b : else m =a
 D. None of the above
224
Quiz 5
 5. Which of the following are valid if/else statements (no
syntax error) in Python, assuming x and y are defined
appropriately (there may be more than one)

 A. if x < y: print('foo') else: print('bar’)

 B. if x < y: if x > 10: print('foo’)

 C. if x < y: print('foo’)
 elif y < x: print('bar’)
 else: print('baz’)

 D. if x < y: print('foo'); print('bar'); print('baz')

225
Quiz 5
 6. What is value of this expression?
 'a' + 'x' if '123'.isdigit() else 'y' + 'b’

 A. 'axb’

 B. 'ab’

 C. 'ax’

 D. 'axyb’

 E. None of the above

226
Quiz 5
 7. Which statement will check if x is strictly less than y and
does nothing if it’s true?

 A if x < y:
 print(“ “)
 B if x < y:
 pass
 C if x<=y:
 print(“”)
 D none of the above

227
Quiz 5
 8. What is the output of the following code?
 i = 20
 if (i == 10):
 print ("i is 10")
 elif (i == 15):
 print ("i is 15")
 elif (i == 20):
 print ("i is 20")
 else:
 print ("i is not present")

 A. error
 B. “i is not present”
 C. “i is 15”
 D. “i is 20”
 E. None of the above

228
Quiz 5
 9. What is the output of the following code?
 i = 20
 if (i < 10):
 print ("i is less than 10")
 elif (i >=20):
 print (“i is at least 20")
 elif (i > 15):
 print ("i is at least 15")
 else:
 print (“none of the conditions hold")
 A. “i is less than 10”
 B. “i is at least 20”
 C. “i is at least20”
 i is at least 25”
 D. “i is at least 15”
 E. None of the above

229
Quiz 5
 10. What is the output of the following code
 i = 10
 if (i == 10):
 # First if statement
 if (i < 15):
 print ("i is smaller than 15")
 if (i < 12):
 print ("i is smaller than 12 too")
 else:
 print ("i is greater than 15")

 A. “i is smaller than 15”


 “i is smaller than 12 too”
 B. Error
 C. “i is smaller 15”
 D. “i is smaller than 12 too”
 E. None of the above
230
Python Loops

231
Python Loops (cont)
 Python For Loops
 A for loop is used for iterating over a sequence (that is either a
list, a tuple, a dictionary, a set, or a string)
 This is less like the for keyword in other programming languages,
and works more like an iterator method as found in other object-
orientated programming languages (C++, Java)
 With the for loop we can execute a set of statements, once for
each item in a list, tuple, set etc..
 “For loops” in Python use indents to determine which statements
belong to the loop
 Example:
 fruits = ["apple", "banana", "cherry"]
 for x in fruits:
Indentation
 print(x) Python relies on indentation, using
whitespace, to define scope in the
code
Other programming languages often
use curly-brackets for this purpose 232
Python Loops(cont)
 The for loop does not require an indexing variable to set
beforehand
 Looping Through a String
 Even strings are iterable objects, they contain a sequence of
characters:
 Example
 Loop through the letters in the word "banana":
 for x in "banana":
 print(x)

233
Python Loops(cont)
 The break Statement
 With the break statement we can stop the loop before it has looped
through all the items:
 Example
 Exit the loop when x is “apple":
 fruits = [“cherry", “apple", “banana"]
 for x in fruits:
 print(x)
 if x == “apple":
 break

234
Python Loops(cont)
 Example
 Exit the loop when x is “apple", but this time the break comes
before the print:
 fruits = [“cherry", “apple", “banana"]
 for x in fruits:
 if x == “apple":
 break
 print(x)

 This time “apple” is not printed


235
Python Loops(cont)
 The continue Statement
 With the continue statement we can stop the current iteration of
the loop, and continue with the next:
 Example
 Do not print apple:
 fruits = ["apple", "banana", "cherry"]
 for x in fruits:
 if x == “apple":
 continue
 print(x)

236
Python Loops(cont)
 The range() Function
 To loop through a set of code a specified number of times, we can
use the range() function,

 The range() function returns a sequence of numbers, starting from


0 by default, and increments by 1 (by default), and ends at a
specified number

 Example
 Using the range() function:
Note that range(6) is not the values of 0
 for x in range(6): to 6, but the values 0 to 5.
The range() function defaults to 0 as a
 print(x) starting value, however it is possible to
specify the starting value by adding a
parameter: range(2, 6), which means
values from 2 to 6 (but not including 6)

237
Python Loops(cont)
 Example
 Using the start parameter:
 for x in range(2, 10):
 print(x)

 The range() function defaults to increment the sequence by 1,


however it is possible to specify the increment value by adding a
third parameter: range(2, 10, 2):
 Example
 Increment the sequence with 2 (default is 1):
 for x in range(2, 10, 2):
 print(x)
Start at 2 , increment by 2
10 is not included

238
Python Loops(cont)
 Else in For Loop
 The else keyword in a for loop specifies a block of code to be
executed when the loop is finished:
 Example
 Print all numbers from 0 to 10, and print a message when the loop
has ended:
Else is not part of the
 for x in range(11): for loop
 print(x)
 else: Question:
 print("Finally finished!") for x in range(11):
print(x)

if x ==8:
break
else:
print("Finally finished!")

What is the output of the


code above?
239
Python Loops(cont)
 Nested Loops
 A nested loop is a loop inside a loop
 The "inner loop" will be executed one time for each iteration of
the "outer loop":
 Example
 Print each adjective for every fruit:
 adj = [“crunchy", “yellow", “sweet"]
 fruits = ["apple", "banana", "cherry"]

 for x in adj:
 for y in fruits:
 print(x, y)

240
Python Loops(cont)
 Python While Loops
 Python Loops
 Python has two primitive loop commands:
 while loops
 for loops
 We already covered the “for loop”, in this section we will discuss
the while loop
 The while Loop
 With the while loop we can execute a set of statements if a
condition is true

241
Python Loops(cont)
 Example
 Print i as long as i is less than 10:
 i=1
Indentation
 while i < 10: Python relies on indentation, using whitespace, to
define scope in the code
 print(i) Other programming languages often use curly-
 i += 1 brackets for this purpose.

 Note: remember to increment i, or else the loop will continue forever


 The while loop requires relevant variables to be ready, in this example we need to
define an indexing variable, i, which we set to 1

242
Python Loops(cont)
 The break Statement
 With the break statement we can stop the loop even if the while
condition is true:
 Example
 Exit the loop when i is 3:
 i=1
 while i < 6:
 print(i)
 if i == 3:
 break
 i += 1

243
Python Loops(cont)
 The continue Statement
 With the continue statement we can stop the current iteration, and
continue with the next:
 Example
 Continue to the next iteration if i is 3:
 i=0
 while i < 6:
 i += 1
 if i == 3:
 continue
 print(i)

244
Python Loops(cont)
 While True loops
 while True:
 means infinite loop

 The while statement is often used as a finite loop


 Using the constant 'True' guarantees the repetition of the while
statement without the need to control the loop by setting a boolean
value inside the iteration for example, unless you want to break it

 Syntax

 while True:
 progress = do_something()
 if progress is done:
 break

245
Python Loops(cont)
 Example:
 ctr=10
 while True:
 inp=input("input a number")
 inp = int (inp)
 if (inp!=ctr):
 print ("didn't enter that number yet")
 elif(inp==ctr):
 print("ok")
 break

 Try out this program and see how it fits the structure of a while
True loop (compare with the previous slide)
 You will need to enter the number 10 to get out of the loop

246
Quiz 6

247
Quiz 6
 1. What is the output of the following code?
 for i in range(10):
 if i == 5:
 break
 else:
 print(i)
 else:
 print("Here")

 A. 0 1 2 3 4 Here
 B. 0 1 2 3 4 5 Here
 C. 0 1 2 3 4
 D. 1 2 3 4 5
 E. None of the above

248
Quiz 6
 2. What is the output of the following code?

 string = "my name is x"


 for i in string:
 print (i, end=", ") # end each print with a , (comma)

 A. m, y, , n, a, m, e, , i, s, , x,
 B. m, y, , n, a, m, e, , i, s, , x
 C. my, name, is, x,
 D. error
 E. None of the above

249
Quiz 6
 3. What is the output of the following code?

 string = "my name is x"


 for i in string.split():
 print (i, end=", ") # end each print with a , (comma)

 A. m, y, , n, a, m, e, , i, s, , x,
 B. m, y, , n, a, m, e, , i, s, , x
 C. error
 D. my, name, is, x,
 E. None of the above

250
Quiz 6
 4. What is the output of the following code snippet?
 a = [0, 1, 2, 3]
 for x in a:
 print(a[-1])

 A. 0 1 2 3
 B. 3 3 3 3
 C. error
 D. 3 2 1 0
 E. None of the above

251
Quiz 6
 5. What is the output of the following code snippet?

 a = [0, 1, 2, 3]
 i = -2
 while i not in a:
 print(i)
 i += 1

 A. -2 -1
 B. 0
 C. error
 D. -2 -1 0

252
Quiz 6
 6. What is the output of the following code snippet?

 i=0
 while i < 5:
 print(i)
 i += 1
 if i == 3:
 break
 else:
 print(0)

 A. 0 1 2 0
 B. 0 1 2
 C. error
 D. none of the mentioned
253
Quiz 6
 7. What is the output of the following code snippet?

 i=0
 while i < 3:
 print(i)
 i += 1
 else:
 print(0)

 A. 0 1 2 3 0
 B. 0 1 2 0
 C. 0 1 2
 D. error

254
Quiz 6
 8. What is the output of the following code snippet?

 x = "abcdef"
 while i in x:
 print(i, end=" ")

 A. a b c d e f
 B. abcdef
 C. i i i i i i …
 D. error

255
Quiz 6
 9. What is the output of the code snippet below?
 x = "abcdef"
 i = "i"
 while i in x:
 print(i, end=" ")

 A. no output
 B. i i i i i i …
 C. a b c d e f
 D. abcdef
 E. error

256
Quiz 6
 10. What is the output of the following code snippet?
 i=2
 while True:
 if i%2 == 0:
 print(i)
 break
 i += 2

 A. 2 4
 B. 0 …
 C. 0 2
 D. 2
 E. None of the above

257
Dictionaries
 In this section, you'll learn everything you need to know about
Python dictionaries; how they are created, accessing, adding and
removing elements from them and, various built-in methods

258
Dictionaries(cont)
 Python dictionary is an unordered collection of items
 While other data types have only value as an element, a dictionary
has a key: value pair
 Dictionaries are optimized to retrieve values when the key is known
 How to create a dictionary?
 Creating a dictionary is as simple as placing items inside curly
braces {} separated by comma
 Another way is to use the dict() function
 An item has a key and the corresponding value expressed as a pair,
key: value
 While values can be of any data type and can repeat, keys must
be of immutable type (string, number or tuple with immutable
elements) and must be unique

259
Dictionaries(cont)
 Examples
 # empty dictionary
 my_dict = {}

 # dictionary with integer keys


 my_dict = {1: 'apple', 2: 'ball'}

 # dictionary with mixed keys


 my_dict = {'name': 'John', 1: [2, 4, 3]}

 # using dict()
 my_dict = dict({1:'apple', 2:'ball'})

 # from sequence having each item as a pair


 my_dict = dict([(1,'apple'), (2,'ball')])
260
Dictionaries(cont)
 How to access elements from a dictionary?
 One way is to use indexing with keys
 Another way is to use the get() method
 The difference with using get() is that it returns None instead of
KeyError, if the key is not found

 my_dict = {'name':'Jack', 'age': 26}


 print(my_dict[‘name’])
 #output is Jack
 print(my_dict.get(‘age’))
 my_dict.get(‘address’)
 #outputs blank
 my_dict[‘address’]
 #will output an error

261
Dictionaries(cont)
 How to change or add elements in a dictionary?
 Dictionaries are mutable
 We can add new items or change the value of existing items using
assignment operator
 If the key is already present, value gets updated, else a new key:
value pair is added to the dictionary
 Examples
 my_dict = {'name':'Jack', 'age': 26}
 # update value
 my_dict['age'] = 27
 #Output: {'age': 27, 'name': 'Jack’}
 print(my_dict)
 # add item
 my_dict['address'] = 'Downtown’
 # Output: {'address': 'Downtown', 'age': 27, 'name': 'Jack’}

262
Dictionaries(cont)
 How to delete or remove elements from a dictionary?
 We can remove a particular item in a dictionary by using the
method pop()

 This method removes an item with the provided key and returns
the value

 The method, popitem() can be used to remove the last key:value


pair listed in the dictionary(this will depend on the order of how the
key value pairs were inserted)

 All the items can be removed at once using the clear() method

 We can also use the del keyword to remove individual items or the
entire dictionary itself

263
Dictionaries(cont)
 Examples
 # create a dictionary
 squares = {1:1, 2:4, 3:9, 4:16, 5:25}
 Remove a specific item using pop
 squares.pop(4)
 #output is 16
 print(squares)
 #{1: 1, 2: 4, 3: 9, 5: 25}
 Remove the last key:value pair
 squares.popitem()
 #output is (5,25)
 Delete a particular item
 del squares[1]
 print(squares)
 # {2:4, 3:9}
264
Dictionaries(cont)
 Remove all items
 squares.clear()
 print(squares)
 #output is {}
 Delete the dictionary itself
 del squares
 print(squares)
 # output is an error, squares is not defined

265
Dictionaries(cont)

266
Dictionaries(cont)
 Example of some of these methods
 marks = {}.fromkeys(['Math','English','Science'], 0)
 print(marks)
 Output: {'English': 0, 'Math': 0, 'Science': 0}
 for item in marks.items():
 print(item)
 #output
 ('Math', 0)
 ('English', 0)
 ('Science', 0)
 list(sorted(marks.keys()))
 #output
 ['English', 'Math', 'Science’]

267
Dictionaries(cont)
 Python Dictionary Comprehension
 Dictionary comprehension is an elegant and concise way to create
new dictionary from an iterable in Python
 Dictionary comprehension consists of an expression pair (key:
value) followed by for statement inside curly braces {}
 Here is an example to make a dictionary with each item being a
pair of a number and its square
 Example
 squares = {x: x*x for x in range(6)}
 print(squares)
 Output is {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

268
Dictionaries(cont)
 A dictionary comprehension can optionally contain for or if
statements
 An optional if statement can filter out items to form the new
dictionary
 Here is an example to make dictionary with only odd items
 odd_squares = {x: x*x for x in range(11) if x%2 == 1}
 print(odd_squares)
 # Output: {1: 1, 3: 9, 5: 25, 7: 49, 9: 81}
 This code is equivalent to:
 squares = {}
 for x in range(11):
 if x%2 ==1:
 squares[x] = x*x

269
Dictionaries(cont)
 Other Dictionary Operations
 Dictionary Membership Test
 We can test if a key is in a dictionary or not using the keyword in
 Notice that membership test is for keys only, not for values
 squares = {1: 1, 3: 9, 5: 25, 7: 49, 9: 81}
 print( 1 in squares)
 #output is True
 print( 2 not in squares)
 #output is True
 Print(49 not in squares)
 #output is True

270
Dictionaries(cont)
 Iterating Through a Dictionary
 Using a for loop we can iterate though each key in a dictionary
 squares = {1: 1, 3: 9, 5: 25, 7: 49, 9: 81}
 for i in squares:
 print(squares[i])
 #output
 1
 9
 25
 49
 81

271
Dictionaries(cont)

272
Dictionaries(cont)
 Examples
 squares = {1: 1, 3: 9, 5: 25, 7: 49, 9: 81}
 print(len(squares))
 # Output: 5
 print(sorted(squares))
 #output is [1,3,5,7,9]

273
Quiz 7

274
Quiz 7
 1.Which of the following statements create a dictionary?

 A. d = {}
B. d = {“john”:40, “peter”:45}
C. d = {40:”john”, 45:”peter”}
D. A, B and C
 E. A and B

275
Quiz 7
 2. Read the code shown below carefully and pick out the
keys?
 mydict = {"john":40, "peter":45}

 A. “john”, 40, 45, and “peter”


 B. “john” and “peter”
 C. 40 and 45
 D. d = (40:”john”, 45:”peter”)

276
Quiz 7
 3. What is the output?
 dict = {"john":40, "peter":45}
 dict["john"]

 A. 40
 B. 45
 C. “john”
 D. “peter”
 E. None of the above

277
Quiz 7
 4. What will be the output of the following code snippet?
 a = {(1,2):1,(2,3):2}
 print(a[1,2])

 A. Key Error
 B. 1
 C. {(2,3):2}
 D. {(1,2):1}

278
Quiz 7
 5. What will be the output of the following code snippet?
 a = {'a':1,'b':2,'c':3}
 print (a['a','b’])

 A. Key Error
 B. [1,2]
 C. {‘a’:1,’b’:2}
 D. (1,2)

279
Quiz 7
 6. What will be the output of the following code snippet?
 fruit = {}
 def addone(index):
 if index in fruit:
 fruit[index] += 1
 else:
 fruit[index] = 1
 addone('Apple')
 addone('Banana')
 addone('apple')
 print (len(fruit))

 A. 1
B. 2
C. 3
D. 4
 E. 0
280
Quiz 7
 7. What will be the output of the following code snippet?
 arr = {}
 arr[1] = 1
 arr['1'] = 2
 arr[1] += 1
 sum = 0
 for k in arr:
 sum += arr[k]
 print (sum)

 A. 1
B. 2
C. 3
D. 4

281
Quiz 7
 8. What will be the output of the following code snippet?

 my_dict = {}
 my_dict[1] = 1
 my_dict['1'] = 2
 my_dict[1.0] = 4
 sum = 0
 for k in my_dict:
 sum += my_dict[k]
 print (sum)

 A. 7
B. Syntax error
C. 3
D. 6

282
Quiz 7
 9. What will be the output of the following code snippet?
 my_dict = {}
 my_dict[(1,2,4)] = 8
 my_dict[(4,2,1)] = 10
 my_dict[(1,2)] = 12
 sum = 0
 for k in my_dict:
 sum += my_dict[k]
 print (sum)
 print(my_dict)

 A. Syntax error
B. 30
{(1, 2): 12, (4, 2, 1): 10, (1, 2, 4): 8}
C. 47
{(1, 2): 12, (4, 2, 1): 10, (1, 2, 4): 8}
D. 30
{[1, 2]: 12, [4, 2, 1]: 10, [1, 2, 4]: 8}
283
Quiz 7
 10. What will be the output of the following code snippet?
 box = {}
 jars = {}
 crates = {}
 box['biscuit'] = 1
 box['cake'] = 3
 jars['jam'] = 4
 crates['box'] = box
 crates['jars'] = jars
 print (len(crates[‘box’]))
 A 1
 B 3
 C 4
 D Type Error
 E 2
284
Python File I/O

285
Python File I/O (cont)
 In this section, you'll learn about Python file operations
 More specifically, opening a file, reading from it, writing into it,
closing it and various file methods you should be aware of
 File is a named location on disk to store related information
 It is used to permanently store data in a non-volatile memory (e.g.
hard disk)
 Since, random access memory (RAM) is volatile which loses its data
when computer is turned off, we use files for future use of the data
 When we want to read from or write to a file we need to open it
first
 When we are done, it needs to be closed, so that resources that are
tied with the file are freed
 Hence, in Python, a file operation takes place in the following order.
 Open a file
 Read or write (perform operation)
 Close the file
286
Python File I/O (cont)
 How to Open a file
 Python has a built-in function open() to open a file
 This function returns a file object, also called a handle, as it is used
to read or modify the file accordingly
 Examples(don’t type into console yet )
 f = open(“test.txt”) # open a file in your current directory
 f = open(“C:/data/test.txt”) # this time specifying a path
 We can specify the mode while opening a file
 In mode, we specify whether we want to read 'r', write 'w' or
append 'a' to the file
 We also specify if we want to open the file in text mode or binary
mode

287
Python File I/O (cont)
 The default is reading in text mode
 In this mode, we get strings when reading from the file
 On the other hand, binary mode returns bytes and this is the mode
to be used when dealing with non-text files like image or exe files

288
Python File I/O (cont)
 Examples
 f = open("test.txt") # equivalent to 'r'
 f = open("test.txt",'w') # write in text mode
 f = open("img.bmp",'r+b') # read and write in binary mode
 When working with files in text mode, it is highly recommended to
specify the encoding type
 f = open("test.txt",mode = 'r',encoding = 'utf-8’)
 utf – unicode transformation format
 For more information utf see
http://www.unicode.org/faq//utf_bom.html
 When you specify exclusive creation, it clearly means, you would
use this mode for exclusively creating the file
 The need for this is required when you don't accidentally want to
truncate/append an existing file with either of the modes w or a

289
Python File I/O (cont)
 How to close a file Using Python?
 When we are done with operations to the file, we need to properly
close the file
 Closing a file will free up the resources that were tied with the file
and is done using Python close() method
 Python has a garbage collector to clean up unreferenced objects
but, we must not rely on it to close the file
 Example:
 f = open("test.txt",encoding = 'utf-8’)
 # perform file operations
 f.close()
 This method is not entirely safe
 If an exception occurs when we are performing some operation
with the file, the code exits without closing the file

290
Python File I/O (cont)
 A safer way is to use a try...finally block(we’ll get to this later in the
course)
 try:
 f = open("test.txt",encoding = 'utf-8')
 # perform file operations
 finally:
 f.close()
 This way, we are guaranteed that the file is properly closed
even if an exception is raised, causing program flow to stop
 The best way to open a file is using the with statement
 This ensures that the file is closed when the block inside with is
exited
 Example
 with open("test.txt",encoding = 'utf-8') as f:
 # perform file operations
291
Python File I/O (cont)
 As this is an interactive course, let’s practice on a test file
 Open the test.txt file below and save it the directory where the
python script was launched

test.txt

 Type f = open("test.txt",encoding = “utf-8”) in your console


 If you want to see the text, type f.read()

 The “\n” are the line breaks


 f.close()

292
Python File I/O (cont)
 How to write to File Using Python?
 In order to write into a file in Python, we need to open it in write
'w', append 'a' or exclusive creation 'x' mode
 We need to be careful with the 'w' mode as it will overwrite into the
file if it already exists
 All the previous data will be erased
 Writing a string or sequence of bytes (for binary files) is done using
write() method
 This method returns the number of characters written to the file
 Example (type this a script)
 with open("test.txt",'w',encoding = 'utf-8') as f:
 f.write("This file\n\n")
 f.write("my first file\n")
 f.write("contains three lines\n")

293
Python File I/O (cont)
 This program will create a new file named 'test.txt' if it does not
exist
 If it does exist, it is overwritten
 We must include the newline characters ourselves to distinguish
different lines
 In our case, the file did get overwritten

294
Python File I/O (cont)
 How to read files in Python?
 To read a file in Python, we must open the file in reading mode
 There are various methods available for this purpose
 We can use the read(size) method to read in size number of data
 If size parameter is not specified, it reads and returns up to the
end of the file
 Examples
 f = open("test.txt",'r',encoding = 'utf-8’)
 f.read(4) # read the first 4 data
 #'This’
 f.read(4) # read the next 4 data
 #’ fil’
 f.read() #no size parameter specified – reads from the current
cursor position to the end
 If f.read() is executed first, it reads from start to end

295
Python File I/O (cont)
 f.read()
 # read in the rest till end of file
 # 'e\n\nmy first file\ncontains three lines\n'
 f.read() # further reading returns empty string

296
Python File I/O (cont)
 We can see that, the read() method returns newline as '\n’
 Once the end of file is reached, we get empty string on further
reading
 We can change our current file cursor (position) using the seek()
method
 Similarly, the tell() method returns our current position (in number
of bytes)
 Examples:
 f.tell() #get the current file position
 f.seek(0) # bring file cursor to initial position
 print(f.read()) # read the entire file

297
Python File I/O (cont)
 See the results below after typing into the python console

298
Python File I/O (cont)
 We can read a file line-by-line using a for loop
 This is both efficient and fast
 for line in f:
 print(line)

299
Python File I/O (cont)
 Alternately, we can use readline() method to read individual lines
of a file
 This method reads a file till the newline, including the newline
character
 f.readline()
 #'This file\n’
 f.readline()
 #'\n'
 f.readline()
 #'my first file\n'
 f.readline()
 'contains three lines\n’
 f.readline()
 # ‘’

300
Python File I/O (cont)

301
Python File I/O (cont)
 Lastly, the readlines() method returns a list of remaining lines of
the entire file
 All these reading method return empty values when end of file
(EOF) is reached
 f.readlines()

302
Python File I/O (cont)

303
Quiz 8

304
Quiz 8
 1. What does opening a file in ‘a’ mode do?
 Choose one of the answers below

 A. opens a file for reading


 B. opens a file for writing
 C. opens a file for appending at the end of the file
 D. opens a file for exclusive creation
 E. None of the above

305
Quiz 8
 2. What does the following code do?
 f = open("test.txt")
 Choose one the following answers below

 A. Opens test.txt file for both reading and writing


 B. Opens test.txt file for reading only
 C. Opens test.txt file for writing only
 D. Opens test.txt file in “read, write, execute” mode
 E. None of the above

306
Quiz 8
 3. Which of the following codes closes file automatically if
exception occurs?
 Choose one of the following answers below:

 A. with open("test.txt", encoding = 'utf-8') as f:


 # perform file operation
 B. try:
 f = open("test.txt",encoding = 'utf-8')
 # perform file operations
 finally:
 f.close()

 C. A and B
 D. None of the above

307
Quiz 8
 4. For the following code below:
 f = open('test.txt', 'r', encoding = 'utf-8')
 f.read()

 Which of the following statements is true?


 Choose one of the answers below

 A. This program reads the content of test.txt file


 B. If test.txt contains newline, read() will return newline as ‘\n’
 C. You can pass an integer to the read() method
 D. A, B, C
 E. A, B

308
Quiz 8
 5. What will happen if you try to open a file that doesn’t
exist?
 Choose one of the answers below

 A. A new file is created


 B. Nothing will happen
 C. An exception is raised
 D. A and C

309
Quiz 8
 6. For the following code below:
 f = open('test.txt', ‘w', encoding = 'utf-8’)
 The file test.txt already exists
 What happens to the file test.txt?

 A. Copy of the test.txt is created


 B. previous test.txt will be overwritten
 C. An error is returned, operation fails
 D. test.txt will be opened and any new information will be
appended

310
Quiz 8
 7. For the following code below:
 f = open('test.txt’, ‘x', encoding = 'utf-8’)
 The file test.txt already exists
 What happens?

 A. text.txt is opened in read only mode


 B. test.txt is opened for editing
 C. Operation fails
 D. Nothing happens

311
Quiz 8
 8. What is the output of the following code ?
 with open('test.txt') as f:
 print(f.read(5))

test.txt file contains the content below on two separate lines (no
line after “How are you”)
Hello
How are you

A. Hell
B. How
C. Hello\n
D. you
E. Hello

312
Quiz 8
 9. What is the output of the following code ?
 with open('test.txt') as f:
 print(f.readlines())

 test.txt file contains the content below on three separate lines


(there is a blank line after “How are you”)
 Hello
 How are you

 A. ['Hello\n', 'How are you\n’]


 B. ['Hello', 'How are you’]
 C. [‘\nHello', ‘\nHow are you’]
 D. Hello, How are you
 E. None of the above

313
Quiz 8
 10. What is the output of the following code ?
 The file test.txt is the same as question 9

 with open('test.txt') as f:
 myfile = f.readlines() Test

 print(myfile[1])

 A. Error occurs
 B. ‘Hello’
 C. 'How are you\n’
 D. ‘How are you’ followed by a blankline
 E. None of the above

314
Python Directory and Files Management
 In this section, you'll learn about file and directory management in
Python, i.e. creating a directory, renaming it, listing all directories
and working with them

315
Python Directory and Files Management(cont)
 If there are a large number of files to handle in your Python
program, you can arrange your code within different directories to
make things more manageable
 A directory or folder is a collection of files and sub directories
 Python has the os module, which provides us with many useful
methods to work with directories (and files as well)
 Get Current Directory
 We can get the present working directory using the getcwd()
method
 This method returns the current working directory in the form of a
string
 Type the following below into your Python console
 import os
 os.getcwd()

316
Python Directory and Files Management(cont)

 Changing Directory
 We can change the current working directory using the chdir()
method
 The new path that we want to change to must be supplied as a
string to this method
 We can use both forward slash / or the backward slash \ to
separate path elements.
 It is safer to use escape sequence \\ when using the backward
slash
317
Python Directory and Files Management(cont)
 Type the following into your Python console
 os.chdir('C:\\Users\\Carlo’)
 print(os.getcwd())

 List Directories and Files


 All files and sub directories inside a directory can be known using
the listdir() method

318
Python Directory and Files Management(cont)
 This method takes in a path and returns a list of sub directories
and files in that path
 If no path is specified, it returns from the current working directory

319
Python Directory and Files Management(cont)
 Making a New Directory
 We can make a new directory using the mkdir() method
 This method takes in the path of the new directory
 If the full path is not specified, the new directory is created in the
current working directory
 Type the following into your Python console
 os.mkdir(‘zzz’) or os.mkdir([name] where name whatever you
want to call your new directory)
 os.listdir()

320
Python Directory and Files Management(cont)
 Renaming a Directory or a File
 The rename() method can rename a directory or a file
 The first argument is the old name and the new name must be
supplied as the second argument
 Type the following below into your Python Console
 os.rename(‘zzz’,’yyy’)
 os.listdir()

321
Python Directory and Files Management(cont)
 Removing Directory or File
 A file can be removed (deleted) using the remove() method
 Similarly, the rmdir() method removes an empty directory
 Type the following into your Python console
 os.listdir()

 os.remove(“test.txt”)
 os.listdir()

322
Python Directory and Files Management(cont)
 However, note that rmdir() method can only remove empty
directories
 In order to remove a non-empty directory we can use the rmtree()
method inside the shutil (“sh” utilities) module

323
Python Directory and Files Management(cont)

324
Python Directory and Files Management(cont)

325
Python Errors and Built-in Exceptions

326
Python Errors and Built-in Exceptions(cont)
 Python Errors and Built-in Exceptions
 When writing a program, we, more often than not, will encounter
errors (I always say that you learn more from errors than always
writing perfect code)
 Error caused by not following the proper structure (syntax) of the
language is called syntax error or parsing error
 Example
 Type the next line into the Python Console:
 if a < 3
 You will get the message below:
 File "<interactive input>", line 1 if a < 3
 SyntaxError: invalid syntax ^
 In this case, the colon sign is missing with the input statement

327
Python Errors and Built-in Exceptions(cont)
 Errors can also occur at runtime and these are called exceptions
 They occur, for example, when a file we try to open does not exist
(FileNotFoundError), dividing a number by zero (ZeroDivisionError),
module we try to import is not found (ImportError) etc…
 Whenever these type of runtime error occur, Python creates an
exception object
 If not handled properly, it prints a traceback to that error along
with some details about why that error occurred

328
Python Errors and Built-in Exceptions(cont)
 Python Built-in Exceptions
 Illegal operations can raise exceptions
 There are plenty of built-in exceptions in Python that are raised
when corresponding errors occur
 We can view all the built-in exceptions using the local() built-in
functions as follows
 Type the following into your Python console
 dir(locals()['__builtins__'])

329
Python Errors and Built-in Exceptions(cont)

330
Python Errors and Built-in Exceptions(cont)

331
Python Errors and Built-in Exceptions(cont)

332
Python Exception Handling - Try, Except, Else and
Finally
 We can handle these built-in and user-defined
exceptions in Python using try, except and finally statements

333
Python Exception Handling - Try, Except, Else and
Finally(cont)
 In this section, you'll learn how to handle exceptions in your Python
program using try, except and finally statements
 This will motivate you to write clean, readable and efficient code in
Python
 Python has many built-in exceptions which forces your program to
output an error when something in it goes wrong
 When these exceptions occur, it causes the current process to stop
and passes it to the calling process until it is handled
 If not handled, our program will crash
 For example, if function A calls function B which in turn calls
function C and an exception occurs in function C
 If it is not handled in C, the exception passes to B and then to A
 If never handled, an error message is spit out and our program
come to a sudden, unexpected halt (you may not want this to
happen)

334
Python Exception Handling - Try, Except, Else and
Finally(cont)
 Catching Exceptions in Python
 In Python, exceptions can be handled using a try statement
 A critical operation which can raise exception is placed inside the
try clause and the code that handles exception is written in except
clause
 It is up to you (the programmer), what operations we perform once
we have caught the exception
 Here is a simple example
 try:
 print ("Hello World“)
 except:
 print ("This is an error message!”)
 Type the above into your console and see what you get

335
Python Exception Handling - Try, Except, Else and
Finally(cont)
 Another Example
 my_number = 0
 try:
 z = 1/my_number
 print(z)
 except:
 print(“you can’t divide by 0”)
 print(“continuing the program”)

 What happens if you don’t do have the try and except?


 my_number = 0
 z = 1/my_number
 print(z)
 The program will stop and output an error

336
Python Exception Handling - Try, Except, Else and
Finally(cont)
 Another example:
 Open the embedded txt file below and copy it into your python IDE

Try_Except_Examp
le

 # import module sys to get the type of exception


 import sys
 randomList = ['a', 0, 2]
 for entry in randomList:
 try:
 print("The entry is", entry)
 r = 1/int(entry)
 break #if successful the for loops break
 except:
 print("Oops!",sys.exc_info()[0],"occured.")
 print("Next entry.")
 print()
 print("The reciprocal of",entry,"is",r)

337
Python Exception Handling - Try, Except, Else and
Finally(cont)
 Output is below:
 The entry is a
 Oops! <class 'ValueError'> occured.
 Next entry.

 The entry is 0
 Oops! <class 'ZeroDivisionError'> occured.
 Next entry.

 The entry is 2
 The reciprocal of 2 is 0.5

338
Python Exception Handling - Try, Except, Else and
Finally(cont)
 In this program, we loop until each time an entry that has a valid
reciprocal (i.e. , it is a number)
 The portion that can cause exception is placed inside try block
 If no exception occurs, except block is skipped and normal flow
continues
 But if any exception occurs, it is caught by the except block
 The name of the exception using ex_info() function inside sys
module
 We can see that the value 'a' causes ValueError and number 0
causes ZeroDivisionError

339
Python Exception Handling - Try, Except, Else and
Finally(cont)
 What about try, except else?
 Syntax:
 try:
 operation_that_can_throw_io_error()
 except IOError:
 handle_the_exception_somehow()
 else:
 Example:
 try:
 age=int(input(‘Please enter your age: '))
 except:
 print (‘Sorry you have entered an invalid value.')
 else:
 if age <= 18:
 print(‘Please come back when you are 18.')
 else:
 print(‘Please Enter.’)
 Else clause will execute if no exception is raised

340
Python Exception Handling - Try, Except, Else and
Finally(cont)
 Catching Specific Exceptions in Python
 In the previous example, we did not mention any exception in the
except clause

 This is not a good programming practice as it will catch all


exceptions and handle every case in the same way

 We can specify which exceptions an except clause will catch


 A try clause can have any number of except clauses to handle them
differently but only one will be executed in case an exception
occurs (please remember that only one will be executed)

 We can use a tuple of values to specify multiple exceptions in an


except clause

341
Python Exception Handling - Try, Except, Else and
Finally(cont)
 try:
 # do something
 pass
 except ValueError:
 # handle ValueError exception
 pass
 except (TypeError, ZeroDivisionError):
 # handle multiple exceptions
 # TypeError and ZeroDivisionError
 pass
 except:
 # handle all other exceptions
 pass

342
Python Exception Handling - Try, Except, Else and
Finally(cont)
 Example

 a=2 Try_Exception_Exa
mple_value_errors
 random_list = [a,0,'1']
 for item in random_list:
 try:
 print("value is ", item)
 r = 1/item
 print("reciprocal is", r)
 except (TypeError, ValueError):
 print("not a number error at value ", item)
 pass
 except (TypeError, ZeroDivisionError):
 # handle multiple exceptions
 print("divison by zero error at value", item)
 pass
 except:
 # handle all other exceptions
 print("sorry an error occurred")
 pass

343
Python Exception Handling - Try, Except, Else and
Finally(cont)
 Raising Exceptions
 In Python programming, exceptions are raised when corresponding
errors occur at run time, but we can forcefully raise it using the
keyword raise (I’ll explain on the next slide, why you would do this
)
 Type the following into your Python Console (see below)

 We can also optionally pass in value to the exception to clarify why


that exception was raised (passed in “This is an argument” above )

344
Python Exception Handling - Try, Except, Else and
Finally(cont)
 try:
 a = int(input("Enter a positive integer: "))
 if a <= 0:
 raise ValueError("That is not a positive number!")
 except ValueError as val_error:
 print(val_error)

 Enter -1 as your input when asked

345
Python Exception Handling - Try, Except, Else and
Finally(cont)
 try...finally
 The try statement in Python can have an optional finally clause
 This clause is executed no matter what, and is generally used to
release external resources (i.e. close a file, close a connection)
 In all these circumstances, we must clean up the resource once
used, whether it was successful or not
 Closing the file should occur in the finally block
 Example
 try:
 f = open("test.txt",encoding = 'utf-8')
 # perform file operations
 finally:
 f.close()

 This guarantees the file will be closed even if an exception occurs

346
Python Exception Handling - Try, Except, Else and
Finally(cont)
 You need to be careful using Try, Except and Finally
 Example:
 # Open new file to write
 file = None
 try:
 file = open(filePath, 'w')
 except IOError:
 msg = ("Unable to create file on disk.")
 file.close()
 return
 finally:
 file.write("Hello World!")
 file.close()

 Question: what can go wrong with this code?


347
Python Exception Handling - Try, Except, Else and
Finally(cont)
 Answer:
 If Python fails to open given file (say because the file doesn’t
exist), then the 'except' block executes because of the error ,
however the value of file is none (because no file was opened) and
the ‘finally’ block which always executes will try to write lines into
an non existent file

 Class Exercise:
 Rewrite the code in a better way so that this doesn’t happen

348
Exercise Solution
 Here is one possible solution
 If you want to use try:except:finally, you should be doing
something like this:
 try:
 f = open("file", "w")
 try:
 f.write('Hello World!')
 finally:
 f.close()
 except IOError:
 print ‘we have a problem'

349
Exercise Solution
 A much cleaner way (pythonic way) of doing this is using
the with statement:
 try:
 with open("output", "w") as outfile:
 outfile.write('Hello World')
 except IOError:
 print ‘we have an error'

350
Quiz 9

351
Quiz 9
 1. How many except statements can a try-except block
have?

 A. zero
B. one
C. at least two
D. at least one
 E. None of the above

 2. When will the else part of try-except-else be executed?


A. always
B. when an exception occurs
C. when no exception occurs
D. when an exception occurs in to except block

352
Quiz 9
 3. Is the following code valid?
 try:
 # Do something
 except:
 # Do something
 finally:
 # Do something

 A. no, there is no such thing as finally


 B. no, finally cannot be used with except
 C. no, finally must come before except
 D. yes, no issue with this code

353
Quiz 9
 4. Is the following code valid?
 try:
 # Do something
 except:
 # Do something
 else:
 # Do something

 A. no, else can only be used with if else if block


 B. no, else cannot be used with except
 C. no, else must come before except
 D. There is an error in the syntax
 E. Of course it is

354
Quiz 9
 5. Can one block of except statements handle multiple
exception?
 A. yes, like except [TypeError, SyntaxError]
 B. yes, like except (TypeError, SyntaxError)
 C. no

 6. When is the finally block executed?


 A. when there is no exception
 B. when there is an exception
 C. only if some condition that has been specified is satisfied
 D. always

355
Quiz 9
 7. What is the output of the following code?
 def foo():
 try:
 return 1
 finally:
 return 2
 k = foo()
 print(k)

 A. 1
 B. 2
 C. 3
 D. error, there is more than one return statement in a single try-
finally block

356
Quiz 9
 8. What is the output of the following code?
 def foo():
 try:
 print(1)
 finally:
 print(2)
 foo()

 A. 1 2
 B. 1
 C. 2
 D. None of the above

357
Quiz 9
 9. What is the output of the following?
 try:
 if ‘5' != 5:
 raise TypeError
 else:
 print("someError has not occurred")
 except TypeError:
 print ("someError has occurred")

 A. Syntax Error
 B. someError has not occurred
 C. someError has occurred
 D. None of the above

358
Quiz 9
 10. What happens when ‘5’ == 5 is executed?

 A. we get a True
 B. we get a False
 C. a TypeError occurs
 D. a ValueError occurs
 E. Nothing happens

359
Quiz 9
 11. What does the following code snippet do?
 try:
 # code that can raise error
 pass

 except (TypeError, ZeroDivisionError):


 print("Two")

 Choose one the answers below

 A. Prints Two if exception occurs (doesn’t matter which exception)


 B. Prints Two if exception doesn’t occur
 C. Prints Two if TypeError or ZeroDivisionError if exception occurs
 D. Prints Two only if both TypeError and ZeroDivisionError
exception occurs
360
Python Functions

361
Python Functions(cont)
 Python Functions

 A function is a block of code which only runs when it is called

 You can pass data, known as parameters, into a function

 A function can return data as a result

 Creating a Function

 In Python a function is defined using the def keyword:


 Example
 def my_function():
 print(“I am a function")

362
Python Functions(cont)
 Calling a Function

 To call a function, use the function name followed by parenthesis:


 Example
 def my_function():
 print(“I am a function")

 my_function()

363
Python Functions(cont)
 Parameters
 Information can be passed to functions as parameters

 Parameters are specified after the function name, inside the


parentheses
 You can add as many parameters as you want, just separate them
with a comma

 The following example has a function with one parameter (fname)


 When the function is called, we pass along a first name, which is
used inside the function to print the full name:

364
Python Functions(cont)
 Example
 def my_function(fname):
 print(fname + "Loves Python")

 my_function(“Steve")
 my_function(“Anil")
 my_function(“Martha")

365
Python Functions(cont)
 Default Parameter Value

 The following example shows how to use a default parameter value

 If we call the function without parameter, it uses the default value:


 Example
 def my_function(country = “Canada"):
 print("I am from " + country)

 my_function("Sweden")
 my_function(“USA")
 my_function()
 my_function(“Argentina")

 Default is Canada
366
Python Functions(cont)
 Return Values

 To let a function return a value, use the return statement:


 Example
 def my_function(x):
 return x**2

 print(my_function(3))
 print(my_function(5))
 print(my_function(9))

367
Python Functions
 You are going to hear a lot of terms associated with functions and
two important ones are arguments and parameters

 What is the difference between a parameter and an argument?

 The key difference between argument and parameter is that an


argument is the data passed at the time of calling a function while
a parameter is a variable defined by a function that receives a
value when the function is called

 Example:
 def function(x,y): 5,6 are arguments
 return x+y
x, y are parameters
 function(5,6)

368
Python Functions(cont)
 More on Function Arguments
 Python functions can have four types of arguments:
 Required Arguments: When the argument is mandatory for the
proper execution of the function
 If this argument is not passed an error will occur
 Default Arguments: In this case, this function works even if the
argument is not passed(as explained on slide 350)
 When this occurs, a default value is used.
 Keyword Arguments: A way to pass arguments by the parameter
name
 Variable Number of Arguments: A function can have an
unknown number of required arguments and keyword arguments
 In this case, extra positional arguments are stored in the tuple args
and extra keyword arguments in the dictionary kwargs.
 This must be specified at the definition of the function

369
Python Functions(cont)
 See the example function below: (it’s in the embedded text file –
Python function example)
 The parameters *args and **kwargs work as a placeholder as extra
positional and keyword arguments respectively
 def mysum(x,y,z=4,*args,**kwargs):
 #Requirements
 result = x+y
 #default argument
 result += z
 #variable arguments Pythonfunctionexample.txt
 for v in args:
 result += v
 #variable kw arguments
 for k,v in kwargs.items():
 result += v
 #show extra positional and keyword args
 print(args)
 print(kwargs)

 return result

370
Python Functions(cont)
 Let’s look closely at what this function does
 This function first adds the values of the required arguments x and
y
 Then it adds the third default argument z
 If z is not passed during the function call, it will receive the default
value of 4
 If more than three positional arguments are passed, the values are
stored in the tuple args
 Extra keyword arguments are stored in the kwargs dictionary
 The examples below represent many ways to call this function

371
Python Functions(cont)
 Type these into your console and see what results you get

 mysum(1,2,3,4)
 mysum(1,2,3,4,5,6)
 mysum(1,2,3,4,5,6,7,8,9,10)

 #outputs keyword arguments


 mysum(1,2,3,d=4, e=5)

 mysum(x=0, y=0,a=1, b=2,


 c=3, d=4, e=5)

372
Python Functions(cont)
 Recursion

 Python also accepts function recursion, which means a defined


function can call itself!

 Recursion is a common mathematical and programming concept


 It means that a function calls itself
 This has the benefit of meaning that you can loop through data to
reach a result

 You should be very careful with recursion as it can be quite easy to


slip into writing a function which never terminates, or one that uses
excess amounts of memory or processor power

373
Python Functions(cont)
 However, when done correctly recursion can be a very efficient and
mathematically-elegant approach to programming

 In the next example (next slide), you will see a function , called
my_recursion() which is a function that calls itself

 We use a variable j as the input, which decrements (-1) every time


we call the function

 The recursion ends when j = 0 (condition fails)

374
Python Functions(cont)
 def my_recursion(j):
 if (j>0):
 result = j+my_recursion(j-1)
 print(result)
 else:
 result = 0
 return result

 print("\n\nRecursion Example Results")


 my_recursion(6)

375
Unpacking Arguments
 Unpacking Arguments
 You can also use tuples and dictionaries to pass parameters to
functions
 A single asterisk (*) is used to perform the unpacking for tuple (or
list) and double asterisk (**) for dictionaries
 Example
 #Function definition
 def mytest(x,y):
 print("My test function")
 return x+y
 t=(1,2)
 mytest(*t)
 #same as
 mytest(1,2)

 mydict ={'x':1,'y':2}
 mytest(**mydict)
 #same as
 mytest(1,2)

376
Lambda Functions(cont)
 Python Lambda
 A lambda function is an anonymous/generic function (because it
doesn’t have a name)
 A lambda function can take any number of arguments but can only
have single/one expression

 Syntax
 lambda arguments : expression
 Example:
 y = lambda x : x**2 + 1
 print(y(1))

377
Lambda Functions(cont)
 Here is an example with more than one input (that’s correct, you
can have more than one input)
 y = lambda x, y, w : x**2+y**2+w**2
print(y(5, 6, 2))

 No Statements Allowed
 A lambda function can not contain any statements in its body
 Statements such as return, raise, pass, or assert in a lambda
function will raise a SyntaxError
 Here is an example of a lambda function containing return
 y = lambda x: return x
 Executing this statement will yield a syntax error

378
Lambda Functions(cont)
 Remember I said you can only have single/one expression?
 Can the single expression be spread out?
 Yes, you can spread the expression over more than one line,
however it must remain as a single expression

 y = (lambda x:
 'odd' if x%2 else 'even')

 print(y(6))

 print(y(7))

379
Lambda Functions(cont)
 Immediately Invoked Function Expression (IIFE)
 A lambda function can be immediately invoked
 For this reason it is often referred to as an Immediately Invoked
Function Expression (IIFE)

 See the doubler lambda function below that is called immediately


with 6 as an argument

 print ((lambda x: x*2)(5))

380
Lambda Functions(cont)
 Return Multiple Values
 You bet they can!!
 To return multiple values pack them in a tuple
 Then use multiple assignment to unpack the parts of the returned
tuple
 f = lambda number: (number**2, number**3)
 x, y = f(2)
 print(x)
 print(y)

381
Lambda Functions(cont)
 if else in Lambda
 Generally if else statement can be used to implement selection
logic in a function (of course, we’ve seen this before)
 But as it is a statement, you cannot use it in a lambda function 
 However, you can use the if else statement we’ve seen before
 Example:
 f = lambda x, y: x if x < y else y

 print(f(2, 4))

382
Lambda Functions(cont)
 Ways to Pass Arguments
 Just like a regular Python function, a lambda function supports all
the different ways of passing arguments
 This includes:

 Positional arguments
 Keyword arguments
 Default argument
 Variable list of arguments (*args)
 Variable list of keyword arguments (**kwargs)

383
Lambda Functions(cont)
 Positional arguments
 f = lambda x, y, z: x+y+z
 print(f(5, 6, 7))

 Keyword arguments
 f = lambda x, y, z: x+y+z
 print(f(5, z=7, y=6))

 Default arguments
 f = lambda x, y=3, z=4: x+y+z
 print(f(2))

384
Lambda Functions(cont)
 *args
 f = lambda *args: sum(args)
 print(f(5, 6, 7))

 **kwargs
 f = lambda **kwargs: sum(kwargs.values())
 print(f(x=5, y=6, z=7))

385
Zip function
 What is zip in Python?
 The zip() is a built-in Python function –comes with base python,
not package needs to be imported
 It is used to create an iterator of tuples (known as zip object)
from a list of iterables passed as arguments
 Each tuple in the iterator contains elements that exist at a similar
index in all the input iterables
 The size of the zip object depends on the shortest of the iterables
passed to the Python zip function

 Python zip() syntax


 zip(iterator_1, iterator_2, iterator_3 ...)
 Or
 zip(*iterables)

386
Zip function(cont)
 Zip() parameters
 The zip() function allows:

 Python iterables or collections such as a list, string, dictionary, set,


or any custom iterables

 Zip() return value


 The zip() function returns a consolidated iterator that contains
tuples holding adjacent values from input containers

387
Zip function(cont)
 Examples:

 prog_lang =[‘C’,’R’,’Java’,’C++’]
 numbers = [1,2,3,4]

 zip(prog_lang, numbers)
 list(zip(prog_lang,numbers))

388
Zip function(cont)
 Example
 x =(1,2,3,4)
 y =('a','b','c','d')
 z = [10,11,12,13]

 zip(x,y,z)

389
Enumerate Function
 Another useful function that I have used a lot is the enumerate
function
 When dealing with iterators, you may need to keep a count of
iterations
 Python provides a built-in function enumerate() for this task
 enumerate() adds a counter to an iterable and returns it in a form
of enumerate object
 The enumerate object can then be used directly in for loops or be
converted into a list of tuples using list() method
 Syntax:
 enumerate(iterable, start=0)
 Parameters:
 iterable: any object that supports iteration (e.g. list, tuple )
 start: the index value from which the counter is
 to be started, by default it is 0

390
Enumerate Function(cont)
 Example
 mylist = ["Python","Java","C"]
 s = "programmer"
 mytuple =("hello","world")
 mydict = {1:"Hello" , 2:"World"}

 print(list(enumerate(mylist)))
 print(list(enumerate(s)))
 print(list(enumerate(mytuple)))
 print(list(enumerate(mydict)))

391
Quiz 10

392
Quiz 10
 1. Which of the following refers to a use of a function in
python (select all that apply)?

 A. Functions are reusable pieces of programs


 B. Functions don’t provide better modularity for your application
 C. You can create functions with out a name
 D. All of the above

 2. Which keyword is use for function?

 A. fun
 B. define
 C. def
 D. function
393
Quiz 10
 3. What is the output of the below program?

 def sayHello():
 print('Hello World!')
 sayHello()
 sayHello()

 A. Hello World!
 Hello World!
 B. ‘Hello World!’
 ‘Hello World!’
 C. Hello
 Hello
 D. None of the above

394
Quiz 10
 4. What is the output of the below program?

 def printMax(a, b):

 if a > b:

 print(a, 'is maximum')

 elif a == b:

 print(a, 'is equal to', b)

 else:

 print(b, 'is maximum')

 print (printMax(5, 6))

 A. 5
 B. 6
 C. 6 is maximum
 D. None of the above

395
Quiz 10
 5. What is the output of the code snippet below ?

 x = 50
 def func(x):

 print('x is', x)

 x=2
 print('Changed local x to', x)

 func(x)

 print('x is now', x)

 A. x is now 2
 B. x is now 50
 C. x is now 100
 D. None of the above

396
Quiz 10
 6. What is the output of below program?

 def say(message, times = 1):

 print(message * times)

 say('Hello')

 say('World', 5)

 A. Hello
 HelloHelloHelloHelloWorld

 B. Hello
 World 5

 C. Hello
 World,World,World,World,World

 D. Hello
 WorldWorldWorldWorldWorld

397
Quiz 10
 7. What is the output of the below program?

 def func(a, b=5, c=10):

 print('a is', a, 'and b is', b, 'and c is', c)

 func(3, 7)

 func(25, c = 24)

 func(c = 50, a = 100)

 A. a is 7 and b is 3 and c is 10
 a is 25 and b is 5 and c is 24
 a is 5 and b is 100 and c is 50

 B. a is 3 and b is 7 and c is 10
 a is 5 and b is 25 and c is 24
 a is 50 and b is 100 and c is 5

 C. a is 3 and b is 7 and c is 10
 a is 25 and b is 5 and c is 24
 a is 100 and b is 5 and c is 50

 D. None of the above

398
Quiz 10
 8. What is the output of below program?

 def maximum(x, y):

 if x > y:

 return x

 elif x == y:

 return 'The numbers are equal'

 else:

 return y

 print(maximum(2, 3))

 A. 2
 B. 3
 C. The numbers are equal
 D. None of the above

399
Quiz 10
 9. Which are the advantages of functions in python?

 A. Reducing duplication of code


 B. Decomposing complex problems into simpler pieces
 C. Improving clarity of the code
 D. A and C
 E. A, B and C

400
Quiz 10
 10. What is the output of the below program?

 def power(x, y=2):

 r=1

 for i in range(y):

 r=r*x

 return r

 print (power(3))

 print (power(3, 3))

 A. 212
 32
 B. 9
 27
 C. 567
 98
 D. None of the above

401
Quiz 10
 11. What is the output of the following code snippet?
 myfunc = lambda x: return x
 print(myfunc(5))

 A. 5.0

 B. 5

 C. x

 D. syntax error

 E. 0

402
Quiz 10
 12. What would be the output of the following code snippet?

 (lambda x: (x + 9) * 5 / 2)(3)

 A. SyntaxError

 B. 0

 C. 15.0

 D. 30.0

403
Quiz 10
 13. Consider the following list as an input:
 my_list = [‘Python', ‘ Rules’]
 Which of the statements below will translate the following function
to an anonymous lambda function? (Select all that apply)

 def func(x):
 return “ ''.join(x)
 func(my_list)

 A. lambda x: ” ''.join(x)
 B. y =lambda x : “ ''.join(x)
 C. lambda x: return “ ''.join(x)
 D. Can’t be done with a lambda function

404
Quiz 10
 14. How are lambda functions useful? Select all that apply
(there may be more than one):

 A. They are useful in allowing quick calculations or processing as


the input to other functions

 B . Lambda functions are anonymous functions that can replace


defined functions

 C. Lambda functions can only have one input variable

 D. They can be useful as quick, throwaway single line functions

405
Quiz 10
 15. What is the output of the following code snippet?

 function_product = lambda x, y: lambda x: y**x

 (function_product(2,3))(2)

 A. 6
 B. You can’t nest lambda functions
 C. 12
 D. 18
 E. 9

406
Python Custom Exceptions
 In this section, you will learn to define custom exceptions
depending upon your requirements

407
Python Custom Exceptions(cont)
 Python has many built-in exceptions which forces your program to
output an error when something in it goes wrong
 However, sometimes you may need to create custom exceptions
that serves your purpose
 In Python, users can define such exceptions by creating a new
class (don’t worry it’s not that bad)
 This exception class must be derived, either directly or indirectly,
from the Exception class (we haven’t covered classes yet)
 Most of the built-in exceptions are also derived from this class
 Example:

408
Python Custom Exceptions(cont)
 Here, we have created a user-defined exception called CustomError
which is derived from the Exception class
 This new exception can be raised, like other exceptions, using the
raise statement with an optional error message
 When we are developing a large Python program, it is a good
practice to place all the user-defined exceptions in a separate file
 Many standard modules do this

409
Python Custom Exceptions(cont)
 They define their exceptions separately as exceptions.py or
errors.py (generally but not always)
 User-defined exception class can implement everything a normal
class can do, but we generally make them simple and concise
 Most implementations declare a custom base class and derive
others exception classes from this base class
 Let’s look at an example which will help make sense of this
 I know we have not covered classes yet, but this will give you a
mild introduction to it

410
Python Custom Exceptions(cont)
 Example: User-Defined Exception in Python
 In this example, we will illustrate how user-defined exceptions can
be used in a program to raise and catch errors
 This program will ask the user to enter a number until they guess a
stored number correctly
 To help them figure it out, hint is provided whether their guess is
greater than or less than the stored number
 Open the attached script below

User_Defined_Exceptions.txt

 Copy it to your Python IDE and run the script

411
Python Custom Exceptions(cont)

412
Python Custom Exceptions(cont)
 Here, we have defined a base class called Error
 The other two exceptions (ValueTooSmallError and
ValueTooLargeError) that are raised by our program are derived
from this class
 This is the standard way to define user-defined exceptions in
Python programming, but not the only way

413
Pop Quiz
 Which of the following statement is true?
 Choose one the answers below

 A. You cannot create custom exceptions in Python


 B. You can create a user-defined exception by deriving a class
from Exception class
 C. You can create a user-defined exception by deriving a class
from Error class
 D. None of the above

414
Python Namespace and Scope
 Python Namespace and Scope
 In this section, you will learn about namespace; mapping from
names to objects and, scope of a variable

415
Python Namespace and Scope(cont)
 If you have ever read 'The Zen of Python' (type "import this" in
Python interpreter), the last line states, Namespaces are one
honking great idea -- let's do more of those!

 So what are these mysterious namespaces? Let us first look at


what name is
 Name (also called identifier) is simply a name given to objects
 Everything in Python is an object
 Name is a way to access the underlying object.
416
Python Namespace and Scope

417
Python Namespace and Scope(cont)
 For example, when we do the assignment a = 2, here 2 is an object
stored in memory and a is the name we associate it with
 We can get the address (in RAM) of some object through the built-
in function, id()
 Example

 Here, both refer to the same object


 Let's make things a little more interesting

418
Python Namespace and Scope(cont)

419
Python Namespace and Scope(cont)
 What is happening in the above sequence of steps?

420
Python Namespace and Scope(cont)
 Initially, an object 2 is created and the name a is associated with it,
when we do a = a+1, a new object 3 is created and now a
associates with this object
 Note that id(a) and id(3) have same values
 Furthermore, when we do b = 2, the new name b gets associated
with the previous object 2
 This is efficient as Python doesn't have to create a new duplicate
object
 This dynamic nature of name binding makes Python powerful; a
name could refer to any type of object
 a=5
 a = ‘Welcome to Python!'
 a = (a,b,c,1,2,3)

421
Python Namespace and Scope(cont)
 All these are valid, and a will refer to three different types of object
at different instances
 Functions are objects too, so a name can refer to them as well

 Our same name a can refer to a function and we can call the
function through it

422
Python Namespace and Scope(cont)
 What Are Namespaces?
 A namespace is basically a system to make sure that all the names
in a program are unique and can be used without any conflict
 Everything in Python—like strings, lists, functions, etc.—is an
object (later when we get to classes, we will see that every class is
a base class of object – don’t be concerned if you don’t understand
this right now)
 Python implements namespaces as dictionaries
 There is a name to object mapping, with the names as keys and
the objects as values
 Multiple namespaces can use the same name and map it to a
different object
 Here are a few examples of namespaces:

423
Python Namespace and Scope(cont)
 Local Namespace:
 This namespace includes local names inside a function
 This namespace is created when a function is called, and it only
lasts until the function returns
 Global Namespace:
 This namespace includes names from various imported modules
that you are using in a project
 It is created when the module is included in the project, and it lasts
until the script ends
 Built-in Namespace:
 This namespace includes built-in functions and built-in exception
names

424
Python Namespace and Scope(cont)
 For example, the Python math and cmath (complex number math)
modules have a lot of functions that are common to both of them,
like log10(), acos(), cos(), exp(), etc…
 If you are using both modules in the same program, the only way
to use these functions unambiguously is to prefix them with the
name of the module, like math.log10() and cmath.log10()

 from math import log10 as mathlog10


 mathlog10(12)
 #1.0791812460476249
 from cmath import log10 as cmathlog10
 cmathlog10(12)
 #(1.0791812460476247+0j)

425
Python Namespace and Scope(cont)
 Summary:
 A namespace containing all the built-in names is created when we
start the Python interpreter and exists as long, we don't exit
 This is the reason that built-in functions like id(), print() etc. are
always available to us from any part of the program
 Each module creates its own global namespace
 These different namespaces are isolated
 Multiple namespaces can use the same name and map it to a
different object

426
Python Namespace and Scope(cont)
 Modules can have various functions and classes
 A local namespace is created when a function is called, which has
all the names defined in it
 Similar, is the case with class
 Following diagram may help to understand the concept

427
Python Namespace and Scope(cont)
 What Is Scope?
 Namespaces help us uniquely identify all the names inside a
program
 However, this doesn't imply that we can use a variable name
anywhere we want (keep this in mind)
 A name also has a scope that defines the parts of the program
where you could use that name without using any prefix
 Just like namespaces, there are also multiple scopes in a program
 Here is a list of some scopes that can exist during the execution of
a program

428
Python Namespace and Scope(cont)
 A local scope, which is the innermost scope that contains a list of
local names available in the current function
 A scope of all the enclosing functions --the search for a name starts
from the nearest enclosing scope and moves outwards
 A module level scope that contains all the global names from the
current module
 The outermost scope that contains a list of all the built-in names –
this scope is searched last to find the name that you referenced
 Remember the dir() function?
 Remember the math module
 Try this:
 import math
 dir(math)

429
Python Namespace and
Scope(cont)

 You will get the


names from the
module math
 This is an example
of module level
scope

430
Python Namespace and Scope(cont)
 Python Variable Scope
 Although there are various unique namespaces defined, we may
not be able to access all of them from every part of the program
 The is where the concept of scope comes into play
 Scope is the portion of the program from where a namespace can
be accessed directly without any prefix
 At any given moment, there are at least three nested scopes
 Scope of the current function which has local names
 Scope of the module which has global names
 Outermost scope which has built-in names
 When a reference is made inside a function, the name is searched
in the local namespace, then in the global namespace and
finally in the built-in namespace
 If there is a function inside another function, a new scope is nested
inside the local scope

431
Python Namespace and Scope(cont)
 Example of Scope and Namespace in Python

 Here, the variable a is in the global namespace


 Variable b is in the local namespace of outer_function() and c is
in the nested local namespace of inner_function()
 When we are in inner_function(), c is local to us, b is nonlocal
and a is global.
 We can read as well as assign new values to c but can only read b
and c from inner_function()
 If we try to assign as a value to b, a new variable b is created in
the local namespace which is different than the nonlocal b
 Same thing happens when we assign a value to a
432
Python Namespace and Scope(cont)
 However, if we declare a as global, all the reference and
assignment go to the global a
 Similarly, if we want to rebind the variable b, it must be declared
as nonlocal
 The following example will further clarify this

433
Python Namespace and Scope(cont)
 Type the program in your Python IDE and run it

 In this program, three different variables a are defined in separate


namespaces and accessed accordingly
434
Python Namespace and Scope(cont)
 Let’s look at the next program

 Type the program into your Python IDE and run it

435
Python Namespace and Scope(cont)

Here, all reference and assignment are to the


global a due to the use of keyword global

436
Quiz 11

437
Quiz 11
 #Write your answer on the line next to the question
 1. What is the value of a after running the program?
 a = 100
 def myfunction():
 global a _____________
 a= 50
 return a
 myfunction()
 print(a)

 2. What is the output of running myfunction?


 a = 100
 def myfunction():
 global a ______________
 b = 5*a
 return b
 What is the output of myfunction()

438
Quiz 11
 3. What is the output of myfunction()?

 What is the output of myfunction()?


 a = 100
 def myfunction():
 a =30
 b = 5*a
 return b

 myfunction()

 _____________

439
Quiz 11
 4. What does the following code print?
 x=55
 def high(x): _____________
 return x

 print(high(x))

 5. What does the following code print?


 def pointless():
 z=77
 return z _____________

 print(pointless())

440
Quiz 11
 6. What does the following code print?
 i=50
 def fan():
 i=100 _____________
 return i

 print(fan())

 7. What does the following code print?


 nn=9
 if True: _____________
 nn=16

print(nn)

441
Quiz 11
 8. What does the following code print?
 cc=2
 if False:
 cc=66

 def car():
 if True:
 cc=40
 print(cc)

 print(car())
 print(cc)

 _____________

442
Quiz 11
 9. What does the following code print?
 qq=3
 def cycle():
 qq=7
 return qq

 print(qq)

 _____________

443
Quiz 11
 10. What is the value of dd printed?
 dd = 0
 def func1():
 dd=1
 return dd

 def func2():
 a=1
 dd = a+1
 return dd

 print(func1())
 print(func2())
 print(dd)

 _____________

444
Python Objects and Class
 In this section, you'll learn about the core functionality of Python,
Python objects and classes
 You'll learn what a class is, how to create it and use it in your
program

445
Python Objects and Class(cont)
 Class Example

446
Python Objects and Class(cont)
 Python is an object-oriented programming language
 Unlike procedure-oriented programming, where the main emphasis
is on functions, object-oriented programming focuses on objects
 An object is simply a collection of data (variables) and methods
(functions) that act on those data
 And a class is a blueprint for the object
 We can think of class as a sketch (prototype) of a house
 It contains all the details about the floors, doors, windows etc….
 Based on these descriptions we build the house as the house is the
object
 As, many houses can be made from a description, we can create
many objects from a class
 An object is also called an instance of a class and the process of
creating this object is called instantiation

447
Python Objects and Class(cont)
 Defining a Class in Python
 Like function definitions begin with the keyword def, in Python, we
define a class using the keyword class
 The first string is called docstring and has a brief description about
the class
 Although not mandatory, this is recommended
 Here is a simple class definition

 class MyNewClass:
 '''This is a docstring. I have created a new class'''
 pass

448
Python Objects and Class(cont)
 A class creates a new local namespace where all its attributes are
defined
 Attributes may be data or functions
 There are also special attributes in it that begins with double
underscores (__) (sometimes referred to a dunder methods)
 For example, __doc__ gives us the docstring of that class
 As soon as we define a class, a new class object is created with the
same name
 This class object allows us to access the different attributes as well
as to instantiate new objects of that class
 Another Example
 class MyClass:
 “This is my practice class“
 a = 10
 def func():
 print('Hello Python')
449
Python Objects and Class(cont)
 MyClass.a
 MyClass.func()
 MyClass.__doc__

450
Python Objects and Class(cont)
 Creating an Object in Python
 We saw that the class object could be used to access different
attributes
 It can also be used to create new object instances (instantiation) of
that class
 The procedure to create an object is like a function call
 ob = MyClass()
 This will create a new instance object named ob
 We can access attributes of objects using the object name prefix
 Attributes may be data or a method
 Methods of an object are corresponding functions of that class
 Any function object that is a class attribute defines a method for
objects of that class
 This means to say, since MyClass.func is a function object
(attribute of class), ob.func will be a method object

451
Python Objects and Class(cont)
 Let’s take a look at another example
 class MyClass:
 "This is my practice class"
 a = 10
 def func(self):
 print('Hello')

 # create a new MyClass


 ob = MyClass()
 print(MyClass.func)
 print(ob.func)
 #Calling func
 ob.func()

452
Python Objects and Class(cont)

453
Python Objects and Class(cont)
 You may have noticed the self parameter in function definition
inside the class but, we called the method simply as ob.func()
without any arguments and it worked
 This is because, whenever an object calls its method, the object
itself is passed as the first argument
 So, ob.func() translates into MyClass.func(ob)
 In general, calling a method with a list of n arguments is equivalent
to calling the corresponding function with an argument list that is
created by inserting the method's object before the first argument
 For these reasons, the first argument of the function in class must
be the object itself
 This is conventionally called self
 It can be named something else (your choice) but I highly
recommend to follow the convention

454
Python Objects and Class(cont)
 Constructors in Python
 Class functions that begins with double underscore (__) are called
special functions as they have special meaning
 Of one interest is the __init__() function
 This special function gets called whenever a new object of that
class is instantiated
 These type of functions are also called constructors in Object
Oriented Programming (OOP)
 We normally use it to initialize all the variables
 Let’s look at another example

455
Python Objects and Class(cont)
 class ComplexNumber:
 def __init__(self,r = 0,i = 0):
 self.real = r
 self.imag = i

 def getData(self):
 print("{0}+{1}j".format(self.real,self.imag))

 c1 = ComplexNumber(2,3)
 #Call the get data function
 c1.getData()
 #Create another Complex Number object
 c2 = ComplexNumber(4,5)
 #create a new attribute, “attr”
 c2.attr = 20
456
Python Objects and Class(cont)

457
Python Objects and Class(cont)
 In the previous example, we define a new class to represent
complex numbers (remember them from high-school math?)
 It has two functions, __init__() to initialize the variables (defaults
to zero) and getData() to display the number properly
 An interesting thing to note is that attributes of an object can be
created on the fly
 We created a new attribute attr (could have called it something
else) for object c2 and we can read it as well
 But this did not create that attribute for object c1 (please
keep this in mind)

458
Python Objects and Class(cont)
 Deleting Attributes and Objects
 Any attribute of an object can be deleted anytime, using the del
statement
 Try the following on the Python shell to see the output
 c1 = ComplexNumber(2,3)
 del c1.imag
 c1.getData()

459
Python Objects and Class(cont)
 del ComplexNumber.getData
 c1.getData()

 We can even delete the object itself, using the del statement.
 c1 = ComplexNumber(1,3)
 del c1
 c1
460
Python Objects and Class(cont)

 It is more complicated than that


 When we do c1 = ComplexNumber(1,3), a new instance object is
created in memory and the name c1 binds with it
 On the command del c1, this binding is removed and the name c1
is deleted from the corresponding namespace
 The object however continues to exist in memory and if no other
name is bound to it, it is later automatically destroyed
 This automatic destruction of unreferenced objects in Python is also
called garbage collection
461
Python Objects and Class(cont)

462
Class Inheritance
 Inheritance enables us to define a class that takes all the
functionality from parent class and allows us to add more
 In this section, you will learn to use inheritance in Python

463
Class Inheritance(cont)
 Inheritance is a powerful feature in object-oriented programming
 It refers to defining a new class with little or no modification to an
existing class
 The new class is called derived (or child) class and the one from
which it inherits is called the base (or parent) class
 Python Inheritance Syntax
 class BaseClass:
 Body of base class
 class DerivedClass(BaseClass):
 Body of derived class
 Derived class inherits features from the base class, adding new
features to it
 This results into re-usability of code

464
Class Inheritance(cont)
 Example of Inheritance in Python
 To demonstrate the use of inheritance, let us take an example
 A polygon is a closed figure with 3 or more sides
 Say, we have a class called Polygon defined as follows
 class Polygon:
 def __init__(self, no_of_sides):
PolygonClassExa
 self.n = no_of_sides self.sides = [0 for i in mple

range(no_of_sides)]
 def inputSides(self):
 self.sides = [float(input("Enter side "+str(i+1)+" : "))
 for i in range(self.n)]
 def dispSides(self):
 for i in range(self.n):
 print("Side",i+1,"is",self.sides[i])

465
Class Inheritance(cont)
 This class has data attributes to store the number of sides, n and
magnitude of each side as a list, sides
 Method inputSides() takes in magnitude of each side and similarly,
dispSides() will display these properly
 A triangle is a polygon with 3 sides (I remember this from high-school
geometry class)
 We can create a class called Triangle which inherits from Polygon
 This makes all the attributes available in class Polygon readily available in
Triangle
 We don't need to define them again (i.e. code re-usability)
 Triangle is defined as follows:

466
Class Inheritance(cont)
 Triangle is defined as follows:
 class Triangle(Polygon):
 def __init__(self):
 Polygon.__init__(self,3)
 def findArea(self):
 a, b, c = self.sides
 # calculate the semi-perimeter s = (a + b + c) / 2
 area = (s*(s-a)*(s-b)*(s-c)) ** 0.5
 print('The area of the triangle is %0.2f' %area)

TriangleClassInher
itanceExample

467
Class Inheritance(cont)
 However, class Triangle has a new method findArea() to find and
print the area of the triangle
 Let’s use the Triangle class

468
Class Inheritance(cont)
 We can see that, even though we did not define methods like
inputSides() or dispSides() for class Triangle, we were able to use
them
 If an attribute is not found in the class, search continues to the
base class
 This repeats recursively, if the base class is itself derived from
other classes
 Method Overriding in Python
 In the Triangle Class Example, notice that __init__() method was
defined in both classes, Triangle as well as Polygon
 When this happens, the method in the derived class overrides that
in the base class
 This is to say, __init__() in Triangle gets preference over the same
in Polygon

469
Class Inheritance(cont)
 Generally when overriding a base method, we tend to extend the
definition rather than simply replace it
 The same is being done by calling the method in base class from
the one in derived class (calling Polygon.__init__() from __init__()
in Triangle)
 A better option would be to use the built-in function super()
 So, super().__init__(3) is equivalent to Polygon.__init__(self,3)
and is preferred
 Two built-in functions isinstance() and issubclass() are used to
check inheritances
 Function isinstance() returns True if the object is an instance of
the class or other classes derived from it
 Each class in Python inherits from the base class object

470
Class Inheritance(cont)

471
Class Inheritance(cont)
 Similarly, issubclass() is used to check for class inheritance

472
Multiple Inheritance
 In this section, you'll learn what is multiple inheritance in Python
and how to use it in your program
 You'll also learn about multilevel inheritance and the method
resolution order

473
Multiple Inheritance(cont)
 Like C++, a class can be derived from more than one base classes
in Python
 This is called multiple inheritance
 In multiple inheritance, the features of all the base classes are
inherited into the derived class
 The syntax for multiple inheritance is similar to single inheritance
 Python Multiple Inheritance Example
 class Base1:
 pass

 class Base2:
 pass

 class MultiDerived(Base1, Base2):


 pass

474
Multiple Inheritance(cont)

475
Multiple Inheritance(cont)
 Multilevel Inheritance in Python
 On the other hand, we can also inherit from a derived class
 This is called multilevel inheritance
 It can be of any depth in Python
 In multilevel inheritance, features of the base class and the derived
class is inherited into the new derived class
 An Example
 class Base:
 pass

 class Derived1(Base):
 pass

 class Derived2(Derived1):
 pass
476
Multiple Inheritance(cont)

477
Multiple Inheritance(cont)
 Method Resolution Order in Python
 Every class in Python is derived from the class object
 It is the underlying base class in Python
 So technically, all other classes, either built-in or user-defined, are
derived classes and all objects are instances of object class

478
Multiple Inheritance(cont)
 In the multiple inheritance scenario, any specified attribute is
searched first in the current class
 If not found, the search continues into parent classes in depth-first,
left-right fashion without searching same class twice

 So, in our example of a MultiDerived class the search order is


[MultiDerived, Base1, Base2, object]
 This order is also called linearization of MultiDerived class and the
set of rules used to find this order is called Method Resolution
Order (MRO)
 MRO must prevent local precedence ordering and provide
monotonicity
 It ensures that a class always appears before its parents and in
case of multiple parents, the order is same as tuple of base classes

479
Multiple Inheritance(cont)
 MRO of a class can be viewed as the __mro__ attribute or mro()
method
 The former returns a tuple while latter returns a list

480
Multiple Inheritance(cont)
 Example – A more complex multiple inheritance example and its
visualization along with the MRO

481
Multiple Inheritance(cont)
 class X: pass
 class Y: pass
 class Z: pass
 class A(X,Y): pass
 class B(Y,Z): pass
 class M(B,A,Z): pass
 print(M.mro())

482
Quiz 12

483
Quiz 12
 1. What is Instantiation in terms of OOP(object oriented
programming) terminology?

 A. Deleting an instance of class


 B. Modifying an instance of class
 C. Copying an instance of class
 D. Creating an instance of class

484
Quiz 12
 2. What is the output of the following code?
 class test:
 def __init__(self,a="Hello World"):
 self.a=a

 def display(self):
 print(self.a)
 obj=test()
 obj.display()
 A. The program has an error because constructor can’t have default
arguments
 B. Nothing is displayed
 C. “Hello World” is displayed
 D. The program has an error display function doesn’t have
parameters

485
Quiz 12
 3. What is the output of the following code?
 class test:
 def __init__(self,a):
 self.a=a

 def display(self):
 print(self.a)
 obj=test()
 obj.display()
 A. Runs normally, doesn’t display anything
 B. Displays 0, which is the automatic default value
 C. Error as one argument is required while creating the object
 D. Error as display function requires additional argument

486
Quiz 12
 4. Is the following piece of code correct?
 class A:
 def __init__(self,b):
 self.b=b
 def display(self):
 print(self.b)

 obj=A("Hello")
 del obj

 A. True
 B. False

487
Quiz 12
 5. What is the output of the following code?
 class Demo:
 def __init__(self):
 pass
 def test(self):
 print(“hello”)
 obj = Demo()
 obj.test()

 A. Exception is thrown
 B. __init__
 C. Demo
 D. hello
 E. None of the above

488
Quiz 12
 6. What is the output of the following piece of code?
 class A:
 def one(self):
 return self.two()

 def two(self):
 return 'A'

 class B(A):
 def two(self):
 return 'B'
 obj1=A()
 obj2=B()
 print(obj1.two(),obj2.two())
 A. A A
 B. A B
 C. B B
 D. An exception is thrown

489
Quiz 12
 7. What type of inheritance is illustrated in the following
piece of code?
 class A():
 pass
 class B():
 pass
 class C(A,B):
 pass

 A. Multi-level inheritance
 B. Multiple inheritance
 C. Hierarchical inheritance
 D. Single-level inheritance

490
Quiz 12
 8. What is the output of the following piece of code?
 class Test:
 def __init__(self):
 self.x = 0
 class Derived_Test(Test):
 def __init__(self):
 self.y = 1
 def main():
 b = Derived_Test()
 print(b.x,b.y)
 main()
 A. 0 1
 B. 0 0
 C. Error because class B inherits A but variable x isn’t inherited
 D. Error because when object is created, argument must be passed like
Derived_Test(1)

491
Quiz 12
 9. What is the output of the following piece of code?
 class A():
 def display(self):
 print("A display()")
 class B(A):
 pass
 obj = B()
 obj.display()

 A. Invalid syntax for inheritance


 B. Error because when object is created, argument must be passed
 C. Nothing is printed
 D. A display()

492
Quiz 12
 10. Suppose B is a subclass of A, to invoke the __init__
method in A from B, what is the line of code you should
write?

 A. A.__init__(self)
 B. B.__init__(self)
 C. A.__init__(B)
 D. B.__init__(A)
 E. None of the above

493
Operator Overloading
 You can change the meaning of an operator in Python depending
upon the operands used
 This practice is known as operating overloading

494
Operator Overloading(cont)
 Python operators work for built-in classes
 But same operator behaves differently with different types
 For example, the + operator will, perform arithmetic addition on
two numbers, merge two lists and concatenate two strings
 This feature in Python, that allows same operator to have different
meaning according to the context is called operator overloading
 So what happens when we use them with objects of a user-defined
class?
 Let us consider the following class, which tries to simulate a point
in 2-D coordinate system (Cartesian)
 class Point:
 def __init__(self, x = 0, y = 0):
 self.x = x
 self.y = y

495
Operator Overloading(cont)
 Run the code for class Point and try the following below
 p1 = Point(4,4)
 p2 = Point(0,0)
 p1 + p2

496
Operator Overloading(cont)
 We have a TypeError raised since Python didn't know how to add
two Point objects together
 However, the good news is that we can teach this to Python
through operator overloading
 But first, let's get a notion about special functions
 Special Functions in Python
 Class functions that begins with double underscore __ are called
special functions in Python (sometimes called “dunder” methods)
 This is because, well, they are not ordinary
 The __init__() function, is one of them
 It gets called every time we create a new object of that class
 There are a lot of special functions in Python
 Using special functions, we can make our class compatible with
built-in functions

497
Operator Overloading(cont)
 Example
 p1 = Point(2,3)
 print(p1)

 define __str__() method in our class, so we can control how it


gets printed
 So, let's add this to our class

498
Operator Overloading(cont)
 class Point:
 def __init__(self, x = 0, y = 0):
 self.x = x
 self.y = y
 def __str__(self):
 return "({0},{1})".format(self.x,self.y)

 p1 = Point(2,3)
 print(p1)

499
Operator Overloading(cont)
 Looks much better
 Overloading the + Operator in Python
 To overload the + sign, we will need to implement __add__()
function in the class
 We can do whatever we like, inside this function
 But it makes sense to return a Point object of the coordinate sum
 class Point:
 def __init__(self, x = 0, y = 0):
 self.x = x
 self.y = y
 def __str__(self):
 return "({0},{1})".format(self.x,self.y)
 def __add__(self,other):
 x = self.x + other.x
 y = self.y + other.y
 return Point(x,y)

500
Operator Overloading(cont)
 Now let’s try the addition again

501
Operator Overloading(cont)
 You could have done it this way

 What happens is that, when you do p1 + p2, Python will call


p1.__add__(p2) which in turn is Point.__add__(p1,p2)

 You can overload other operators as well, see the chart on the next
slide

502
Operator Overloading(cont)

503
Operator Overloading(cont)
 Overloading Comparison Operators in Python
 Python does not limit operator overloading to arithmetic operators
only
 We can overload comparison operators as well
 Suppose, we wanted to implement the less than symbol “<“ in our
Point class
 Let us compare the magnitude of these points from the origin and
return the result for this purpose
 If you remember magnitude of a point in the Cartesian plane, it is |
(a,b)| = square_root(

c is the magnitude of the


point(a,b)

504
Operator Overloading(cont)
 class Point:
 def __init__(self, x = 0, y = 0):
 self.x = x
 self.y = y

 def __str__(self):
 return "({0},{1})".format(self.x,self.y)

 def __lt__(self,other):
 self_mag = (self.x ** 2) + (self.y ** 2)
 other_mag = (other.x ** 2) + (other.y ** 2)
 return self_mag < other_mag

505
Operator Overloading(cont)

506
Operator Overloading(cont)

507
Quiz 13

508
Quiz 13
 1. Which is the output of the following code snippet?

 class Vase:
 def __init__(self, volume):
 self.volume = volume
 v1 = Vase(100)
 v2 = Vase(200)
 print(v1 + v2)

 A 100
 B 300
 C 200
 D unsupported operand type(s) for +: 'Vase' and 'Vase'

509
Quiz 13
 2. Which of the following will print True after the code executes?
 a = foo(2)
 b = foo(3)
 print(a < b)
 A B
 class foo: class foo:
def __init__(self, x):
 def __init__(self, x):
self.x = x
 self.x = x def __less__(self, other):
 def __lt__(self, other): if self.x > other.x:
 if self.x < other.x: return False
 return False else:
 else: return True
 return True

C D
class foo: class foo:
def __init__(self, x): def __init__(self, x):
self.x = x self.x = x
def __lt__(self, other): def __less__(self, other):
if self.x < other.x: if self.x < other.x:
return True return False
else: else:
return False return True
510
Quiz 13
 3. Which function overloads the + operator?
 A __add__()
 B __plus__()
 C __sum__()
 D None of the above

 4. Which operator is overloaded by __invert__()?


 A !
 B ~
 C ^
 D –

511
Quiz 13
 5. Which function overloads the == operator?
 A __eq__()
 B __equ__()
 C __isequal__()
 D None of the above

 6. Which operator is overloaded by __lg__()?


 A<
 B>
 C !=
 D None of the above

512
Quiz 13
 7. Which function overloads the >> operator?
 A __rshift__()
 B __gt__()
 C __ge__()
 D None of the above

 8. Which operator is overloaded by the __or__() function?


 A ||
 B|
 C //
 D/

513
Quiz 13
 9. Which function overloads the // operator?
 A __div__()
 B __ceildiv__()
 C __floordiv__()
 D __truediv__()

 10. Let A and B be objects of class Foo. Which functions are


called when print(A + B) is executed?
 A __add__(), __str__()
 B __str__(), __add__()
 C __sum__(), __str__()
 D __str__(), __sum__()

514
DATE TIME

51
Date Time
 Python has a module named datetime to work with dates and time
 Example
 Get Current Date and Time

 import datetime

 curr_datetime = datetime.datetime.now()
 print(curr_datetime)

 We have imported datetime module using import datetime


statement
 One of the classes defined in the datetime module is datetime class
 We then used now() method to create a datetime object containing
the current local date and time

516
Date Time(cont)
 Example
 Get Current Date

 import datetime

 curr_date = datetime.date.today()
 print(curr_date)

517
Date Time(cont)
 We have used the today() method defined in the date class to get a
date object containing the current local date

 Use the dir function to get all the attributes a module


 Example
 import datetime
 dir(datetime)

518
Date Time(cont)
 Commonly used classes in the datetime module are:
 date Class
 time Class
 datetime Class
 timedelta Class

 datetime.date Class
 You can instantiate date objects from the date class
 A date object represents a date (year, month and day)

519
Date Time(cont)
 Example:
 Date object to represent a date

 import datetime

 d = datetime.date(2019, 4, 13)
 print(d)

 date() in the above example is a constructor of the date class


 The constructor takes three arguments: year, month and day.
 The variable d is a date object

520
Date Time(cont)
 Example
 Get current date
 You can create a date object containing the current date by using a
classmethod named today()

 from datetime import date

 today = date.today()

 print("Current date =", today)

521
Date Time(cont)
 Example
 Get date from a timestamp
 We can also create date objects from a timestamp
 A Unix timestamp is the number of seconds between a particular
date and January 1, 1970 at UTC (Consolidated Universal time)
 You can convert a timestamp to date using fromtimestamp()
method.

 from datetime import date

 timestamp = date.fromtimestamp(100000000)
 print("Date =", timestamp)

522
Date Time(cont)
 Example
 Access today's year, month and day
 We can get year, month, day, day of the week etc. from the date
object

 from datetime import date

 # get today's date


 today = date.today()

 print("Current year:", today.year)


 print("Current month:", today.month)
 print("Current day:", today.day)

523
Date Time(cont)
 datetime.time
 A time object instantiated from the time class represents
the local time
 Example
 Time object to represent time
 from datetime import time
 # time(hour, minute and second)
 b = time(10, 35, 26)
 print("b =", b)

 # time(hour, minute and second)


 c = time(hour = 1, minute = 11, second = 11)
 print("c =", c)

 # time(hour, minute, second, microsecond)


 d = time(10, 30, 50, 6000)
 print("d =", d)

524
Date Time(cont)
 Example
 Access hour, minute, second and microsecond
 With time object, you can easily access its attributes such as hour,
minute , seconds, and microseconds

 from datetime import time

 t = time(5, 30, 23)

 print("hour =", t.hour)


 print("minute =", t.minute)
 print("second =", t.second)
 print("microsecond =", t.microsecond)

525
Date Time(cont)
 datetime.datetime
 The datetime module has a class named dateclass that can contain
information from both date and time objects.

 Example
 Python datetime object

 from datetime import datetime


 #datetime(year, month, day)
 a = datetime(2018, 11, 28)
 print(a)
 # datetime(year, month, day, hour, minute, second, microsecond)
 b = datetime(2012, 11, 22, 5, 27, 29, 342000)
 print(b)

526
Date Time(cont)

527
Date Time(cont)
 The first three arguments year, month and day in the datetime()
constructor are mandatory

 Example
 Access year, month, hour, minute and timestamp

 from datetime import datetime

 a = datetime(2016, 10, 25, 21, 25, 20, 300000)


 print("year =", a.year)
 print("month =", a.month)
 print("hour =", a.hour)
 print("minute =", a.minute)
 print("timestamp =", a.timestamp())

528
Date Time(cont)

529
Date Time(cont)
 datetime.timedelta
 A timedelta object represents the difference between two dates or
times
 Example
 Difference between two dates and times
 from datetime import datetime, date
 t1 = date(year = 2018, month = 8, day = 21)
 t2 = date(year = 2017, month = 11, day = 20)
 t3 = t1 - t2
 print("t3 =", t3)
 t4 = datetime(year = 2018, month = 8, day = 22, hour = 11, minute = 19, second
= 38)
 t5 = datetime(year = 2019, month = 7, day = 13, hour = 6, minute = 57, second =
23)
 t6 = t4 - t5
 print("t6 =", t6)
 print("type of t3 =", type(t3))
 print("type of t6 =", type(t6))

530
Date Time(cont)

531
Date Time(cont)
 Example
 Difference between two timedelta objects

 from datetime import timedelta

 t1 = timedelta(weeks = 3, days = 6, hours = 4, seconds = 30)


 t2 = timedelta(days = 6, hours = 12, minutes = 5, seconds = 25)
 t3 = t1 - t2
 print("t3 =", t3)

532
Date Time(cont)
 Printing negative timedelta object

 from datetime import timedelta

 t1 = timedelta(seconds = 59)
 t2 = timedelta(seconds = 24)
 t3 = t2-t1

 print("t3 =", t3)


 print("t3 =", abs(t3))

 Notice how Python handles the negative time


 -35 seconds is handled as -1day + 23:59:25

533
Date Time(cont)
 Time duration in seconds
 Total number of seconds in a timedelta object using total_seconds()
method

 from datetime import timedelta

 t = timedelta(days = 2, hours = 1, seconds = 30, microseconds =


60000)
 print("total seconds =", t.total_seconds())

534
Date Time(cont)
 Python format datetime
 Dates and times may be represented in many different ways
 You can use mm/dd/yyyy, dd/mm/yyyy, yyyy-mm-dd etc…
 Python has strftime() and strptime() methods to handle this

 Python strftime() - datetime object to string


 The strftime() method is defined under classes date, datetime and
time
 The method creates a formatted string from a given date, datetime
or time object

535
Date Time(cont)
 Example
 Format date using strftime()

 from datetime import datetime


 # current date and time
 now = datetime.now()

 t = now.strftime("%H:%M:%S")
 print("time:", t)
 s1 = now.strftime("%m/%d/%Y, %H:%M:%S")
 # mm/dd/YY H:M:S format
 print("s1:", s1)
 s2 = now.strftime("%d/%m/%Y, %H:%M:%S")
 # dd/mm/YY H:M:S format
 print("s2:", s2)

536
Date Time(cont)

537
Date Time(cont)
 Python strptime() - string to datetime
 The strptime() method creates a datetime object from a given
string (representing date and time)
 Example
 strptime()

 from datetime import datetime

 date_string = "22 June, 2012"


 print("date_string =", date_string)

 date_object = datetime.strptime(date_string, "%d %B, %Y")


 print("date_object =", date_object)

538
Date Time(cont)

539
Date Time(cont)
 For a successful conversion, the format in the date_string = “22
June 2018” must match the directive %d %B, %Y in the strptime
function
 There are a lot of directives and I will show you what options there
other than %d %B, %Y
 Directives:
 %a - abbreviated weekday name
 %A - full weekday name
 %b - abbreviated month name
 %B - full month name
 %c - preferred date and time representation
 %C - century number (the year divided by 100, range 00 to 99)
 %d - day of the month (01 to 31)
 %D - same as %m/%d/%y
 %e - day of the month (1 to 31)
 %g - like %G, but without the century
 %G - 4-digit year corresponding to the ISO week number (see %V).
 %h - same as %b
 %H - hour, using a 24-hour clock (00 to 23)

540
Date Time(cont)
 %I - hour, using a 12-hour clock (01 to 12)
 %j - day of the year (001 to 366)
 %m - month (01 to 12)
 %M - minute
 %n - newline character
 %p - either am or pm according to the given time value
 %r - time in a.m. and p.m. notation
 %R - time in 24 hour notation
 %S - second
 %t - tab character
 %T - current time, equal to %H:%M:%S
 %u - weekday as a number (1 to 7), Monday=1. Warning: In Sun
Solaris Sunday=1
 %U - week number of the current year, starting with the first
Sunday as the first day of the week

541
Date Time(cont)
 %V - The ISO 8601-week number of the current year (01 to 53),
where week 1 is the first week that has at least 4 days in the
current year, and with Monday as the first day of the week
 %W - week number of the current year, starting with the first
Monday as the first day of the first week
 %w - day of the week as a decimal, Sunday=0
 %x - preferred date representation without the time
 %X - preferred time representation without the date
 %y - year without a century (range 00 to 99)
 %Y - year including the century
 %Z or %z - time zone or name or abbreviation
 %% - a literal % character
 This is almost like a mini-language, but it’s worth understanding

542
Date Time(cont)
 You can see then 22 June 2012 matches up with %d %B %Y
 Class Question
 Which format does “15/06/2014” correspond with?
 Note
 Month is in double digit %m
 Day is single to two digits %d
 Full year is displayed  %Y
 Let’s try
 date_string = “15/06/2014"
 print("date_string =", date_string)

 date_object = datetime.strptime(date_string, "%d/%m/%Y")


 print("date_object =", date_object)

543
Date Time(cont)

544
Date Time(cont)
 Timezone in Python
 If you are interested in displaying time and dates in a different time
zone, Python has a package for you, and it is pytZ (use pip install
pytZ to install)
 Example
 from datetime import datetime
 import pytz
 local = datetime.now()
 print("Local:", local.strftime("%m/%d/%Y, %H:%M:%S"))
 tz_NY = pytz.timezone('America/New_York')
 datetime_NY = datetime.now(tz_NY)
 print("NY:", datetime_NY.strftime("%m/%d/%Y, %H:%M:%S"))
 tz_London = pytz.timezone('Europe/London')
 datetime_London = datetime.now(tz_London)
 print("London:", datetime_London.strftime("%m/%d/%Y, %H:%M:%S"))

545
Date Time(cont)

546
Date Time(cont)
 Suppose that you are given a date (datetime object), and want to
determine the day of the week?
 There is a method called weekday that will determine the day of
the week
 Example
 today = datetime.datetime(2017, 10, 20)
 today.weekday() # look for this
 Return the day of the week as an integer, where Monday is 0 and Sunday is
6
Value Day of the week
0 Monday
1 Tuesday
2 Wednesday
3 Thursday
4 Friday
5 Saturday
6 Sunday

 The day of the week is Friday


547
Date Time(cont)
 There is another method called isoweekday()
 The function isoweekday() returns an integer value corresponding
to the day of the week
 Unlike the weekday() method, date.isoweekday() returns the value
1 for Monday and increments it by one for the subsequent days
Value Day of the week
1 Monday
2 Tuesday
3 Wednesday
4 Thursday
5 Friday
6 Saturday
7 Sunday

548
Date Time(cont)
 Example:
 import datetime
 daysOftheWeek = ("ISO Week days start from 1",
 "Monday",
 "Tuesday",
 "Wednesday",
 "Thursday",
 "Friday",
 "Saturday",
 "Sunday"
 )
 # Christmas Eve
 xmasEve = datetime.date(2019,12,24)
 isoWeekDay = xmasEve.isoweekday()
 print("Christmas Eve this year falls on a {}".format(daysOftheWeek[isoWeekDay]))
 # Day after Christmas
 dayAfterXmas = datetime.date(2019,12,26)
 isoWeekDay = dayAfterXmas.isoweekday()
 print("Day after Christmas this year falls on a {}".format(daysOftheWeek[isoWeekDay]))

549
Quiz 14

550
Quiz 14
 1. The output of the snippet of code shown below is:
 import datetime
 d=datetime.date(2017,8,21)
 print(d)

 A Error
 B 2017-08-21
 C 2017-8-21
 D 21-7-2017

551
Quiz 14
 2. What is the output of the snippet of code shown below?
 import datetime
 d=datetime.date(2017,06,18)
 print(d)

 A Error
 B 2017-06-18
 C 18-06-2017
 D 06-18-2017

552
Quiz 14
 3. What is the output of the code shown below if the system
date is 21th July, 2011?
 tday=datetime.date.today()
 print(tday.month)

 A July
 B Jul
 C 07
 D7
 E Error

553
Quiz 14
 4. What is the output of the code shown if the system date is
20th June, 2015?
 import datetime
 tday=datetime.date.today()
 print(tday)

 A 20-06-2015
 B 06-20-2015
 C 2015-06-20
 D Error

554
Quiz 14
 5. What is the output of the code shown below if the system
date is 18th June, 2017 (Sunday)?

 tday=datetime.date.today()
 print(tday.weekday())

 A 6
 B 1
 C 0
 D 7

555
Quiz 14
 6. What is the output of the following code if the system
date is 22st June, 2017 (Thursday)?

 tday=datetime.date.today()
 print(tday.isoweekday())

 A Wed
 B Wednesday
 C2
 D3
 E4

556
Quiz 14
 7. Point out the error (if any) in the code shown below if the
system date is 18th June, 2018?
 tday=datetime.date.today()
 bday=datetime.date(2018,9,18)
 till_bday=bday-tday
 print(till_bday)

 A 3 months, 0:00:00
 B 90 days, 0:00:00
 C 3 months 2 days, 0:00:00
 D 92 days, 0:00:00
 E Error

557
Quiz 14
 8. Which of the following will throw an error if used after
the code shown below?
 tday=datetime.date.today()
 bday=datetime.date(2017,9,18)
 t_day=bday-tday

 A print(t_day.seconds)
 B print(t_day.months)
 C print(t_day.max)
 D print(t_day.resolution)

558
Quiz 14
 9. What is the output of the code shown below if the system
date is: 6/19/2018

 tday=datetime.date.today()
 tdelta=datetime.timedelta(days=10)
 print(tday+tdelta)

 A 2018-16-19
 B 2018-06-9
 C 2018-06-29
 D Error

559
Quiz 14
 10. Which of the following functions can be used to find the
coordinated universal time, assuming that the datetime
module has already been imported? (Select only one)

 import datetime

 A datetime.utc()
 B datetime.datetime.utc()
 C datetime.utcnow()
 D datetime.datetime.utcnow()

560
Regular Expressions

561
Regular Expressions(cont)
 In this section, I will give a brief introduction (there are entire
courses on regex) to regular expressions

 A RegEx, or Regular Expression, is a sequence of characters that


forms a search pattern

 RegEx can be used to check if a string contains the specified search


pattern – most of the time, that’s what I need to do

 Python has a built-in package called re, which can be used to work
with Regular Expressions

 Import the re module:

 import re

562
Regular Expressions(cont)
 Example:
 Search the text/string to see if it starts with “Python" and ends
with “language":

 import re
 txt ="Python is a programming language"
 myregsearch = re.search("^Python.*language$", txt)
 if myregsearch:
 print("yes")
 else:
 print("No")

563
Regular Expressions(cont)
Here are some regex functions that search for string matches

RegEx Functions

The re module offers a set of functions that allows us to search a string for a match:

Function Description

Returns a list containing all matches


findall
Returns a Match object if there is a match anywhere
in the string
search
Returns a list where the string has been split at each
match
split
Replaces one or many matches with a string

sub

564
Regular Expressions(cont)
 Here are some meta-characters that you are likely to see in regular
expression statements
Metacharacters

Metacharacters are characters with a special meaning:

Character Description Example


[] A set of characters "[a-z]"
\ Signals a special sequence (can also be used to
"\d"
escape special chara
. Any character (except newline character) "Pyt..n"
^ Starts with "^Python"
$ Ends with "Language$"
* Zero or more occurrences "pyt*"
+ One or more occurrences "pyt+"
{} Exactly the specified number of occurrences "py{2}"
| Either or "Python|R"
() Capture and group

565
Regular Expressions(cont)
 Here are some special sequences you will see in regular expression
statements

Special Sequences
A special sequence is a \ followed by one of the characters in the list below, and has a special

Character Description Example


\A Returns a match if the specified "\APython"
characters are at the beginning of the
string
\b Returns a match where the specified r"\bain"
characters are at the beginning or at the
end of a word
(the "r" in the beginning is making sure r"ain\b"
that the string is being treated as a "raw
string")
\B Returns a match where the specified r"\Bain"
characters are present, but NOT at the
beginning (or at the end) of a word
(the "r" in the beginning is making sure r"ain\B"
that the string is being treated as a "raw
string")
\d Returns a match where the string contains "\d"
digits (numbers from 0-9)
\D Returns a match where the string DOES "\D"
NOT contain digits
\s Returns a match where the string contains "\s"
a white space character
\S Returns a match where the string DOES "\S"
NOT contain a white space character
\w Returns a match where the string contains "\w"
any word characters (characters from a to
Z, digits from 0-9, and the underscore _
character)
\W Returns a match where the string DOES "\W"
NOT contain any word characters
\Z Returns a match if the specified "Python\Z"
characters are at the end of the string

566
Regular Expressions(cont)

Sets
A set is a set of characters inside a pair of square brackets [] with a
special meaning:

Set Description
[arn] Returns a match where one of the specified
characters (a, r, or n) are present
[a-n] Returns a match for any lower case
character, alphabetically between a and n
[^arn] Returns a match for any character
EXCEPT a, r, and n
[0123] Returns a match where any of the specified
digits (0, 1, 2, or 3) are present
[0-9] Returns a match for any digit
between 0 and 9
[0-5][0-9] Returns a match for any two-digit numbers
from 00 and 59
[a-zA-Z] Returns a match for any character
alphabetically between a and z, lower case
OR upper case
[+] In sets, +, *, ., |, (), $,{} has no special
meaning, so [+] means: return a match for
any + character in the string

567
Regular Expressions(cont)
 Now you might be wondering, if matching is case-sensitive?
 The answer is a resounding yes!
 Let’s go back to our previous example and change Python to
python (lower case p instead of upper case)
 import re
 txt ="Python is a programming language"
 myregsearch = re.search("^python.*language$", txt)
 if myregsearch:
 print("yes")
 else:
 print("No")

568
Regular Expressions(cont)
 Let’s look at some other functions
 The findall() Function
 The findall() function returns a list containing all matches
 Example
 Print a list of all matches:

 import re

 txt = “Python is a programming language. Python is great"


 x = re.findall(“on", txt)
 print(x)
 The list contains the matches in the order they are found

 If no matches are found, an empty list is returned

569
Regular Expressions(cont)
 The search() Function
 The search() function searches the string for a match, and returns
a Match object if there is a match – it will check all lines of an input
string
 If there is more than one match, only the first occurrence of the
match will be returned
 If no matches are found, the value None is returned
 Search for the first white-space character in the text

 Example
 import re
 txt = “Python is a programming language"
 x = re.search("\s", txt)
 print("The first white-space character is located in position:",
x.start())

570
Regular Expressions(cont)
 Example

 import re
 txt = “R is great for statistics"
 x = re.search(“java", txt)
 print(x)

571
Regular Expressions(cont)
 The split() Function
 The split() function returns a list where the string has been split at
each match:

 Example
 Split at each white-space character
 Output is a list of words split by the white-space character
 import re
 txt = “Python is a programming language"
 x = re.split("\s", txt)
 print(x)

572
Regular Expressions(cont)
 You can control the number of occurrences by specifying the
maxsplit parameter

 Example
 Split the string only at the second occurrence of the white-space

 import re
 txt = “R is used by statisticians"
 x = re.split("\s", txt, 2)
 print(x)

573
Regular Expressions(cont)
 The sub() Function
 The sub() function replaces the matches found with a text of the
user’s choice

 Example
 Replace every white-space character with the underscore _
 import re

 txt = “Python is awesome"


 x = re.sub("\s", “_", txt)
 print(x)

574
Regular Expressions(cont)
 You can control the number of replacements by specifying the
count parameter

 Example
 Replace the first 2 occurrences

 import re

 txt = “Python is easy to learn"


 x = re.sub("\s", “_", txt, 2)
 print(x)

575
Regular Expressions(cont)
 How about replacing multiple whitespaces with just one?

 Example:
 import re
 txt = "Python is great "
 x = re.sub("\s+", " ", txt)
 print(x)

576
Regular Expressions(cont)
 The re.match() function
 re.match() function will search the regular expression pattern and
return the first occurrence
 This method checks for a match only at the beginning of the string
 So, if a match is found in the first line, it returns the match object
 But if a match is found in some other line, it returns null

 Example
 Do a search that will return a Match Object
 import re
 txt = “Python is great. Python is easy to learn"
 x = re.match(“Py", txt)
 print(x) #this will print an object
 #span(0,2), pattern starts at position
 0 and ends at 2
577
Regular Expressions(cont)
 Output prints the position (start- and end-position) of the first
match occurrence

 Compare re.match() and re.search()


 Example
 import re
 txt = "R is great. Python is easy to learn"
 x = re.match("Py", txt)
 print(x) #this will print an object
 print("\n")
 xx = re.search("Py", txt)
 print(xx)
 Observe that re.match outputs None and
 re.search outputs span(12,14), i.e. “Py”
 starts at 12 and ends at 14
578
Regular Expressions(cont)
 So far, we have not taken into account case sensitivity
 Can we get matches that are not case sensitive?
 Lucky for us, that there is a flag, re.I that takes this into account

 import re
 txt ="Python is useful for statistics and Really good"
 x = re.search("python", txt, flags=re.I)
 print(x)

579
Regular Expressions(cont)
 What about if we have text on multiple lines ?

 What would happen if I wanted to search for lines that start with
python, in a multi-line text?

 import re
 searchtxt = """ R
 python
 python
 java"""

 myregsearch = re.findall("^python", searchtxt)


 print(myregsearch)
 We get no output as seen by the blank list

580
Regular Expressions(cont)
 However, we can see two lines that start with python? What do we
have to do to output these?
 There is a flag we can use, i.e. re.M
 import re
 searchtxt = """ R
 python
 python
 java"""

 myregsearch = re.findall("^python", searchtxt, flags=re.M)


 print(myregsearch)

 This time, we get results

581
Regular Expressions(cont)
 Can we use the re.M and re.I (multi-line and case-insensitive)
together?

 Answer is yes!

 import re
 searchtxt = """ R
 Python
 Python
 java"""

 myregsearch = re.findall("^python", searchtxt, flags=re.M | re.I)


 print(myregsearch)

582
Quiz 14-A
 1. What is line of Python code imports the re module?
 A Import re
 B import RE
 C import re
 D Import RE

 2. Which flag will make your search case-insensitive?


 A re.I
 B re.c-I
 C re.CI
 D re.C-I

583
Quiz 14-A
 3. Which flag will search over multiple lines?
 A re.ml
 B re.M
 C re.m
 D re.ML

 4. _______ is used to search through a string starting at its


beginning. It returns None if no match is found
 A re.match()
 B re.method()
 C re.Match()
 D re.search()

584
Quiz 14-A
 5. _______ searches the entire string, not just starting at
the beginning. It returns None if no match is found
 A re.match()
 B re.Search()
 C re.Method()
 D re.search()

585
Quiz 14-A
 6. Will this code match the regular expression?
 import re
 my_string = “Python is an awesome language”
 match_result = re.match(“python”, my_string, re.I)

 A True
 B False

 7. Will this code match the regular expression?


 import re
 my_string = “Java is low level programming language”
 match_result = re.match(“java”, my_string)

 A True
 B False
586
Iterators
 Iterators are objects that can be iterated upon
 In this section, you will learn how iterator works and how you can
build your own iterator using __iter__ and __next__ methods

587
Iterators(cont)
 Iterators are everywhere in Python
 They are elegantly implemented within for loops, comprehensions,
generators etc. but hidden from plain sight
 Iterator in Python is simply an object that can be iterated
upon
 An object which will return data, one element at a time
 Technically speaking, Python iterator object must implement two
special methods, __iter__() and __next__(), collectively called
the iterator protocol
 An object is called iterable if we can get an iterator from it
 Most of built-in containers in Python like; list, tuple, string etc. are
iterables
 The iter() function (which in turn calls the __iter__() method)
returns an iterator from them

588
Iterators(cont)
 Iterating Through an Iterator in Python
 We use the next() function to manually iterate through all the
items of an iterator
 When we reach the end and there is no more data to be returned,
it will raise StopIteration
 An Example

IterExample

589
Iterators(cont)
 Open the Iterexample.txt (see last slide) and run the code

590
Iterators(cont)
 A more elegant way of automatically iterating is by using the for
loop

 Using this, we can iterate over any object that can return an
iterator, for example list, string, file etc

 for element in my_list:


 print(element)

591
Iterators(cont)
 How a for loop really works?
 In the previous example, the for loop was able to iterate
automatically through the list
 In fact the for loop can iterate over any iterable
 Let's take a closer look at how the for loop is actually implemented
in Python

 for element in iterable:


 # do something with element
 # continue with code

592
Iterators(cont)
 This is implemented as:
 # infinite loop
 while True:
 try:
 # get the next item
 element = next(iter_obj)
 # do something with element
 except StopIteration:
 # if StopIteration is raised, break from loop
 break

593
Iterators(cont)
 Here’s what’s going on with an infinite loop
 The for loop creates an iterator object, iter_obj by calling iter()
on the iterable
 Ironically, this for loop is implemented as an infinite while loop
 Inside the loop, it calls next() to get the next element and
executes the body of the for loop with this value
 After all the items exhaust, StopIteration is raised which is
internally caught and the loop ends
 Note that any other kind of exception will pass through

 Remember:
 Here’s how to create an iterable
 # create an iterator object from that iterable
 iter_obj = iter(iterable)

594
Iterators(cont)
 Building Your Own Iterator in Python
 Building an iterator from scratch is easy in Python
 We just have to implement the methods __iter__() and __next__()
 The __iter__() method returns the iterator object itself
 If required, some initialization can be performed
 The __next__() method must return the next item in the sequence
 On reaching the end, and in subsequent calls, it must raise
StopIteration
 Here, we show an example that will give us next power of 3 in each
iteration
 Power exponent starts from zero up to a user set number

MyOwnIterator.txt

595
Iterators(cont)
 Open MyOwnIterator.txt and run the code

596
Iterators(cont)
 We can also use a for loop to iterate over our iterator class

 for i in PowThree(4):
 print(i)

597
Iterators(cont)
 Python Infinite Iterators
 It is not necessary that the items in an iterator object have to
exhaust
 There can be infinite iterators (which never ends)
 Care needs to be exercised when handling such iterators
 Here is a simple example to demonstrate infinite iterators
 The built-in function iter() can be called with two arguments where
the first argument must be a callable object (function) and second
is the sentinel
 The iterator calls this function until the returned value is equal to
the sentinel
 Example

598
Iterators(cont)
 The int() function always returns 0
 So passing it as iter(int,1) will return an iterator that calls int()
until the returned value equals 1
 However this will never happen, and we get an infinite iterator
 We can also build our own infinite iterators
 The following iterator will return all the odd numbers
 class InfIter:
 """Infinite iterator to return all
 odd numbers"""

 def __iter__(self):
 self.num = 1 MyInfIterator.txt
 return self

 def __next__(self):
 num = self.num
 self.num += 2
 return num

599
Iterators(cont)
 Run the code

 All the odd numbers are printed

600
Iterators(cont)
 Class Exercise:

 Change the code so that all even numbers are printed

601
Iterators(cont)
 The advantage of using iterators is that they save resources
 In the previous example, we could get all the odd numbers without
storing the entire number system in memory
 We can have infinite items (theoretically) stored in finite memory
 Using iterators makes your code look good
 You may not believe this, but there is an easier way to create
iterators in Python and we will see this when moving on to
generators

602
Quiz 15

603
Quiz 15
 1. Iterators are more efficient in using memory than lists
 A True
 B False

 2. What is the output of the code snippet below?


 a = [1,2,3]
 a = iter(a)
 next(a)
 next(a)
 next(a)
 next(a)
 A3
 B Break Iteration is raised
 C1
 D Stop Iteration is raised
604
Quiz 15
 3. What is the output of the code snippet below?
 a = [1,2,3,4]
 a = iter(a)
 print(list(a))

 A Error
 B 1234
 C (1,2,3,4)
 D [1, 2,3,4]
 E None of the above

605
Quiz 15
 4. What is the output of the following code snippet below?

 a =‘help’
 a = iter(a)
 print(a[1])

 A e
 B TypeError: 'str_iterator' object is not subscriptable
 C h
 D help

606
Quiz 15
 5. What is the output of the code snippet below?
 class Counter:
 def __init__(self, low, high):
 self.current = low
A output is 3 4 5
 self.high = high
B output is 5 6 7
C output is 3 4 5 6 7 8
 def __iter__(self):
D output is 3 4 5 6
 return self
E None of the above
 def __next__(self):
 if self.current > self.high:
 raise StopIteration
 else:
 self.current += 1
 return self.current - 1

 for c in Counter(3, 8):


 print( c)

607
Generators
 Python Generators
 In this section, you'll learn how to create iterations easily using
Python generators, how is it different from iterators and normal
functions, and why you should use it

608
Generators(cont)
 There is a lot of overhead in building an iterator in Python; we have
to implement a class with __iter__() and __next__() method,
keep track of internal states, raise StopIteration when there was no
values to be returned
 This is both lengthy and counter intuitive
 Generator comes into rescue in such situations
 Python generators are a simple way of creating iterators
 All the overhead we mentioned above are automatically handled by
generators in Python
 Simply speaking, a generator is a function that returns an object
(iterator) which we can iterate over (one value at a time)

609
Generators(cont)
 How to create a generator in Python?
 It is fairly simple to create a generator in Python
 It is as easy as defining a normal function with yield statement
instead of a return statement
 If a function contains at least one yield statement (it may contain
other yield or return statements), it becomes a generator function
 Both yield and return will return some value from a function
 The difference is that, while a return statement terminates a
function entirely, yield statement pauses the function saving all its
states and later continues from there on successive calls

610
Generators(cont)
 Differences between Generator function and a Normal
function
 Here is how a generator function differs from a normal function
 Generator function contains one or more yield statements
 When called, it returns an object (iterator) but does not start
execution immediately
 Methods like __iter__() and __next__() are implemented
automatically
 So we can iterate through the items using next()
 Once the function yields, the function is paused, and the control is
transferred to the caller
 Local variables and their states are remembered between
successive calls
 Finally, when the function terminates, StopIteration is raised
automatically on further calls

611
Generators(cont)
 Here is an example to illustrate all of the points stated
 We have a generator function named my_gen() with several yield
statements
 # A simple generator function
SimpleGeneratorE
 def my_gen(): xample
 n=1
 print('This is printed first')
 # Generator function contains yield statements
 yield n

 n += 1
 print('This is printed second')
 yield n

 n += 1
 print('This is printed at last')
 yield n
612
Generators(cont)

613
Generators(cont)

614
Generators(cont)
 One interesting thing to note in the above example is that, the
value of variable n is remembered between each call
 Unlike normal functions, the local variables are not destroyed when
the function yields
 ********************Important ***********************
 Furthermore, the generator object can be iterated only once
 ****************************************************
 To restart the process we need to create another generator object
using something like a = my_gen()
 ****************************************************

 One final thing to note is that we can use generators with for
loops directly
 This is because, a for loop takes an iterator and iterates over it
using next() function
 It automatically ends when StopIteration is raised
615
Generators(cont)
 # Using for loop with a generator
 for item in my_gen():
 print(item)

616
Generators(cont)
 Python Generators with a Loop
 Normally, generator functions are implemented with a loop having
a suitable terminating condition
 Let's take an example of a generator that reverses a string
 def rev_str(my_str):
 length = len(my_str)
 for i in range(length - 1,-1,-1):
 yield my_str[i]
 for char in rev_str("hello"): ReverseStringGen
 print(char) eratorExample
 # For loop to reverse the string
 # Output:
 #o
 #l
 #l
 #e
 #h

617
Generators(cont)
 In this example, we use range() function to get the index in
reverse order using the for loop
 It turns out that this generator function not only works with string,
but also with other kind of iterables like list, tuple etc

618
Generators(cont)
 Python Generator Expression
 Simple generators can be easily created on the fly using generator
expressions
 ********It makes building generators easy*********
 Same as lambda function creates an anonymous function,
generator expression creates an anonymous generator function
 The syntax for generator expression is similar to that of a list
comprehension in Python
 But the square brackets [] are replaced with round
parentheses ()
 The major difference between a list comprehension and a
generator expression is that while list comprehension
produces the entire list, generator expression produces one
item at a time

619
Generators(cont)
 They are kind of lazy, producing items only when asked for
 For this reason, a generator expression is much more memory
efficient than an equivalent list comprehension
 Example:
 mylist = [x for x in range(10000000)]
 mygen =(x for x in range(10000000))

 print(mylist.__sizeof__())
 print(mygen.__sizeof__())
 The list is 81.5MB in size
 The gen is 64 bytes in size

620
Generators(cont)
 Example
 # Initialize the list
 my_list = [1, 3, 6, 10]

 # square each term using list comprehension


 [x**2 for x in my_list]
GeneratorComprehensionExample.txt

 # Output: [1, 9, 36, 100] , the output is an entire list

 # same thing can be done using generator expression


 (x**2 for x in my_list)
 # Output: <generator object <genexpr> at
0x0000000002EBDAF8>

621
Generators(cont)
 We can see above that the generator expression did not produce
the required result immediately
 Instead, it returned a generator object with produces items on
demand
 # Initialize the list

 my_list = [1, 3, 6, 10]


SimpleGeneratorE
 a = (x**2 for x in my_list) xamplev2
 print(next(a))
 print(next(a))
 print(next(a))
 print(next(a))
 print(next(a))

622
Generators(cont)

623
Generators(cont)
 Generator expression can be used inside functions
 When used in such a way, the round parentheses can be dropped
 sum(x**2 for x in my_list)
 max(x**2 for x in my_list)

624
Generators(cont)
 Why generators are used in Python?
 There are several reasons which make generators an attractive
implementation to go for
 1. Easy to Implement
 Generators can be implemented in a clear and concise way as
compared to their iterator class counterpart
 Following is an example to implement a sequence of power of 3's
using iterator class
 class PowThree:
 def __init__(self, max = 0):
 self.max = max Power3ClassExam
ple
 def __iter__(self):
 self.n = 0
 return self

 def __next__(self):
 if self.n > self.max:
 raise StopIteration

 result = 3 ** self.n
 self.n += 1
 return result

625
Generators(cont)
 This was lengthy (when using a class)
 Now let's do the same using a generator function
 def PowThree (max = 0):
 n=0
 while n < max:
 yield 3 ** n
 n += 1

 2. Memory Efficient
 A normal function to return a sequence will create the entire
sequence in memory before returning the result
 This is an overkill if the number of items in the sequence is very
large
 Generator implementation of such sequence is memory friendly and
is preferred since it only produces one item at a time

626
Generators(cont)
 3. Represent Infinite Stream
 Generators are an excellent way to represent an infinite set of data
 Infinite sets cannot be stored in memory and since generators
produce only one item at a time, it can represent infinite set of
data
 The following example can generate all the even numbers (at least
in theory)

 def all_even():
 n=0
 while True:
 yield n
 n += 2

627
Quiz 16

628
Quiz 16
 1. What is the output of the code shown below?

 #generator
 def f(x):
 yield x+1
 g=f(8)
 print(next(g))

 A 8
 B 9
 C 7
 D Error

629
Quiz 16
 2. What is the output of the code shown below?

 def f(x):
 yield x+1
 print("test")
 yield x+2
 g=f(9)

 A Error
 B test
 C test
 10
 12
 D No output

630
Quiz 16
 3. What is the output of the code shown below?
 def f(x):
 yield x+1
 print("test")
 yield x+2
 g=f(10)
 print(next(g))
 print(next(g))

 A No output
 B 11
 test
 12
 C 11
 test
 D 11

631
Quiz 16
 4. What is the output of the code shown?

 def f(x):
 for i in range(x):
 yield i
 g=f(8)
 print(list(g))

 A [0, 1, 2, 3, 4]
 B [1, 2, 3, 4, 5, 6, 7, 8]
 C [1, 2, 3, 4, 5]
 D [0, 1, 2, 3, 4, 5, 6, 7]
 E None of the above

632
Quiz 16
 5. What is the output of the code shown below?

 g = (i for i in range(5))
 type(g)

 A class <’loop’>
 B class <‘iteration’>
 C class <’range’>
 D class <’generator’>
 E class <‘dataframe’>

633
Closures
 Python Closures
 In this section, you'll learn what is a Python closure, how to define
a closure, and reasons why you should use it

634
Closures(cont)
 Nonlocal variable in a nested function
 Before getting into what a closure is, we must first understand
what a nested function and nonlocal variable is
 *************************************************
 A function defined inside another function is called a nested
function
 Nested functions can access variables of the enclosing scope
 *************************************************

 These non-local variables are read only by default and we must


declare them explicitly as non-local (using nonlocal keyword) in
order to modify them

635
Closures(cont)
 Nested Functions:

 >>> def outer():


 x = 10
 def inner():
 print(x)
 inner()

 >>> outer()

636
Closures(cont)
 Here is an example of a nested function accessing a non-
local variable

 Example
 def print_msg(msg): Questions:
 # This is the outer enclosing function What is the non-local
 def printer(): variable?
 # This is the nested function What function is calling
it?
 print(msg)
 printer()

 # We execute the function


 print_msg("Hello Python")
 Type this into your Python IDE and execute the code

637
Closures(cont)

638
Closures(cont)
 The nested function printer() was able to access the non-local
variable msg of the enclosing function print_msg
 Defining a Closure Function
 In the example above, what would happen if the last line of the
function print_msg returned the printer function instead of
calling it?
 This means the function was defined as follows
 def print_msg(msg):
 # This is the outer enclosing function
 def printer():
 # This is the nested function
 print(msg)
 return printer #This is what got changed – returning the function, not calling it

 # Now let's try calling this function.


 another = print_msg("Hello Python")
 another()

639
Closures(cont)
Run the code below in your Python IDE

640
Closures(cont)
 What do you think?
 The print_msg() function was called with the string "Hello Python"
and the returned function was bound to the name another
 On calling another(), the message was still remembered although
we had already finished executing the print_msg() function
 This technique by which some data ("Hello Python") gets attached
to the code is called closure in Python (i.e. a function that returns a
function)
 This value in the enclosing scope is remembered even when the
variable goes out of scope or the function itself is removed from the
current namespace
 Try running the following in the Python code console to see the
output
 del print_msg
 another()
 print_msg(“Hello Python”)
641
Closures(cont)

642
Closures(cont)
 When do we have a closure?
 As seen from the previous example, we have a closure in Python
when a nested function references a value in its enclosing scope

 The criteria that must be met to create closure in Python are


summarized in the following points:
 *********************Important***********************

 We must have a nested function (function inside a function)

 The nested function must refer to a value defined in the


enclosing function

 The enclosing function must return the nested function

 *****************************************************
643
Closures(cont)
 When to use closures?
 So what are closures good for? (you must be wondering!)

 Closures can avoid the use of global values and provides some
form of data hiding

 It can also provide an object-oriented solution to the problem

 When there are few methods (one method in most cases) to be


implemented in a class, closures can provide an alternate and more
elegant solution
 But when the number of attributes and methods get larger, it’s
better implement a class
 Here is a simple example where a closure might be more preferable
than defining a class and making objects

644
Closures(cont)
 def make_adder_of(n):
 def adder(x):
 return x + n
 return adder

 # Adder of 3
 adder3 = make_adder_of(3)

 # Adder of 5
 adder5 = make_adder_of(5)
 Type the following into your Python console

 print(adder3(9))
 print(adder5(3))
 print(adder5(adder3(2)))
645
Closures(cont)

646
Closures(cont)
 Here’s the implementation of the make_multiplier closure using a
class

 class make_adder():
 def __init__(self, n):
 self.add = n

 def adder(self,x):
 return self.add + x

 adder5 = make_adder(5)

 adder5.adder(2)

647
Closures(cont)
 Decorators in Python (next section of our course) make an
extensive use of closures as well
 I want to point out that the values that get enclosed in the closure
function can be found out
 Closure functions have __closure__ attribute that returns a tuple
of cell objects
 In our previous example, adder3 and adder5 are closures

 The cell object has the attribute cell_contents which stores the
closed value

648
Decorators
 A decorator takes in a function, adds some functionality and
returns it (it returns a function, a function that returns a function)
 In this section, you will learn how you can create a decorator and
why you should use it

649
Decorators(cont)
 Python has an interesting feature called decorators to add
functionality to an existing code
 This is also called metaprogramming as a part of the program
tries to modify another part of the program at compile time
 What you need to know before learning decorators?
 In order to understand about decorators, we must first know a few
basic things in Python
 We must be comfortable with the fact that, everything in Python
(Yes! Even classes), are objects
 Names that we define are simply identifiers bound to these objects
 Functions are no exceptions, they are objects too (with attributes)
 Different names can be bound to the same function object

650
Decorators(cont)
 Example
 Execute the code below in your Python Console
 def first(msg):
 print(msg)

 first("Hello")

 second = first
 second("Hello")

651
Decorators(cont)
 When you run the code, both functions first and second gives same output
 Here, the names first and second refer to the same function object
 Now things start getting weirder
 Functions can be passed as arguments to another function
 If you have used functions like map, filter and reduce in Python 2, then you
already know about this
 Functions that take other functions as arguments are also called higher
order functions
 Here is an example of such a function (see the operate function)
 def inc(x):
 return x + 1

 def dec(x):
 return x - 1

 def operate(func, x):


 result = func(x)
 return result
652
Decorators(cont)
 You should get the results below

 Furthermore, a function can return another function (yes it can –


strange isn’t it)
 Example
 def is_called():
 def is_returned():
 print("Hello")
 return is_returned

 new = is_called()
 new()
653
Decorators(cont)
 Here, is_returned() is a nested function which is defined and
returned, each time we call is_called()

 Finally we must know about closures in Python

654
Decorators(cont)
 Getting back To decorators
 Functions and methods are called callable as they can be called
 In fact, any object which implements the special method __call__() is termed
callable
 So, in the most basic sense, a decorator is a callable that returns a callable
 Basically, a decorator takes in a function, adds some functionality and returns it
 Example:
 def make_pretty(func):
 def inner():
 print("I got decorated")
 func()
 return inner

 def ordinary():
 print("I am ordinary")

 ordinary()
 pretty = make_pretty(ordinary)
 pretty()

655
Decorators(cont)
 Execute the code in your Python IDE

656
Decorators(cont)
 The function ordinary() got decorated and the returned function
was given the name pretty
 We can see that the decorator function added some new
functionality to the original function
 This is similar to packing a gift
 The decorator acts as a wrapper
 The nature of the object that got decorated (actual gift inside) does
not alter
 But now, it looks pretty (since it got decorated) 
 In Python the standard is to reassign the function as,
 ordinary = make_pretty(ordinary)
 This is a common construct and for this reason, Python has a
syntax to simplify this

657
Decorators(cont)
 We can use the @ symbol along with the name of the decorator
function and place it above the definition of the function to be
decorated
 For example,
 @make_pretty
 def ordinary():
 print("I am ordinary")

 is equivalent to
 def ordinary():
 print("I am ordinary")
 ordinary = make_pretty(ordinary)

 This is just a syntactic sugar to implement decorators

658
Decorators(cont)
 Decorating Functions with Parameters
 The previous decorator was simple, and will work with functions
that did not have any parameters
 What if we had functions that took in parameters like this one:

 def divide(a, b):


 return a/b

659
Decorators(cont)
 Now let's create a decorator to check for the case where an error
occurred in the division step (i.e. a division by zero error)
 def smart_divide(func):
 def inner(a,b):
 print("I am going to divide",a,"and",b)
 if b == 0:
 print("Whoops! cannot divide")
 return

 return func(a,b)
 return inner

 @smart_divide
 def divide(a,b):
 return a/b
 Type the code above into your Python IDE and execute the code

660
Decorators(cont)

661
Decorators(cont)
 In this manner we can decorate functions that take parameters
 You may have observed that parameters of the nested inner()
function inside the decorator is same as the parameters of
functions it decorates
 Taking this into account, now we can make general decorators that
work with any number of parameters
 In Python, this magic is done as function(*args, **kwargs)
 With this way, args will be the tuple of positional arguments and
kwargs will be the dictionary of keyword arguments
 An example of such decorator would be:

 def works_for_all(func):
 def inner(*args, **kwargs):
 print("I can decorate any function")
 return func(*args, **kwargs)
 return inner

662
Decorators(cont)
 Use this to decorate any function you want
 Let’s create our own function

 def myfunction(a,b):
 return a+b

663
Decorators(cont)
 Chaining Decorators in Python
 Multiple decorators can be chained in Python
 This is to say, a function can be decorated multiple times with different (or same)
decorators
 We simply place the decorators above the desired function
 def star(func):
 def inner(*args, **kwargs):
 print("*" * 30)
 func(*args, **kwargs)
 print("*" * 30)
 return inner
Nested_Decorators_Example.txt
 def percent(func):
 def inner(*args, **kwargs):
 print("%" * 30)
 func(*args, **kwargs)
 print("%" * 30)
 return inner

 @star
 @percent
 def printer(msg):
 print(msg)

 printer("Hello Python")
664
Decorators(cont)
 Run the code and you will get the result below

665
Decorators(cont)
 The above syntax of,
 @star
 @percent
 def printer(msg):
 print(msg)

 is equivalent to
 def printer(msg):
 print(msg)
 printer = star(percent(printer))

 First decorate with percent and then star

666
Decorators(cont)
 ******The order in which we chain decorators matters ******
 If we had reversed the order,
 @percent
 @star
 def printer(msg):
 print(msg)
 printer(“Hello World”)
 The code would execute differently because you first decorate with
star and then percent

667
Quiz 17

668
Quiz 17
 1. What is the output of the code shown below?
 def mj(func):
 def mj1():
 print("Decorated")
A Decorated
 func() Decorated
 return mj1
B Ordinary
 def mj2(): Ordinary
 print("Ordinary")
C Ordinary
Decorated
 p = mj(mj2)
 p() D Decorated
Ordinary

669
Quiz 17
 2. In the code shown below, which function is the
decorator?
 def mj(funct):
 def mj1(): A p()
 print("Decorated")
B mj()
 funct()
 return mj1 C mj1()

 def mj2(): D mj2()


 print("Ordinary")

 p = mj(mj2)
 p()

670
Quiz 17
 3. The ______ symbol along with the name of the decorator
function can be placed above the definition of the function
to be decorated works as an alternate way for decorating a
function

 A#
 B$
 C@
 D&

671
Quiz 17
 4. What is the output of the code shown?
 def ord2():
 print("Ordinary")
 ord2
 ord2()

 A memory address
 Ordinary
 B Error
 Address
 C Ordinary
 Ordinary
 D Ordinary
 Address

672
Quiz 17
 5. Are the two snippets of codes shown below are
equivalent? State whether this is true or false
 Python Program 1
 @f
 def f1():
 print(“Hello”)

 Python Program 2
 def f1():
 print(“Hello”)
 f1 = f(f1)

 A True
 B False

673
Quiz 17
 6. What is the output of the following function?
 def f(x, y):
 return x%y
 f(0, 2)
 f(2, 0)

 A0
 0
 B Zero Division Error
 Zero Division Error
 C0
 Zero Division Error
 D Zero Division Error
 0
 E None of the above
674
Quiz 17
 7. What is the output of the code snippet below?
 def f(func):
 def f1(a, b): A hello
 print("hello") NO
 if b==0:
 print("NO") B hello
 return Zero Division Error
 return f(a, b)
C NO
 return f1
D hello
 @f
 def f(a, b):
 return a%b
 f(4,0)

675
Quiz 17
 8. What are the output of the code shown below?
 def f(func):
 def f1(*args, **kwargs):
 print("*"* 5) A *****
 func(*args, **kwargs) %%%%%
 print("*"* 5) hello
 return f1 %%%%%
 def a(func): *****
 def f1(*args, **kwargs):
 print("%"* 5) B Error
 func(*args, **kwargs)
 print("%"* 5) C *****%%%%%hello%%%%
 return f1 %*****
 @f
 @a
 def p(m):
D hello
 print(m)
 p("hello")

676
Quiz 17
 9. The code shown above can work with ____ parameters.
 def f(func):
 def f1(*args, **kwargs):
 print(“ Hello Python")
 return func(*args, **kwargs)
 return f1

 A2
 B1
 C any number of
 D0

677
Quiz 17
 10. What is the output of the code shown below?
 def f(x):
 def f1(*args, **kwargs):
 print("*", 5)
 x(*args, **kwargs)
 print("*", 5)
 return f1
 @f
 def p(m):
 pass
 print("hello")

 A *****
hello
 B *****
*****
hello
 C *****
 D hello

678
Quiz 17
 11. A function with parameters cannot be decorated. State
whether true or false.
 A True
 B False

 12. Identify the decorator in the snippet of code shown


below.
 def sf():
 pass A @f
 def mk(): Bf
 return C sf()
 sf = mk(sf) D mk
 @f

679
Quiz 17
 13. What is the output of the code shown below?
 class A:
 @staticmethod
 def a(x):
 print(x)

 A.a(100)

 A Error
 B Warning
 C 100
 d) No output

680
Quiz 17
 14. What is the output of the code shown below?
 def d(f):
 def n(*args):
 return '$' + str(f(*args))
 return n

 @d
 def p(a, t):
 return a + a*t
 print(p(100,0))

 A 100
 B $100
 C $0
 D0
681
Quiz 17
 15. What is the output of the code shown below?
 def c(f):
 def inner(*args, **kargs):
 inner.co += 1 A4
B3
 return f(*args, **kargs)
C0
 inner.co = 0 D1
 return inner
 @c
 def fnc():
 pass
 fnc()
 fnc()
 fnc()
 print(fnc.co)

682
@property
 You will learn about Python @property; pythonic way to use getters
and setters

683
@property(cont)
 Python has a great concept called property which makes the life of
an object oriented programmer much simpler
 Before defining and going into details of what @property is, let us
first build an intuition on why it would be needed in the first place
 An Example To Begin With
 Let us assume that you decide to make a class that could store the
weight on an object in kilograms
 It would also implement a method to convert the weight into
pounds
 Here is one way of doing this
 class Kilogram:
 def __init__(self, weight = 0):
 self.weight = weight

 def to_pound(self):
 return (self.weight * 1000/454)

684
@property(cont)
 We could make objects out of this class and manipulate the
attribute weight
 Try this on your Python shell or in a script on your IDE

685
@property(cont)
 Whenever we assign or retrieve any object attribute like
temperature, as show above, Python searches it in the object's
__dict__ dictionary

 x.__dict__

 Therefore, x.weight internally becomes x.__dict__[‘weight’]


 Remember python dictionaries have keys and values

686
@property(cont)
 Now assume that our class had been adopted by our clients and
they started using it in their programs
 They did all kinds of assignments to the object
 One day, a trusted client came to us and suggested that weights
cannot go below 0 lbs/kgs and that we need to implement a
constraint

 We want the client to be happy, so let’s implement the constraint

687
@property(cont)
 Using Getters and Setters
 One possible solution to the above constraint will be to hide the attribute weight
(make it private) and define new getter and setter interfaces to manipulate it
 This can be done as follows
 class Kilogram:
 def __init__(self, weight=0):
 self.set_weight(weight)

 def to_pound(self):
 return (self.get_weight()* 1000/454)

 # getter method
 def get_weight(self):
 return self._weight

 # setter method
 def set_weight(self, value):
 if value < 0:
 raise ValueError("Weight below 0 is not possible.")
 self._weight = value

 c = Kilogram(-1)

688
@property(cont)
 We can see above that new methods get_weight() and
set_weight() were defined and furthermore, weight was replaced
with _weight
 An underscore (_) at the beginning is used to denote private
variables in Python
 Try the following in your Python console

689
@property(cont)
 This update successfully implemented the new restriction
 We are no longer allowed to set weight below 0
 With Python, there is no existence of private instance variables
which can not be accessed except inside an object
 A convention has is being followed by most Python programmers is
that a name prefixed with _ is “private”

690
@property(cont)
 The problem with the update is that all the clients who
implemented our previous class in their program will have to
modify their code from obj.weight to obj.get_weight() and all
assignments like obj.weight = val to obj.set_weight(val)
 Would you want to do this? If not, then don’t expect the clients/end
users to do it either
 Our new update is not backward compatible!
 What can be done about this? How can we make the update
backward compatible?
 Now here is where property comes to rescue

691
@property(cont)
 The Power of @property
 The pythonic way to deal with the above problem is to use property
 Here is how we can do it
 class Kilogram:
 def __init__(self, weight = 0):
 self.weight = weight

 def to_pound(self):
 return (self.weight * 1000/454)

 def get_weight(self):
 print("Getting value")
 return self._weight

 def set_weight(self, value):


 if value < 0:
 raise ValueError("Weight below 0 is not possible")
 print("Setting value")
 self._weight = value

 weight = property(get_weight,set_weight)
692
@property(cont)
 We added a print() function inside get_weight() and set_weight()
to clearly observe that they are being executed
 The last line of the code, makes a property object weight
 Simply put, property attaches some code (get_weight and
set_weight) to the member attribute accesses (weight)
 Any code that retrieves the value of weight will automatically call
get_weight() instead of a dictionary (__dict__) look-up
 Similarly, any code that assigns a value to weight will automatically
call set_weight()
 This is a powerful feature of Python
 We can see above that set_weight() was called even when we
created an object

693
@property(cont)
 Can you see why?
 The reason is that when an object is created, __init__() method
gets called, this method has the line self.weight = weight
 This assignment automatically called set_weight
 c.weight

694
@property(cont)
 Similarly, any access like c.weight automatically calls get_weight()
 This is what property does
 Here is another example

695
@property(cont)
 By using property, we can see that we modified our class and
implemented the value constraint without any change required to
the client code
 Our implementation was backward compatible, and everybody is
happy (can you see why?)
 Because the client does not have to change their code or their
procedures
 Finally note that, the actual weight value is stored in the private
variable _value
 The attribute weight is a property object which provides interface
to this private variable

696
@property(cont)
 Looking further into Property
 In Python, property() is a built-in function that creates and returns
a property object
 The signature of this function is
 property(fget=None, fset=None, fdel=None, doc=None)
 where, fget is a function to get value of the attribute, fset is a
function to set value of the attribute, fdel is a function to delete the
attribute and doc is a string (like a comment)
 As seen from the implementation, these function arguments are
optional
 So, a property object can simply be created as follows

697
@property(cont)
 A property object has three methods, getter(), setter() , and
delete()
 You can specify fget, fset and fdel later
 The line
 weight = property(get_weight,set_weight)
 Could have been written
 # make empty property
 weight = property()
 # assign fget
 weight = weight.getter(get_weight)
 # assign fset
 weight = weight.setter(set_weight)
 They are equivalent

698
@property
 Remember our previous tutorial on decorators?
 class Kilogram:
 def __init__(self, weight = 0):
 self._weight = weight

 def to_pound(self):
 return (self.weight* 1000/454)

 @property
 def weight(self):
 print("Getting value")
 return self._weight

 @weight.setter
 def weight(self, value):
 if value < 0:
 raise ValueError("Weight below 0 is not possible")
 print("Setting value")
 self._weight = value

699
@property

700
Quiz 18

701
Quiz 18
 1. Methods of a class that provide access to private
members of the class are called as ______ and ______

 A getters/setters
 B __repr__/__str__
 C user-defined functions/in-built functions
 D __init__/__del__
 E None of the above

702
Quiz 18
 2. Which of these is a private data field?
 def Demo:
 def __init__(self):
 __a = 1
 self.__b = 1
 self.__c__ = 1
 __d__= 1

 A __a
 B __b
 C __c__
 D __d_

703
Quiz 18
 3. What is the output of the following code?
 class Demo:
 def __init__(self):
 self.a = 1
 self.__b = 1

 def get(self):
 return self.__b

 obj = Demo()
 print(obj.get())

 A The program has an error because there isn’t any function to return self.a
 B The program has an error because b is private and display(self) is returning a
private member
 C The program has an error because b is private and hence can’t be printed
 D The program runs fine and 1 is printed

704
Quiz 18
 4. What is the output for the following piece of code?
 class Demo:
 def __init__(self):
 self.a = 1
 self.__b = 1
 def get(self):
 return self.__b
 obj = Demo()
 obj.a=45
 print(obj.a)

 A The program runs properly and prints 45


 B The program has an error because the value of members of a class can’t
be changed from outside the class
 C The program runs properly and prints 1
 D The program has an error because the value of members outside a class
can only be changed as self.a=45
705
Quiz 18
 5. Private members of a class cannot be accessed. True or
False?

 A True
 B False

706
Quiz Index
 Navigate to the quizzes (questions) using the links below
 Solutions are found in the notes of the powerpoint deck

 Quiz 0 Quiz 13
 Quiz 1 Quiz 14
 Quiz 14-A
 Quiz 2 Quiz 15
 Quiz 3 Quiz 16
 Quiz 4 Quiz 17
 Quiz 5 Quiz 18
 Quiz 7
 Quiz 8
 Quiz 9
 Quiz 10
 Quiz 11
 Quiz 12

707
Sample Exam Questions

708
Sample Questions
 1. Python was released publicly in
 A 1941
 B 1971
 C 1981
 D 1991

 2. Who created Python


 A Guido Van Rossum
 B Denis Ritchie
 C John Hull
 D Bjarne Stroustrup

709
Sample Questions
 3. Python has the reputation of being:

 A readable language
 B writable language
 C bug-able language
 D scriptable language
 E All of the aobve

 4. There is a do-while loop in Python

 A True
 B False

710
Sample Questions
 5. Which function below converts a string to a frozen set

 A set(x)
 B dict(x)
 C frozenset(x)
 D chr(x)

 6. Which keyword is a valid placeholder for the body of a


function

 A break
 B body
 C continue
 D pass

711
Sample Questions
 7. Which operator evaluates to true if it does not find a
variable in the specified sequence and false otherwise

 A **
 B //
 C is
 D not in

 8. In Python3 what does the // operator do?

 A Float division
 B Floor division
 C Returns the remainder
 D Same as /

712
Sample Questions
 9. Which function checks that all characters in a string are
digits?

 A isnumber()
 B isadigit()
 C isdigit()
 D capitalize()

 10. Which function will convert a float to a string?

 A str2float()
 B str(x)
 C string(x)
 D can’t be done
713
Sample Questions
 11. Which keyword is used to start a function?

 A function
 B func
 C def
 D import

 12. Which function below can be used to open a file for


reading ?

 A fopen(filename,mode)
 B open(filename,mode)
 C openfilename(filename,mode)
 D openfile_name(filename,mode)

714
Sample Questions
 13. Which function returns the minimum alphabetical
character of a string?

 A lower()
 B lowest()
 C lstrip()
 D min()

 14. Which function compares elements of two lists?

 A cmp(list1,list2)
 B len(list1,list2)
 C max(list1,list2)
 D min(list1,list2)
 E None of the above
715
Sample Questions
 15. Suppose I have a list a=[1,2,3] and tuple b =(1,2,3).
Which statement below is correct?
 A a and b are mutable
 B b is mutable
 C a is mutable
 D neither are mutable

 16. Which function inserts “a” into the list , L = [1,2,3,4,5]


at index 3?
 A L.index(“a”)
 B L.pop(“a”,3)
 C L.insert(1,”a”)
 D L.insert(3,”a”)
 E L.insert(2,”a”)

716
Sample Questions
 17. Which statement loads the module math?

 A load math
 B module math
 C include math
 D import math

 18. What is the name of the character data type in python?

 A char
 B character
 C chr
 D chrs
 E No built in type for character

717
Sample Questions
 19. What is the output of the following?
 print("abc DEF".capitalize())

 A abc def
 B ABC DEF
 C Abc def
 D Abc Def

 20. What is the output of the following?


 print("abcdef".center(0))

 A cd
 B abcdef
 C error
 D none of the mentioned
718
Sample Questions
 21 What does the function re.match do?

 A matches a pattern at the start of the string


 B matches a pattern at any position in the string
 C such a function does not exist
 D None of the above

 22. What does the function re.search do?


A matches a pattern at the start of the string


B matches a pattern at any position in the string
C such a function does not exist
D none of the mentioned

719
Sample Questions
 23. What is the correct extension for python files?

 A .pyth
 B .pyt
 C .pt
 D .py

 24. What is the correct syntax to output the type of a


variable or object in Python?

 A print(typeof(x))
 B print(type(x))
 C print(typeOf(x))
 D print(typeofx)

720
Sample Questions
 25. What is the output of the code shown below if the
system date is 28th July, 2019?
 tday=datetime.date.today()
 print(tday.month)

 A July
 B Jul
 C 07
 D7
 E Error

721
Sample Questions
 26. Which of the following is required to create a new
instance of the class?

 A A constructor
 B A class
 C A value-returning method
 D A None method

722
Sample Questions
 27. What will be the output of the following code snippet?
 class Sales:
 def __init__(self, id):
 self.id = id
 id = 200

 val = Sales(421)
 print (val.id)

 A SyntaxError, this program will not run


 B 200
 C 421
 D None of the above

723
Sample Questions
 28. What is the output of the code shown below?

 def dec(func):
 def n(*args):
 return ‘$$$' + str(func(*args))
 return n
 @dec
 def q(x, y):
 return x + x*y
 print(q(100,0))

 A. 100
 B. $$$100
 C. $$$0
 D. 0
724
FINAL EXAM

725
FINAL EXAM
 Q1 - What is the output for the code below?
 ‘Python Rules’ [7:999]

 A ‘Python'
 B ‘Rules'
 C Index error
 D ‘n Rules’
 E None of the above

 Q2 – Which python module which supports regular expressions?

 A regex
 B pyre
 C re
 D pyregex
 E None of the above

726
FINAL EXAM
 Q3 - Syntax error in python is detected by _________at
_________

 A compiler/ compile time


 B interpreter/ run time
 C compiler / run time
 D None of the above

 Q4 – What is the output of min(“I love Python”)

 A ‘Python’
 B a blank space
 C ‘I’
 D ‘e’
 E None of the above
727
FINAL EXAM
 Q5 – What is the output of max(“I Love Python”)

 A ‘y’
 B ‘Love’
 C ‘I’
 D ‘Python’
 E None of the above

728
FINAL EXAM
 Q6 - Find the output of the code?
 def f(a, b = 1, c = 2):
 print('a is: ',a, 'b is: ', b, 'c is: ', c)
 f(2, c = 2)
 f(c = 100, a = 110)

 A a is: 2 b is: 1 c is: 2


 a is: 110 b is: 1 c is: 100
 B a is: 2 b is: 2 c is: 2
 a is: 110 b is: 2 c is: 100
 C a is: 0 b is: 2 c is: 2
 a is: 110 b is: 0 c is: 100
 D a is: 110 b is: 0 c is: 100
 a is: 110 b is: 0 c is: 100
 E None of the above
729
FINAL EXAM
 Q7 - Which options(may be more than one) are correct to
create an empty set in Python?
 A {}
 B ()
 C []
 D set()
 E None of the above

 Q8 - Choose the correct syntax for reading from a text file


stored in ‘‘c:\nba.txt’’ ?
 A myfile = open( "c:\nba.txt","r" )
 B myfile = open(file="c:\\\nba.txt", "r")
 C myfile = open.file( "c:\\nba.txt","r" )
 D myfile = open( "c:\\nba.txt", "r" )

730
FINAL EXAM
 Q9 - What is output of
 33 == 33.0
 A False
 B True
 C 33
 D 33.0
 E None of the above

 Q10 - Which is invalid in python for y = 10 ?


 A y = y++
 B y = ++y
 C y += 1
 D y -= 1
 E None of the above

731
FINAL EXAM
 Q11 – Which error type shown below will not make the
program stop?
 A - Syntax error
 B - Runtime error
 C - Logical error
 D – None of the above

 Q12 - Which command can be used to insert “abc” in a list


mylist=[1,2] at the 3rd position ?
 A - mylist.insert(2,”abc”)
 B – mylist.insert(3,”abc”)
 C – mylist.add(3,”abc”)
 D - mylist.append(2,”abc”)

732
FINAL EXAM
 Q13 – Which statement(s) below is false when you run the
code below ?
 class A:
 def __init__(self, i=1000):
 self.i=i
 class B(A):
 def __init__(self,j=10):
 self.j=j

 def main():
 b= B()
 print(b.i)
 print(b.j)
 main()

 A Class B inherits from class A


 B Class B has a default value for it’s argument
 C The data field ‘j’ cannot be accessed by object b
 D Class B is inheriting class A but the data field ‘i’ in A cannot be inherited

733
FINAL EXAM
 Q14 - Which can’t be used as a name for a Python variable?
(there may be more than one)
 A 7xyz
 B abc_123
 C _zz1
 D @python_rules

 Q15 - Which of the following is correct about Python?


(There may be more than one)
 A Python is a high-level, interpreted, interactive and object-
oriented scripting language
 B Python is designed to be highly readable
 C It uses English keywords frequently where as other languages
use punctuation, and it has fewer syntactical constructions than
other languages
 D All of the above
734
FINAL EXAM
 Q16 - Which of the following is correct about Python?
 A It supports functional and structured programming methods as
well as OOP
 B It can be used as a scripting language or can be compiled to
byte-code for building large applications
 C It provides very high-level dynamic data types and supports
dynamic type checking
 D All of the above

 Q17 – Python is a case sensitive language?


 A True
 B False

735
FINAL EXAM
 Q18 - Which of the following data types is not supported in
python?
 A Numbers
 B String
 C List
 D Slice

 Q19 - Which of the following data types is not supported in


python?
 A Tuple
 B Dictionary
 C Generics
 D List

736
FINAL EXAM
 Q20 - Which of the following data types is not supported in
python?
 A Tuple
 B Dictionary
 C Table
 D List

 Q21 - What is the output of print str if str = ‘Python Rules’ ?


 A Python Rules
 B Error
 C str
 D None of the above

737
FINAL EXAM
 Q22 - What is the output of print (str[0]) if str = ‘Python
Rules'?
 A Python Rules
 B P
 C ython Rules
 D Rules

 Q23 - What is the output of print (str * 2) if str = ‘Python


Rules!'?
 A Python Rules!Python Rules!
 B Python Rules! * 2
 C Python Rules!
 D None of the above

738
FINAL EXAM
 Q24 - What is the output of print (list) if list = [ 'abcd’,
‘hello’ , 2.25, ‘harold’, 80.6 ]?
 A ['abcd’, ‘hello’ , 2.25, ‘harold’, 80.6]
 B list
 C Error
 D ('abcd’, ‘hello’ , 2.25, ‘harold’, 80.6 )

 Q25 - What is the output of print (mylist * 2) if mylist =


[123, ‘abc']?
 A Error
 B [123, ‘abc'] * 2
 C [123, ‘abc', 123, ‘abc']
 D None of the above

739
FINAL EXAM
 Q26 - Which of the following is correct (there may be more
than one) about tuples in python?
 A A tuple is another sequence data type that is similar to the list
 B A tuple consists of a number of values separated by commas
 C Unlike lists, however, tuples are enclosed within parentheses
when defined
 D All of the above

 Q27 - What is the output of print (tuple[0]) if tuple = ( ‘abc’,


123 , 123, ‘dohrayme’, 123 )?
 A (123)
 B (‘abc’)
 C Error
 D (‘abc’,123)
 E None of the above

740
FINAL EXAM
 Q28 - What is the output of
 print (tuple[1:3]) if tuple = ( ‘abc’, 123 , 123, ‘dohrayme’, 123 )?
 A (‘abc’,123,123)
 B (123,123,’dohrayme’)
 C Error
 D (123,123)
 E None of the above
 Q29 – What is the output of the code below?
 counter = 100
 type(counter)
 A float
 B decimal
 C whole
 D integer
 E int

741
FINAL EXAM
 Q30 – Which of the following will output a generator?
 A [ x**2 for x in range(5)]
 B (x**3 for x in range(5) )
 C {x**3 for x in range(5) }
 D None of the above

 Q31 -What is the output of the following expression?

 print(8.00/(4.0+4.0))

 A Error
 B1
 C 1.0
 D 1.00

742
FINAL EXAM
 Q32 - What is the value of the expression?

 float(4+int(2.39)%2)
 A 5.0
 B5
 C 4.0
 D4

 Q33 - What is the value of the expression?


 4+2**5//10
 A3
 B7
 C 77
 D0

743
FINAL EXAM
 Q34 - What is the output of the following function?
 def f(p, q):
 return p%q
 f(0, 5)
 f(5, 0)

 A 0
 Zero Division Error
 B 0
 0
 C Zero
 Zero Division Error
 D Zero Division Error
 0

744
FINAL EXAM
 Q35 - What is the output of the code shown below?
 def mk(func):
 def mk1():
 print(“Here I am")
 func()
 return mk1
 def mk2():
 print(“Will you send me an angel")
 p = mk(mk2)
 p()

 A Here I am
 Here I am
 B Will you send me an angel
 Here I am
 C Will you send me an angel
 Here I am
 D Here I am
 Will you send me an angel

745
FINAL EXAM
 Q36 - What is the output of the following?

 for i in range(20):
 if i == 5:
 break
 else:
 print(i)
 else:
 print(“Hello")

 A 0 1 2 3 4 Hello
 B 0 1 2 3 4 5 Hello
 C12345
 D01234

746
FINAL EXAM
 Q37 - What is the output of the following?

 x = (i for i in range(4))
 for i in x:
 print(i)

 A0123
 B error
 C01230123
 D None of the above

747
FINAL EXAM
 Q38 - Is the following piece of code valid?

 myset=frozenset([5,6,7])
 myset
 myset.add(5)

 A Yes, now myset is {5,5,6,7}


 B No, frozen set is immutable
 C No, invalid syntax for add method
 D Yes, now myset is {5,6,7}
 E None of the above

748
FINAL EXAM
 Q39 - Read the information given below carefully and select
a list comprehension such that the output is: [‘e’, ‘o’]?

 w="hello"
 v=('a', 'e', 'i', 'o', 'u’)

 A [x for w in v if x in v]
 B [x for x in w if x in v]
 C [x for x in v if w in v]
 D [x for v in w for x in w]
 E None of the above

749
FINAL EXAM
 Q40 - Select a list comprehension for producing a list of
numbers greater than or equal to 1 and less than 2000 that
are divisible by 3

 A [x for x in range(2000) if x%3==0]


 B [x for x in range(2001) if x%3==0]
 C [x%3 for x in range(1, 2000)]
 D [x%3==0 for x in range(1, 2000)]
 E None of the above

750
FINAL EXAM
 Q41 - What is the output of the following code?
 def foo():
 try:
 print(2)
 finally:
 print(3)
 foo()

 A2
 B2
 3
 C3
 2
 D None of the above

751
FINAL EXAM
 Q42 - What is the output of the following piece of code?

 mydict={'B':5,'A':9,'C':7}
 sorted(mydict)

 A [‘A’,’B’,’C’]
 B [‘B’,’C’,’A’]
 C [5,7,9]
 D [9,5,7]

752
FINAL EXAM
 Q43 - What is the output of the following code?

 mydict={}
 mydict[2]=1
 mydict[1]=[2,3,4]
 print(mydict[1][1])

 A [2,3,4]
 B3
 C2
 D Error

753
FINAL EXAM
 Q44 -In file handling, what does the terms “r, a” mean?
 A read-append
 B append, read
 C read, append
 D None of the above

 Q45 -Which function is used to read all the characters after


opening a file?
 A readchar()
 B readcharacters()
 C readall()
 D read()

754
FINAL EXAM
 Q46 - What type of inheritance is illustrated in the following
piece of code?

 class A():
 pass
 class B(A):
 pass
 class C(B):
 pass

 A Single-level inheritance
 B Multiple inheritance
 C Hierarchical inheritance
 D Multi-level inheritance

755
FINAL EXAM
 Q47 - What is the output of the following piece of code when
executed in the Python shell?

 class A:
 pass
 class B(A):
 pass
 obj=B()
 isinstance(obj,A)

 A False
 B True
 C Wrong syntax for isinstance() method
 D Invalid method for classes

756
FINAL EXAM
 Q48 - What is the order of namespaces in which Python
looks for an identifier?

 A Python first searches the local namespace, then the global


namespace and finally the built-in namespace
 B Python first searches the built-in namespace, then the global
namespace and finally the local namespace
 C Python first searches the built-in namespace, then the local
namespace and finally the global namespace
 D Python first searches the global namespace, then the local
namespace and finally the built-in namespace

757
FINAL EXAM
 Q49 - What is the output of the following piece of code?

 from math import factorial


 print(math.factorial(5))

 A 120
 B Nothing is printed
 C Error, method factorial doesn’t exist in math module
 D Error, the statement should be: print(factorial(5))

 Factorial : factorial(6) Is defined as 6x5x4x3x2x1

758
FINAL EXAM
 Q50 - Which of the following is not a valid namespace?

 A Global namespace
 B Public namespace
 C Built-in namespace
 D Local namespace

759
Exam Answers

760

You might also like