Python
Python
Introduction
History
• Guido van Rossum is Python's principal author
• First version was released in 1994
Python Features
• High-level language
• Interpreted language
• Dynamically typed
• Case-sensiBve for keywords and idenBfiers
• Uses indentaBon for blocks and nested blocks
• Free and open source
• Portable and available in many plaHorm
• Has a rich library of predefined funcBons
References
Official Website
https://www.python.org/
Documentation
https://docs.python.org/
CPython GitHub
https://github.com/python/cpython
PEP 20 – The guiding principles for Python's design is referred to as The Zen of Python. It lists 19
principles that are applicable for all good Python programs.
https://peps.python.org/pep-0020/
Execution Modes of Python Interpreter
Interactive Mode
• Python's Integrated Development and Learning Environment (IDLE) opens the IDLE Shell,
which runs Python in interactive mode.
• Python statements are executed one statement at a time.
• The statement should be typed-in at the prompt.
• The statement is executed on pressing enter key.
• A statement can span across multiple lines, the statement will be executed when enter key
is pressed after the complete statement is typed-in.
• When an expression is keyed in as a statement, it is evaluated and the evaluated value is
printed.
• Previously typed-in statements can be executed again by moving the input cursor to that
statement and pressing enter key.
Script Mode
• A script file cannot be directly executed from the shell (interactive mode) prompt.
• When the script file is open, menu option RunàRun Module (or shortcut key F5) will
execute the script.
• When a script file is run, syntax check is done for the entire file before starting execution.
• When a line contains an expression (not a statement), it is evaluated and the evaluated
value discarded (not printed to output as in case of interactive mode).
Example: Let’s say a script file contains the following two lines of code.
print('Hello')
print(10 + '20')
On running the script file, Hello will be printed and then an error occurs in the second line as
it is trying to add an integer and a string. This is a run-time error.
Let’s introduce a syntax error in the second line by removing one of the single quotes in '20'.
If the modified script file is run, Hello will NOT be printed and only a compile-time syntax
error occurs. This is because syntax check is done for the entire script before the start of
execution.
If a script file has multiple syntax errors, Python interpreter stops at the first syntax error.
Python Syntax
Character Set
• For language elements outside string literals and comment texts, Python uses only ASCII
printing characters and whitespace characters. All printing ASCII characters are used except
three: $ ? and ` (grave accent).
• Any ASCII or non-ASCII character can be present in string literals and comments.
Comments
Starts with # and ends with newline.
Line Continuation
Expressions in parentheses, square brackets or curly braces can continue to multiple lines till the
closing parentheses/brackets/braces.
Example:
if x > y:
x = ( a * b # continuation
+ c * d) # indentation of continuation lines doesn't matter
y = 5 # indentation matters here
If a line ends with a backlash, the next line is treated as a continuation. Not character (not even a
space) can follow backslash.
Example:
if x > \
y: # explicit continuation line
x = 4
y = 5
Tokens
Identifiers
• Names used to identify a variable, function, or other entities in a program.
Keywords
Soft keywords are reserved only under certain specific contexts. During tokenization, they are NOT
treated as keywords. Later, during parsing, they are treated as keywords in certain specific contexts.
There are three soft keywords: match case _
Built-in Constants
None True False
Literals
String Literals
Escaping
• Note: Two single quotes or two double quotes is not an escape sequence (different from
MySQL). 'Tom''s idea' will be treated are two adjacent literals 'Tom' and 's idea',
which will get concatenated.
Escape
Character Represented by Sequence
Sequence
\0 ASCII NUL (X'00') character
\' Single quote (') character
\" Double quote (") character
\a Alert (bell)
\b Backspace
\f Form feed
\n Newline (linefeed)
\r Carriage return
\t Tab
\v Vertical tab
\\ Backslash
\ooo One to three octal digits
\xhh Exactly two hexadecimal digits
\uhhhh Exactly four hexadecimal digits
\Uhhhhhhhh Exactly eight hexadecimal digits
Bytes Literals
Numeric Literals
Integer Literals
• Decimal integer – Sequence of digits 0 to 9. Cannot start with 0
• Hexadecimal integer – Sequence of hexadecimal digits prefixed with 0x
• Octal integer – Sequence of octal digits prefixed with 0o
• Binary integer – Sequence of 0s and 1s prefixed with 0b
• The prefixes and hexadecimal digits can be in upper or lower case
FloaZng-point Literals
• Should contain a decimal point or an exponent part. Examples:
o 4.5
o 4.
o 4.1e3
o 4e3
o 4E-1
Note:
• An underscore _ can be added between two digits. This is for readability. Example: 123_000
is same as 123000 and 0x_7A is same as 0x7A.
• A leading - or + is considered as unary operators by Python. They are is not considered as
part of the numeric literal. For example, -10 is a literal expression, not an integer literal.
Similarly, 5+6j is a literal expression, not a complex number literal.
Interning
Python implementaBons have the freedom to merge matching literals (includes all immutable literal
expressions) into a single instance.
For example,
'aa' is 'a'*2 can give True if the implementaBon merges 'aa' and 'a'*2 into a single string instance.
The same implementaBon can give False for 'aa'*20000 is 'a'*40000. This difference is because the
choice of when and when not to do interning is lep to the implementaBon.
The approach of merging mulBple literals into a single instance is called interning. This can be done
for strings, numeric types and tuples. For example, the tuple (10, 20, 30) can be interned.
Note that interning can be done only for immutable types. Mutable types like list and dicBonary
should not be interned. For example, [10, 20, 30] and (2, 3, [4,5]) should not be
interned.
Interning is based on the final value of the expression, not the form of the expression. For example,
2+3 and 4+1 can be merged.
Example:
x = (2, 3, (22,33), 4)
y = 22,33
print(y is x[2]) # can print True
Operators
As per the syntax of Python, following are operators that can be used in expressions.
+ - * ** / // % @
<< >> & | ^ ~ :=
< > <= >= == !=
Punctuations
Assignment symbol = and augmented assignment symbols like += and *= are all delimiters in Python.
This is different from other languages like C/C++/C#/Java, where they are treated as operators.
C/C++/C#/Java does not put restricBons on how assignment operators can be used – they can be
used anywhere in expressions. For example, the following is valid in C/C++/C#/Java.
However, this is not allowed in Python as one of the goals of Python was to not have any side effect
in expressions. Python allows = only in assignment statements and augmented assignment operators
only in augmented assignment statements.
Note: Operator := (called the walrus operator) was introduced in Python 3.8. This is the Python
version of the assignment operator = in C/C++/C#/Java. This is the only operator that has side-effects
in Python.
Trivia: IntroducBon of the walrus operator created a controversy and led to the primary creator of
Python, Guido van Rossum, distancing himself from Python development.
htps://medium.com/pythonistas/the-story-of-guido-van-rossum-and-his-walrus-operator-quick-
blog-a0481af61bd8
Variables
• Variable in Python is a name that refers to a value/object stored in the memory.
• IdenBfiers are used as variable names.
• A variable can refer to a value/object of any type (not strongly typed as in C/C++/C#/Java).
• Variable declaraBon is implicit in Python - variables get created automaBcally when a value is
assigned to it for the first Bme.
• Variables should be assigned values before they are used in expressions.
Numeric Types
complex Complex numbers complex() Uses floaBng point for real and
imaginary parts
None Type
None is a literal of type NoneType. It represents the absence of a value. None is the only possible
value for NoneType.
Sequence Types
Types holding an ordered sequence of items.
Items can be referred to by their posiBon in the sequence. Non-negaBve indices starBng from lep at
zero or negaBve indices starBng from right at -1. Example:
Slicing
Regular Slice
All sequence types support slicing. The result of the slice will be the same type on which the slice is
done.
S = 'ABCDEF'
print(S[2:4]) # prints CD
R = range(10, 16)
print(R[2:4]) # prints range(12, 14)
Note that the slice [start:stop] begins from the start posiBon and includes items unBl before the stop
posiBon. For example, [3:9] refers to posiBons 3 to 8.
The start and stop arguments in the slice can be given using non-negaBve or negaBve indices or a
mix. For example, if the length of a sequence is 6, [2:4], [-4:4], [2:-2] and [-4:-2] all give the same
result.
Extended Slice
Regular slices use a step value of one to move from start posiBon towards stop posiBon. Any non-
zero step value can be specified by adding a third parameter to the slice like [start:stop:step]. If the
step value is any non-zero value other than 1, the slice is called an extended slice.
Examples:
[:5] is same as [0:5]
For a sequence of length 6, [2:] is same as [2:6]
[:1:-1] is same as [-1:1:-1]
For a sequence of length 6, [-1::-1] is same as [-1:-7:-1]
[:] gives the enBre sequence
[::-1] gives the enBre sequence in reverse
Handling out of range start/stop values
The start and stop can be given values beyond the range of the indices of the items in the sequence.
For example, the items in sequence 'ABCDEF' have indices in the range -6 to 5. Values outside this
range are treated as below:
- For start
o PosiBve values beyond range are treated as the last posiZon
o NegaBve values beyond range are treated as the 0th posiZon
- For stop
o PosiBve values beyond range are treated as one posiZon beyond the last posiZon
o NegaBve values beyond range are treated as one posiZon beyond 0th posiZon
Mapping (Dictionary)
A mapping object maps hashable objects to arbitrary objects. Mappings are mutable objects. There
is only one built-in mapping type, the dicBonary - dict.
Hashable types
• Numeric types – int, float, complex, bool. Numeric values that compare equal have the same
hash value.
• String
• None
• Range
Unhashable types
• List
• DicBonary
• Set
DicBonary has many funcBons and operators. Refer Python Built-in Containers.xlsx for details.
Set
A set object is an unordered collecBon of disBnct hashable objects. Duplicates are idenBfied based
on the hash value.
Set has many funcBons and operators. Refer Python Built-in Containers.xlsx for details.
Iterable Types
Container objects are those that can contain mulBple other objects as its elements. List, tuple,
dicBonary, set, string and range are all containers.
Iterable objects are containers that provide the ability to iterate through each of its elements in the
container one-by-one. All built-in containers listed above are iterable.
The above for loop iterates through the default iterator of contobj. The default iterator can also be
directly accessed using iter(contobj).
Reverse iteraBon is supported by all built-in containers except set. As set maintains no order for the
elements, reverse order has no meaning.
The default iterator of dicBonary iterates through the keys in the dicBonary. It is also possible to
iterate values or items in the dicBonary.
Iterable types have many funcBons and operators. Refer Python Built-in Containers.xlsx for details.
Immutable objects are those whose state (internal values) cannot be changed aper it is iniBalized at
the Bme of creaBon. Immutable types are types whose objects are always immutable.
Mutable objects are those whose state (internal values) can be changed aper creaBon. Mutable
types are types whose objects are always mutable.
Immutable types
• Numeric types – int, float, complex, bool
• String
• Tuple
• None
• Range
Mutable types
• List
• DicBonary
• Set
Immutable types to not support funcBons/operators that can change its state. Examples
t = 10,20,30
t[1] = 25 # not possible as tuple is immutable
s = 'abc'
s[1] = 25 # not possible as string is immutable
c = 2+3j
c.real = 25 # not possible as complex is immutable
L = [10,20,30]
L[1] = 25 # changing element allowed in list
S = {10,20,30}
S.add(25) # adding element allowed in set
D = {1:10,2:20,3:30}
D[2] = 25 # changing element allowed in dictionary
Expressions
Operator Precedence
Following is a subset of Python operators in order of precedence. Parentheses can be used to
override precedence.
Precedence Operators DescripZon
1 ** ExponenBaBon
2 - + ~ Unary minus, unary plus and complement
3 * / % // MulBplicaBon & division
4 + - AddiBon & subtracBon
5 << >> Bit ship operators
6 & Bitwise AND
7 ^ Bitwise XOR
8 | Bitwise OR
< <= > >= Order comparison operators
== != Equality comparison operators
is IdenBty test operators
9
is not
in Membership test operators. 2nd operand should be an iterable
not in
Logical NOT. True when the operand is zero/empty/None.
10 not
Logical AND.
Result is the 1st operand if it is zero/empty/None.
11 and
Else the result is the 2nd operand.
Logical OR.
Result is the 1st operand if it is non-zero/non-empty/not-None.
12 or
Else the result is the 2nd operand.
• Membership test operators: if the 2nd operand is a string, 1st operand should also be a string
AssociaZvity
Among operators with same precedence:
• ExponenBaBon (**) – right-to-len associaBvity.
• Unary prefix operators – right-to-len associaBvity.
• All other operators – len-to-right associaBvity.
EvaluaZon order is always len-to-right
Numeric Operators
Behaviours
• ~ (bit inversion) gives a negative result for a non-zero argument and vice versa.
• ArithmeBc operators – All numeric types (int, float, complex, bool) allowed with the
following excepBons
o // and % not allowed for complex
• Ship and bitwise operators – Only integer (int, bool) operands allowed
Implicit conversion, also known as coercion, for numeric values is done when an expression is
evaluated. Operands of operators get implicitly converted as below
• Then,
o If one of the operands is complex, the other is converted to complex
o Else if one of the operands is float, the other is converted to float
Conversion of an int to float/complex will result in OverflowError if the integer value cannot
be represented by float.
• In case of / (division) operator between two integers, the arguments are converted to float
and division is done in floating-point
Explicit Type Conversion
String operators
• RepeZZon - string * int and int * string will give a string that is string repeated int Bmes. If
the integer operand is non-posiBve, an empty string is returned.
• String formarng or interpolaZon operator (%) – Used for C prins() style forma{ng.
o First argument should be a string containing prinH() style format string.
o If only one value is required, the second argument be the value matching the format
specified
o If mulBple values are required, the second argument should be a tuple with exact
number of values specified in the format string
o The second argument can be a mapping (dicBonary) for name-based matching with
format string.
Examples:
'QuanZty: %d units' % 1000 gives 'QuanZty: 100 units'
'Time: %02d:%02d' % (2, 30) gives 'Time: 02:30'
'Time: %(hrs)02d:%(mins)02d' % {'hrs':2, 'mins':30} gives 'Time: 02:30'
DicBonary Operators
• Pipe operator | merges the second dicBonary into the first one and returns a new dicBonary,
without modifying the first dicBonary.
Set Operators
• Refer Python Built-in Containers.xlsx for details.
Short-Circuited Evaluation
In the below expression, exp1, expr2, … etc are evaluated in order and the evaluaBon stops at the
first expression that is false. The value of the whole expression is the last expression evaluated.
If the last expression in the and sequence is evaluated, that becomes the value of the expression.
Examples:
Expression Value
10 and 'abc' and { } and 4.2 { }
10 and 'abc' and 4.2 4.2
10 and 'abc' and True and 0 0
Similar to logical and, logic or stops at finding first expression that is true.
Examples:
Expression Value
0 or { } or 'abc' or 4.2 'abc'
0 or { } or 4.2 4.2
0 or [ ] or dict() { }
The expression is equivalent to except that expr2, expr3, … are evaluated only once.
expr1 rel-op1 expr2 and expr2 rel-op2 expr3 and expr3 rel-op3 ….
The relaBonal operators can be any of the following with no restricBon on the mix of operators in a
chain:
= >= > <= < !=
is
is not
in
not in
Note: None is expr & None is not expr will also Reason: Equality operators
work but the above style is used for code can have custom
readability. implementaBons for some
types.
Checking if cond-expr is # Directly use cond-expr as condition ==
True if cond-expr: !=
... is
is not
# Use bool() function to store
X = bool(cond-expr) Reason: The behaviour of
these operators does not
match the way condiBon
expressions are interpreted
in Python.
Assignment
L-value and R-value
L-value is a reference to a locaBon in memory that can store a value. L stands for locaBon or lep (as
L-values appear on the lep side of assignment operaBons). Only L-values can be given on the lep side
of an assignment.
Examples:
Variable myvar
List item mylist[5]
Slice of a list mylist[5:10]
DicBonary item mdict['a']
Object atribute myobj.myval
R-value is a value that does not refer to any locaBon in memory. R stands for right (as R-values
appear on the right side of assignment operaBons)
Assignment Statement
Simple Assignment
Unpacking Assignment
a, b, *v = (11, 22, 33, 44, 55, 66) # starred target at the end
print(a, b, v) # prints 11 22 [33, 44, 55, 66]
*v, a, b = (11, 22, 33, 44, 55, 66) # starred target at the start
print(v, a, b) # prints [11, 22, 33, 44] 55 66
a, b, *v, c, d = (11, 22, 33, 44, 55, 66) # starred target in the middle
print(a, b, v, c, d) # prints 11 22 [33, 44] 55 66
The right-side of the assignment can be any iterable. All of the below assignments give the same
values for a, b, c, d.
Unpacking string:
a, b, c, d = 'pqrs'
print(a, b, c, d) # prints p q r s
[x, y, z] = ((11, 22), (33, 44), 55) # contained tuples not unpacked
print(x, y, z) # prints (11, 22) (33, 44) 55
[[a, b], [c,d], e] = ((11, 22), (33, 44), 55) # contained tuples uunpacked
print(a, b, c, d, e) # prints 11 22 33 44 55
Every box bracketed part in the target should match an iterable on the right-side of the assignment.
[a], [b] = [1, 2] # error - [a] is matched with integer 1 (not iterable)
[a], [b] = [[1], [2]] # no error [a] matched with [1] & [b] with [2]
[a, b] = [1, 2] # no error
a, b = [1, 2] # no error
Parentheses can be used like box brackets but with the below excepBons:
• Redundant parentheses are ignored – ((…)) (((…))) are both same as (…)
• Parentheses around a single non-star variable are ignored – (a) and a are both same.
Slice Assignment
Example:
Examples:
When assigning to an extended slice (step other than 1), the size of the assigned sequence should
exactly match the slice size. Otherwise, an error occurs.
Multiple Assignments
This is equivalent to the below assignments except that expr is evaluated only once,
target1 = expr
target2 = expr
target3 = expr
…
…
• target1, target2, etc can be any mix variables, unpacking targets or slices
• Assignment happens from lep to right target1 is assigned first, then target2 and so on.
• If the same variable is assigned by mulBple targets, the assignment done by the right-most
target overwrites all other assignments.
Examples:
L = [1, 2, 3, 4, 5, 6]
X = a, *b = L[1:3] = [11, 22, 33]
print(a, b) # prints 11 [22, 33]
print(L) # prints [1, 11, 22, 33, 4, 5, 6]
print(X) # prints [11, 22, 33]
+= -= *= /= //= %=
&= |= ^= >>= <<= **=
Example:
num1 = num2 = 10
print(num1 is num2) # prints True
L = [1, 2, 3, 4, 5]
L[1] += 555
print(L) # prints [1, 557, 3, 4, 5]
s = 'ab'
s *= 3
print(s) # prints ababab
t = (1, 2, 3)
t += 44, 55
print(t) # prints (1, 2, 3, 44, 55)
Augmented assignment is supported when the corresponding operaBon is supported. For example,
string supports += *= and %= and while tuple supports += and *=
For immutable types, a new instance is created and the lvalue is made to point to the new instance.
Example:
L = [1, 2]
L *= 3 # no new instance of list created
print(L) # prints [1, 2, 1, 2, 1, 2]
L = [1, 2, 3, 4, 5]
L += [111, 222] # no new instance of list created
print(L) # prints [1, 2, 3, 4, 5, 111, 222]
L = [1, 2, 3, 4, 5]
L[1:4] += [111, 222] # no new instance of list created by the assignment
print(L) # prints [1, 2, 3, 4, 111, 222, 5]
In case of mutable types, the operaBon is performed in-place, without creaBng a new instance of the
mutable.
Augmented assignment is supported when the corresponding operaBon is supported. Following are
the augmented assignments supported by built-in mutable types.
Statements
Statement Types
A simple statement is comprised within a single logical line. Examples: import, del, global
One line can contain multiple simple statements separated by semocolon
A compound statement is Compound statements contain (groups of) other statements, Examples:
if-else, for, while.
Flow Control Statements
if-elif-else
for assignment-target in expression
for-else
while
while-else
break
continue
return
assert – To asset for a condiBon. AsserBonError raised if the condiBon evaluates to False
pass – No operaBon. Used as a placeholder where a statement block is required by the syntax but is
not yet to be coded (or is not needed)
with – Used to automaBcally do exit acBons for an object on leaving a statement block. AlternaBve
to using try-finally.
Exception Handling
Types of Errors
Syntax Errors
Example: SyntaxError
Occurs when a code does not confirm to the Python syntax rules. Code is executed only aper syntax
check completes without errors. Syntax errors are also called parsing errors.
RunZme Errors
Logical Errors
A logical error is a bug in the program that causes it to behave not as expected. These errors are
difficult to idenBfy as no excepBon is raised as in case of runBme errors.
Exceptions
• When an error occurs during the execuBon of a program, an excepBon is said to have been
raised.
• An excepBon that is not handled by the program causes the program to terminate
abnormally.
• ExcepBon objects include a stack Traceback, which contains informaBon about the sequence
of funcBon calls that led to the excepBon.
Built-in Exceptions
ValueError A funcBon or operaBon received an argument with correct data type but an
inappropriate value.
KeyboardInterrupt User hit the the interrupt key (normally Control-C or Delete) while program
was execuBng.
EOFError The input() funcBon reached end-of-file condiBon (EOF) without reading any
data
IndexError A sequence subscript is out of range. Not raised for indices in slice.
IndentaBonError Incorrect indentaBon in the program code. Raised during syntax check.
OverflowError Result of a calculaBon exceeded the maximum limit for a numeric data type.
AsserBonError An assert statement failed
RunBmeError An error is detected that doesn’t fall in any of the other categories,
Raising Exceptions
raise Statement
Raising an excepBon.
Raising an excepBon from within an except block specifying a current excepBon (i.e., exc) as the
cause.
try:
print(10 / 0)
except Exception as exc:
raise RuntimeError("Something bad happened") from exc
Raising an excepBon from within an except/finally block suppressing of the current excepBon.
try:
print(10 / 0)
except Exception:
raise RuntimeError("Something bad happened") from None
If raise is done inside an except/finally block without specifying from, any current excepBon is
included and the raised excepBon becomes and excepBon that occurred while handling the current
excepBon.
assert Statement
An assert statement is used to test a condiBon that needs to be saBsfied at the point of asserBon
(i.e., where the assert statement is present).
assert condition-expr
Is equivalent to:
if __debug__:
if not condition-expr: raise AssertionError
Is equivalent to:
if __debug__:
if not condition-expr: raise AssertionError(arg-expr)
Handling Exceptions
try:
• There can be only a single else block and an else block is allowed only when there is at least
one except block.
• A try block should have at least one except block or a finally block.
Built-in Functions
Input/Output
print()
input()
int()
float()
complex()
bool()
Unicode/ASCII conversion
Conversion to string
list()
tuple()
dict()
set()
range()
MathemaBcal funcBons
For built-in mathemaBcal funcBons, the data type of the return value will be based on the
argument data types.
Importing Modules
import module-name
Example:
import math
math.fabs(2.1) # math is a name in the local scope
math.floor(2.1)
Example:
import mysql.connector as sql # sql is a name in local scope for mysql.connector
Example:
from math import fabs, floor
fabs(2.1)
floor(2.1)
math.fabs(2.1) # will cause NameError
ceil(2.1) # will cause NameError
Example:
from math import * #import all public names (not starting with underscore)
fabs(2.1)
floor(2.1)
Importing specific names from a module with different names in the local scope
Example:
from math import fabs as myabs, floor
myabs(2.1) # myabs is the name in local name for math.fabs
floor(2.1) # floor has the same name in local scope
fabs(2.1) # will cause NameError
Build-in Modules
math — Mathematical functions (as per C language standard)
FuncZon Remarks
math.fabs(x) Return absolute value. Return value is always float and does not
support complex.
FuncZon Remarks
random.randrange(stop) Returns a random integer in the range.
random.randrange(start, stop)
random.randrange(start, stop, step)
FuncZon Remarks
statistics.mean(iterable) Mean
statistics.median(iterable) Median
statistics.mode(iterable) If there are mulBple modes, the one occurring first in the
data is returned.
staBsBcs.mode([1,4,4,3,2,2,5]) gives 4
Example:
# function definition
def midvalue(a, b):
mid = (a+b)/2
return mid
Parameters (or Formal Parameters) are names defined by a funcBon to receive values from the caller
of the funcBon.
Arguments (or Actual Parameters) are values given to the parameters at the Bme of a funcBon call.
Omi{ng the return statement or a return statement without specifying a return value is equivalent
to return None.
is same as
The parameters defined as above can take both posiBonal arguments and keyword arguments. With
the above definiBon, all of the below funcBon calls do the same thing.
midvalue(5, 7.5)
midvalue(a = 5, b = 7.5)
midvalue(b = 7.5, a = 5)
midvalue(5, b = 7.5)
In a funcBon call:
• In the parameters list, parameters with default values can come only aper ALL the
parameters without default value.
calc(a, b=10, c, d=20) will cause a SyntaxError
With the above definiBon. FuncBon calls need not contain arguments for parameters c and d.
Examples:
r = calc(2, 3) # no argument for c and d
r = calc(2, 3, 4) # no argument for d
r = calc(2, 3, d=5) # no argument for c
r = calc(d=3, b=4, a=2) # no argument for c
Scope of Names
• Names can be defined at the module (i.e., file) level or at the funcBon level.
This default behaviour can be changed using the global statement within the funcBon
These names CANNOT be used in global statement to change the behaviour. CPython
implementaBon at present does not enforce any of these rules except (a). But can change in
future.
• If a variable is used inside a funcBon without assignment, the global scope variable is used if
available else it is an error.
• A name can refer to a variable, funcBon or module – all of them use the same binding
process.
global statement
Names listed in a global statement must not textually precede the global statement (within the
funcBon).
Examples:
def fun1():
var2 = 20 #local
print(var1) #global (NameError if not defined in global scope)
print(var2) #local
def fun2():
var1 = 20 #local
print(var1) #local
def fun3():
global var1
var1 = 20 #global
print(var1) #global
def fun4():
global var1, var2
var1 = 20 #global
var2 = 30 #global
print(var1, var2) #global
var1 = 10 #global
fun1()
print(var1) # prints 10
var1 = 10 #global
fun2()
print(var1) # prints 10
var1 = 10 #global
fun3()
print(var1) # prints 20
var1 = 10 #global
fun4()
print(var1, var2) # prints 20 30
Within a funcBon code block, the global declaraBon of a name should come before the name is used.
def funA():
print(var1) # SyntaxError - use before global declaration
global var1
Note: This produces a syntax error as the check is done at compile Bme.
Deleting Names
Names can be deleted from the scope using the del statement.
def fun():
global var1, var2
var1 = 10
var2 = 20
fun() # 1st call
del var2
fun() # 2nd call
def fun():
var1 = 10
print(var1) # prints 10
del var1
print(var1) # UnboundLocalError
The excepBon target assigned by the except clause is automaBcally deleted when the except block
completes.
excp = 10
try:
10 / 0
except Exception as excp:
print(excp) # prints division by zero
print(excp) # NameError
Data Structure
Concepts
• Data Structure is an organization of data that makes storage and operations on the
data have the required efficiency in terms of speed and memory usage.
• The data structure used depends on the kind of operations to be performed on the
data.
o Array is suitable if the access is mostly sequential and inserts/deletes are
infrequent.
o Linked list is suitable if the inserts/deletes are frequent but it takes more
space than array.
• Primitive data types are a set of basic data types from which data structure types
are constructed.
• Primitive data types in Python.
o Numeric types (int, float, complex & bool)
o String – It is actually a sequence of characters. It is considered primitive as
there is no character data type (like in C/C++)
Note: In Python, data structures that organize data in a linear order (with zero-based
index) are called sequences. String, list and tuple are sequence data types.
Stack
A stack is a linear data structure in which all the insertion and deletion of data values are
done at one end only.
Applications of Stack
• Expression Evaluation: It is used to evaluate prefix, postfix and infix expressions.
• Expression Conversion: It can be used to convert one form of expression (prefix,
postfix or infix) to one another.
• Syntax Parsing: Many compilers use a stack for parsing the syntax of expressions.
• Backtracking: It can be used for back traversal of steps in a problem solution.
• Parenthesis Checking: Stack is used to check the proper opening and closing of
parenthesis.
• String Reversal: It can be used to reverse a string.
• Function Call: Stack is used to keep information about the active functions or
subroutines.
def pop(stack):
return stack.pop() # IndexError if stack is empty
def isempty(stack):
return len(stack) < 1 # same as return not stack
def size(stack):
return len(stack)
def display(stack):
n = len(stack)
for i in range(n-1,-1,-1):
print(stack[i])
File Handling
Types of Files
Test Files
• End of line
o The default newline markers in Python are '\n' '\r' and '\r\n'.
o The operating system end-of-line (EOL) marker can be accessed using os.linesep. In
Windows, '\r\n' is the EOL. In Linux, '\n' is the EOL.
o Automatic newline translations in file read/write operations.
§ When writing, '\n' is translated to os.linesep
§ When reading, all the following are translated to '\n'
'\r'
'\r\n'
os.linesep
Binary Files
Opening Files
encoding can be specified only for text files. If it is not specified, it depends on the platform. Using
'utf-8' is recommended.
File opening modes:
• If + is added to the mode, both read and write operations are supported.
• If b is added to the mode, the file is opened in binary mode, else it is opened in text mode. t
can be added for text mode, which is anyway the default.
• The modes can be in any order: +br r+b br+ are all same.
No translation
An opened file needs to be closed after performing the required read/write operations. File object’s
close method needs to be called to close the file.
file_obj.close()
Note: Data written by successful write operations may not be saved completely to the disk if the
program ends without calling close(). This can happen even when even the program exits
successfully. Using with statement is highly recommend.
File Pointer
Offsets à 0 1 2 3 4 5 6 7 8
A B C D E F G H
• A file pointer that stores the current offset position in the file is maintained by the file
object.
• All file read and write operations are performed at the position of the file pointer. In the
above example, if the current offset is 3, read of single byte will give D.
• The file pointer position can be retrieved using the tell() method and can be set using the
seek() method.
file_obj.tell()
file_obj.seek(relative-offset, whence)
Sets the file pointer offset and returns the new absolute position.
The following restrictions apply for text files (not for binary files)
Function Description
file_obj.read(size= -1) Read and return at most size characters.
file_obj.readlines() Reads and returns the rest of the file as list of lines.
Newline character is included in the returned
strings.
Returns None
file_obj.flush() Flush the write buffers of the stream if applicable.
This does nothing for read-only and non-blocking
streams.
Returns None
Example:
# writing
with open('names.txt', 'w') as file:
for name in names:
file.write(name)
# Reading
with open('names.txt', 'r') as file:
name = file.readline()
while name:
print(name.rstrip())
name = file.readline()
All the methods shown above wok for binary as well but with the following differences:
• Deals with byte and bytes instead of character and strings. All size arguments are in bytes
instead of characters.
• Line ending is always a single '\n'. Cannot be specified as any other value.
Exceptions
Note that EOFError is not raised. When no data is available, read operations return empty value.
with Statement
Using the with statement, file objects can be automatically cleaned up without explicitly calling
close()
When the control leaves the statement block, file_obj.close() is automatically called even in case of
exceptions.
Using objects that do not support use in with statement will cause an error.
The pickle module implements serialization and de-serialization a Python object structure.
Example:
import os
import pickle
students = [
('John', 88, 55, 76),
('Tom', 81, 54, 66),
('Mary', 83, 65, 71)
]
# Pickling
def writeall():
with open('student.dat', 'wb') as file:
for student in students:
pickle.dump(student, file)
# Unpickling
def readall():
with open('student.dat', 'rb') as file:
while True:
try:
student = pickle.load(file)
except EOFError:
break
print(student)
# Search
def find(name):
found = False
if found:
return student
# Update
def update(name, marks):
found = False
if found:
student = (student[0], marks[0], marks[1], marks[2])
file.seek(offset, os.SEEK_SET)
pickle.dump(student, file)
return student
writeall()
readall()
student = find('Tom')
print('Found:', student)
student = update('Tom', (93, 75, 81)) # Line-A
print('Updated:', student)
readall() # Line-B
The update approach shown above works because the size of the binary representation of
the updated object exactly matches the original object. If sizes do not match, the data will
get corrupted.
This issue does not arise when adding a new object at the end of the file (i.e., using append
file mode)
CSV module
• The csv module implements reading and writing text files containing tabular data.
• Each line in the text file corresponds to one row of data.
• Each row consists of one or more columns separated by a delimiter (comma is the default
delimiter)
Writer object
csv.writer(file_obj)
file_obj should be opened in text mode with newline='' and should be writable.
Writer methods:
• writer.writerow(iterable) – writes one row of data
• writer.writerows(iterable of iterable) – writes multiple rows of data
Note: The argument of csv.writer() can be any object that has a write() method.
Reader object
csv.reader(file_obj)
file_obj should be opened in text mode with newline='' and should be readable.
Note: The argument of csv.reader() can also be an iterator of strings.
Example:
import csv
rows = [
['John', 'No 5, 1st Street', 9999999999],
['Tom', 'No 51, 21st "A" Street', 8888888888],
['Mary', 'No 15, 3rd Street']
]
# Writing CSV
def writeall():
with open('students.csv', 'w', newline='') as file:
writer = csv.writer(file)
writer.writerow(rows[0])
writer.writerow(rows[1])
writer.writerow(rows[2])
# Reading CSV
def readall():
with open('students.csv', 'r', newline='') as file:
reader = csv.reader(file)
for row in reader:
print(row)
The reader returns each row as a lists of strings (no automatic data types conversions):
try:
10 / 0
except Exception as ex:
print(ex)
• For regular (i.e., non-exponent) format, .0 is suffixed if there is no fractional part. This is
done to distinguish floats from integers.
• Format
o Exponent vs regular format – regular format if exponent is in the range -4 to 15
(both inclusive) else exponent formal. The same rule can be expressed as:
Regular format will
§ Not start with 0.0000
§ Not have larger than 16-digit integer part.
o Exponent will have at least 2 digits and + sign is printed for exponent.
o No trailing zeros, except for the .0 suffix to differentiate from integers.
• Significant Digits
o If the number has 15 or less significant digits, matching significant digits printed.
o If the number has more than 15 significant digits, the digits beyond the 15th
significant digit may not be printed as expected. This is because the number is
close to the precision limit of floating-point.
Note: sys.float_info.dig gives the maximum number of significant decimal digits that can be
represented in a float without loss of precision. In CPython, sys.float_info.dig is 15. This is likely to be
the case in most Python implementations as most of them use 8-byte IEEE floating-point format.
For exam purpose – Assume that the output is rounded to 16 significant digits and trailing zeros are
removed.
Example:
print(10 / 5) prints 2.0
print(1 / 625) prints 0.0016
print(20_000_000_000 / 3) prints 6666666666.666667