Unit - 2 Sequence Data Types and OOP
Unit - 2 Sequence Data Types and OOP
The methods above can be generalized to insert or strip arbitrary characters on the
ends of a string. In particular, ljust and rjust can take an additional argument that specifies a
padding character, while lstrip, rstrip and strip can take an additional argument that specifies a
set of characters to be stripped.
>>> s = ‘123’
>>> s.ljust(5, ‘0’) # pad ‘0’
‘12300’
>>> s.rjust(6, ‘-’) # pad ‘-’
‘---123’
>>> s = ‘aabcdceft’
>>> s.lstrip(‘a’) # strip ‘a’
‘bcdceft’
>>> s.lstrip(‘bac’) # the set {‘b’, ‘a’, ‘c ’}
‘dceft’
>>> s.rstrip(‘ag’) # the set {‘a’, ‘g ’}
‘aabcdceft’
>>> s.strip(‘gabf’) # {‘g’, ‘a’, ‘b’, ‘f ’}
‘cdceft’
A method that splits a string into a list of sub strings is split, which takes a single argument
specifying the deliminator, and returns the list that results from the splitting.
>> s = ‘1 2 3’
>>> s.split(‘’)
[‘1’, ‘2’, ‘3’]
>>> s = ‘1<2<3’
>>> s.split(‘<’)
[‘1’, ‘2’, ‘3’]
>>> s = ‘1==2==3’
>>> s.split(‘=’)
[‘1’, ‘’, ‘2’, ‘’, ‘3’]
>>> s.split(‘==’)
[‘1’, ‘2’, ‘3’]
>>> s = ‘1!=2!=3’
>>> s.split(‘!=’)
[‘1’, ‘2’, ‘3’]
As shown by the example above, an empty string results in the splitting of two
consecutive deliminators, and a deliminator can be an arbitrary string that contains one or more
characters.
The input deliminator is optional; when it is not specified, all consecutive runs of whitespace
characters are taken as deliminators
>>> s = ‘ 1 2\t\t3\n4’
>>> s
‘ 1 2\t\t3\n4’
>>> s.split()
[‘1’, ‘2’, ‘3’, ‘4’]
The reverse method to split is join, which takes a list argument and joins the list into a string
with the string being the concatenator.
>>> s = ‘’
>>> s.join([‘1’, ‘2’, ‘3’])
‘1 2 3’
>>> l = [‘abc’, ‘d’, ‘ef’]
>>> ‘--’.join(l)
‘abc --d--ef’
>>> ‘-’.join([1, 2, 3])
Traceback ( most recent call last):
File "<stdin >", line 1, in <module >
TypeError: sequence item 0: expected string , int found
As shown by the examples above, the split method returns a list of strings, and a list of
strings should be used as the argument to join. Any other list items are not allowed by the join
method, and no implicit conversion is performed.
Using split and join, one can replace all occurrences of a sub string in a string with another
string. For example, the following code replaces all occurrences of ‘abc’ in a string into ‘—’:
>>> s1 = ‘abc’
>>> s2 = ‘---’
>>> s = ‘abcdefabcghiabc’
>>> s2.join(s.split(s1))
‘---def ---ghi ---’
Python provides a method, repalce, for sub string replacement directly. It takes two string
arguments, specifying the substring to be replaced and the replacement string, respectively, and
returns a copy of the string after replacement.
>>> s = ‘abcdefabcghiabc’
>>> s.replace(‘abc’, ‘---’)
‘---def ---ghi ---’
replace allows an additional argument that specifies a count, so that the first occurrences of the sub
string up to the count are replaced.
>>> s = ‘abcdefabcghiabc ’
>>> s.replace(‘abc ’, ‘---’, 1)
‘---defabcghiabc ’
>>> s.replace(‘abc ’, ‘---’, 2)
‘---def ---ghiabc ’
A final string formatting method is format, which is an alternative to the string formatting
expression introduced in Chap. 3. The method is bound to a pattern string, and takes arguments
that fill pattern fields in the string. A pattern field is formed by a pair of curly brackets, and
contains either a number specifying the index of the corresponding argument, or a keyword to be
filled by a keyword argument. For example,
>>> ‘{0} + {1} = {2}’. format(1, 2, 1+2)
‘1 + 2 = 3’
>>> ‘Hello , {0}’. format(‘Python ’)
‘Hello , Python ’
>>> ‘{2}-{0}-{1}’. format(‘abc ’, ‘def ’, ‘ghi ’)
‘ghi -abc -def ’
>>> ‘{x}-{y}-{0}’. format(‘ghi ’, x=‘abc ’, y=‘def ’)
‘abc -def -ghi ’
In the example above, the last method call contains two keyword arguments, x and y, which fill
the keyword fields {x} and {y}, respectively. Note that similar to other function calls, keyword
arguments must be placed after non-keyword arguments. If the arguments are sequentially filled,
the indics in the pattern fields can be omitted.
>>> ‘{} + {} = {}’.format(1, 2, 3)
‘1 + 2 = 3’
Formatting specifications can be given to each pattern field by using ‘:’, where follows the
pattern syntax in string formatting expressions. For example,
>>> ‘{0:d} + {1:.2f} = {2}’.format(1, 2.0, 1+2.0)
‘1 + 2.00 = 3.0’
>>> s = ‘{0:d} + {1:.2f} = {x:s}’
>>> s.format(1, 2, x=str(1+2))
‘1 + 2.00 = 3’
In the example above, ‘:d’, ‘:.2f’ and ‘:s’ are used to specify the format of an integer, a
floating point number with 2 digits after the decimal point and a string, respectively. Formatting
specifications can be used for keyword and non-keyword arguments.
If there are too few arguments, an error will be raised. If there are too many arguments, the
first ones will be used to fill the pattern string
>>> s=‘{} + {} = {}’
>>> s.format(1)
Traceback ( most recent call last):
File "<stdin >", line 1, in <module >
IndexError: tuple index out of range
>>> s.format(1, 2, 3, 4)
‘1 + 2 = 3’
There is a built-in function, format(v,s), which takes a value v and a pattern string s as its input
arguments, and return a string by calling s.format(v).
>>> format (3.1,‘.2f’) ‘3.10’
The methods and functions above are frequently used for sequential types, and this section
categories them according to the functionality and return type. There are more methods for
sequential types. The Python documentation is a useful reference for looking for a pre-defined
function before writing one custom function.
8.2 Dicts—A Mutable Mapping Type
The dict type is a container type. Similar to lists, dict objects are mutable. On the other hand,
unlike lists and tuples, which are sequential containers, dicts are associative containers, which
represent mappings from keys to values. Intuitively, dict objects resemble dictionaries, which
map words to their meanings. When a word is looked up in a dictionary, it is used as a key for
finding the corresponding value, which is the entry explaining the word. Dicts generalize the
definitions of keys and values, and are useful for mapping student IDs to their GPAs, looking up
the price of a stock given a company name, and other key-value associations where keys are
discontinuous and distinct.
Formally, a dict object consists of a set of (key, value) pairs, which are items. A
key must be an immutable object, while a value can be any object. The most important
operation for a dict object is lookup, which returns the corresponding value given a key. As a
result, keys must be distinct in a dict object, but values do not have to be distinct.
A dict literal consists of a comma-separated list of key: value pairs, enclosed in a pair of curly
brackets.
>>> d = {1: ‘a’, 2: ‘b’, 3: ‘c’}
>>> d
{1: ‘a’, 2: ‘b’, 3: ‘c’}
>>> type(d)
<type ‘dict’>
>>> d = {1.0: 1, True: 1+2j, None: ‘abc’, (1,2): False}
>>> d
{(1, 2): False , 1.0: (1+2j), None: ‘abc’}
>>> type(d)
<type ‘dict’>
>>> d = {[1,2]: ‘a’}
Traceback ( most recent call last):
File "<stdin >", line 1, in <module >
TypeError: unhashable type: ‘list’
In the example above, the first dict represents a mapping from integers to strings. The second
dict represents a mapping between miscellaneous objects, where the keys include the floating
point number 1.0, the Boolean object True, the None object and the tuple object (1, 2), and the
values include the integer 1, the complex number 1 + 2j, the string ‘abc’ and the Boolean object
False. The third dict literal leads to an error, because the mutable object [1, 2] is used as a key.
The literal of an empty dict is {}.
When two duplicated keys are defined in a dict literal, the latter overrides the former.
>>> d = {‘a’: 1, ‘b’: 2, ‘a’: 3}
>>> d
{‘a’: 3, ‘b’: 2}
In the example above, d contains two identical keys, which are mapped into the integers 1 and 3,
respectively. Python discards the key value pair (‘a’, 1), keeping only (‘a’, 3) for the key ‘a’.
Python uses the == operator to decide whether two keys are identical. As a result, two numerical
values can be identical even if their types are different.
>>> d = {1: ‘a’, 2: ‘b’, 1.0: ‘c’}
>>> d
{1: ‘c’, 2: ‘b’}
In the example above, the keys 1 and 1.0 are treated as identical because the
expression 1 == 1.0 is True. As immutable objects, floating point numbers can be used as keys to
dicts. However, due to rounding off errors, Python’s representation of floating point numbers
can be imprecise. These can also be conflit with integer keys as shown above. As a result, it is
recommended to avoid the use of floating point numbers as keys when possible.
Dict operators similar to tuples and lists, the == and != operators can be used to find the equality
between dict objects. Dicts are unordered collections, the order in which items are specified or
added to a dict object does not affect the value of the dict object.
>>> d1 = {1: ‘a’, 2: ‘b’, 3: ‘c’}
>>> d2 = {3: ‘c’, 1: ‘a’, 2: ‘b’}
>>> d3 = {}
>>> d1 == d2
True
>>> d1 != d3
True
The lookup operation is the most commonly used operation for dict objects. The syntax is
formally identical to that of the getitem operation for tuples and lists, which specify the index of
an item by a pair of square brackets. The only difference is that for a dict object, a key is used in
the place of the index for tuples and lists.
>>> d = {1: ‘a’, 2: ‘b’, 3: ‘c’}
>>> d[1]
‘a’
>>> d[3]
‘c’
>>> d[5]
Traceback ( most recent call last):
File "<stdin >", line 1, in <module >
KeyError: 5
As shown by the example above, a key error is raised if the key to lookup is not in the dict object.
The dict method get is commonly used as an alternative to lookup, which allows default values if
the specified key is not in the dict:
>>> d = {1: ‘a’, 2: ‘b’, 3: ‘c’}
>>> d.get(3, ‘z’)
‘c’
>>> d.get(5, ‘z’)
‘z’
As shown in the example above, get takes two arguments, the first being the key, and the second
being the default value. If the key is in the dict, the return value is thevalue of the key in the dict.
Otherwise the default value is returned by get.
Similar to the case of tuples and lists, the operator in and not in can be applied to a dict object,
returning whether an object is in the dict or not. When applied to a dict, the operators return
whether an object is a key in the dict.
>>> d = {1: ‘a’, 2: ‘b’, 3: ‘c’}
>>> 1 in d
True
>>> 4 in d
False
>>> ‘a’ in d
False
Note that the last expression in the example above is evaluated to False, because ‘a’ is not a key
in d, despite that it is the value of the key 1 in d.
The method call d.get(k, v) can be regarded as a succinct version of the following function:
def defaultlookup (d, k, v):
if k in d:
return d[k]
else :
return v
The len function can be applied to dict objects, returning the number of items in the dict.
>>> len({1: ‘a’, 2: ‘b’, 3: ‘c’})
3
>>> len({})
0
Conversion between dicts and other types. Dicts can be converted to strings, Boolean objects,
tuples and lists, but not to numbers. The string conversion of a dict object represents the literal
form of the dict object.
>>> a = 1.0
>>> b = True
>>> c = ‘a’
>>> d = {a: 1, 2: b, c: 3}
>>> str(d)
"{‘a’: 3, 1.0: 1, 2: True}"
The Boolean conversion of a dict is False only when the dict is empty, and True otherwise.
>>> bool({1: ‘a’, 2: ‘b’, 3: ‘c’})
True
>>> bool({1: 1})
True
>>> bool({})
False
The tuple and list conversions of a dict object consist of all the keys in the dict object.
>>> d = {1: 1.0, 2: 9, 3: 8}
>>> tuple(d)
(1, 2, 3)
>>> list(d)
[1, 2, 3]
Lists and tuples can be converted to dicts using the dict function, but numbers, strings, or
Boolean objects cannot. To be convertable to a dict, a tuple or list must be a sequence (key,
value) pairs.
>>> d1 = dict(((3, ‘a’), (2, ‘b’), (3, ‘c’)))
>>> d2 = dict([(3, ‘a’), (2, ‘b’), (3, ‘c’)])
>>> d1
{2: ‘b’, 3: ‘c’}
>>> d1 == d2
True
8.2.1 Dict Modification
There are two ways to change a dict object. The first is the setitem operation, which sets the
value of a key directly via the assignment syntax, and the delitem operator, which deletes a key-
value pair from a dict object. The syntax of the setitem operation is d[key] = value, where d is a
dict identifier, key is an immutable object and value is an arbitrary object. If key is not an
existing key in d, (key, value) is added as a new item in d. Otherwise, value is used to replace the
old value of key in d. For example
>>> d = {1: ‘a’, 2: ‘b’, 3: ‘c’}
>>> d[0] = ‘’ # adds a new entry to d
>>> d
{0: ‘’, 1: ‘a’, 2: ‘b’, 3: ‘c’}
>>> d[1] = ‘e’ # update an existing entry in d
>>> d
{0: ‘’, 1: ‘e’, 2: ‘b’, 3: ‘c’}
The syntax of the delitem operation is
del d[key]
where d is a dict identifier and key is an immutable object. If key is an existing key in d, the
corresponding item will be removed from d. Otherwise a key error is raised. A commonly used
method to change a dict object is update, which takes a single dict argument, using it to update
the dict. In particular, each (key, value) pair in the argument is enumerated, and used to update
the dict in the same way as setitem. If key is not already in the dict, the item (key, value) is added
to the dict as a new item.
Otherwise, the corresponding value of key is updated by value. The return value of the update
method is None.
>>> d = {1: ‘a’, 2: ‘b’, 3: ‘c’}
>>> d1 = {0: ‘’, 1: ‘e’}
>>> d.update(d1)
>>> d
{0: ‘’, 1: ‘e’, 2: ‘b’, 3: ‘c’}
In the example above, d1 is used to update d. There are two items in d1, namely (0, ‘ ’) and (1,
‘e’). The key 0 is not in d before the update, and therefore (0, ‘ ’) is added to d. On the other
hand, the key 1 is already in d, and therefore the existing item (1, ‘a’) in d is updated with the
item (1, ‘e’).
A method to remove an item from a dict is pop, which takes a single argument. If the argument
is a key in the dict, the corresponding item is removed, with is value returned. Otherwise, a key
error is raised.
>>> d = {1: ‘a’, 2: ‘b’, 3: ‘c’}
>>> d.pop(1)
‘a’
>>> d
{2: ‘b’, 3: ‘c’}
>>> d.pop(0)
Traceback ( most recent call last):
File "<stdin >", line 1, in <module >
KeyError: 0
pop can take an optional second argument, which specifies the default return value if the first
argument is not a key in the dict. When the second argument is given, no key error is raised.
>>> d = {1: ‘a’, 2: ‘b’, 3: ‘c’}
>>> d.pop(1, ‘d’)
‘a’
>>> d
{2: ‘b’, 3: ‘c’}
>>> d.pop(0, ‘d’)
‘d’
>>> d
{2: ‘b’, 3: ‘c’}
A method that removes all the items from a dict object is clear, which takes no argument, and
returns None.
>>> d = {1: ‘c’, 2: ‘b’, 3: ‘c’}
>>> d.clear()
>>> d
{}
Similar to the case of lists, modifications to a dict object shared by multiple identifiers results in
a simultaneous change of values of all the identifiers.
>>> d = {1: ‘a’, 2: ‘b’, 3: ‘c’}
>>> d1 = d
>>> t1 = (d1 , 4, ‘d’)
>>> def f(d2):
... d2.update({0: ‘e’, 1: ‘d’})
... del d2[3]
...
>>> f(t1[0])
>>> d
{0: ‘e’, 1: ‘d’, 2: ‘b’}
>>> d1
{0: ‘e’, 1: ‘d’, 2: ‘b’}
>>> t1
({0: ‘e’, 1: ‘d’, 2: ‘b’}, 4, ‘d’)
In the example above, the identifiers d, d1 and t1[0] are bound to the same dict object. When f is
called, the local identifier d2 is bound to the same object as the argument. As a result, when f
(t1[0]) is called, all the identifiers above are changed.
In addition to dict modification methods, the dict type also supports a set of methods that return
information of a dict object, including keys, values and items, which take no argument and
return a list of copies of the keys, values and items of a dict object, respectively.
>>> d = {1: ‘a’, 2: ‘b’, 3: ‘c’}
>>> d.keys()
[1, 2, 3]
>>> d.values()
[‘a’, ‘b’, ‘c’]
8.2 Dicts—A Mutable Mapping Type 201
>>> d.items()
[(1, ‘a’), (2, ‘b’), (3, ‘c’)]
Because the return values of the methods are copies of the original keys, values and items,
modifications to the return values do not affect the original dict.
>>> d = {1: ‘a’, 2: ‘b’, 3: ‘c’}
>>> l = d.keys()
>>> l
[1, 2, 3]
>>> l[0] = 0
>>> l
[0, 2, 3]
>>> d
{1: ‘a’, 2: ‘b’, 3: ‘c’}
• The ∧ operator and the symmetric_difference method return the symmetric difference
sets, which contains all the items in the first set that are not in the second set.
between the two sets, which consists of elements in either but not both of the sets.
>>> s1 = {1, 2, 3}
>>> s2 = {3, 4}
>>> s1&s2
set([3])
>>> s1.union(s2)
set([1, 2, 3, 4])
>>> s1 -s2
set([1, 2])
>>> s1.symmetric_difference(s2)
set([1, 2, 4])
Conversion between sets and other types. Set objects can be converted into strings, Boolean
objects, tuples and lists. The string conversion of a set object is aliteral form of the set; the
Boolean conversion of a set object is False only if the set is empty, and True otherwise; the tuple
and list conversions of a set object consists of all the items in the set, in arbitrary (but not
random) order.
>>> s = {‘a’, ‘b’, ‘c’, 1, 2, 3}
>>> str(s)
"set([‘a’, 1, 2, 3, ‘c’, ‘b’])"
>>> print s
set([‘a’, 1, 2, 3, ‘c’, ‘b’])
>>> bool(s)
True
>>> if s :
... print ‘non -empty ’
...
non -empty
>>> tuple(s)
(‘a’, 1, 2, 3, ‘c’, ‘b’)
>>> list(s)
[‘a’, 1, 2, 3, ‘c’, ‘b’]
Strings, tuples, lists and dicts can be converted into sets. The set conversion of a string consists of
all the characters in the string, the set conversion of a tuple or a list consists of all the items in
the sequence, while the set conversion of a dict consists of all the keys.
>>> set("123")
set([‘1’, ‘3’, ‘2’])
>>> set([‘c’, True , 1+3j])
set([True , ‘c’, (1+3j)])
>>> set({1:1, 2:0, 3:-1})
set([1, 2, 3])
Python supports the bitwise operations above by the integer operation |, & and ∧, respectively.
different from the ith bit of n2, and 0 otherwise.
>>> a = 0b1101
>>> b = 0b1001
>>> a
13
>>> b
9
>>> a|b
13
>>> bin(a|b)
‘0b1101’
>>> a&b
8.3 Sets and Bitwise Operations 211
9
>>> bin(a&b)
‘0b1001’
>>> a^b
4
>>> bin(a^b)
‘0b100’
The correlation between set operations and bitwise integer operations is shown in
Fig. 8.2. Note that the difference (i.e. –) operation between two sets is not correlated to the –
|, & and ∧ are all binary bitwise operations, taking two operands. There is a unary bitwise
operation between two numbers, which is an arithmetic operator rather than a bitwise operator.
Boolean operator, ∼ , which takes one operand and flips every bit in it:
Fig. 8.2 The correlation between set operations and bitwise integer operations
>>> a=0b1010101100
>>> bin(~a)
‘-0b1010101101 ’
In addition to bitwise Boolean operations, Python also supports a set of bitwise shifting
operations between two integers. In particular, right-shift operation n >> k shifts the binary
form of n to the right by k bits, and the left-shift operation n >> k shifts the binary form of n to
the left by k bits. In terms of the value, the operation n >> k is equivalent to n/(2k ) and the n k
operation is equivalent to n × 2k . In both n/(2k ) and n × 2k , n is treated as a positive integer.
>>> n = 0b1011
>>> bin(n<<1)
0b10110
>>> bin(n>>1)
0b101
class Dog:
sound = "bark"
Object of Python Class
An Object is an instance of a Class. A class is like a blueprint while an instance is a copy
of the class with actual values. It’s not an idea anymore, it’s an actual dog, like a dog of
breed pug who’s seven years old. You can have many dogs to create many different
instances, but without the class as a guide, you would be lost, not knowing what
information is required.
An object consists of:
State: It is represented by the attributes of an object. It also reflects the
properties of an object.
Behavior: It is represented by the methods of an object. It also reflects the
response of an object to other objects.
Identity: It gives a unique name to an object and enables one object to interact
with other objects.
# A simple class
# attribute
attr1 = "mammal"
attr2 = "dog"
# A sample method
def fun(self):
print("I'm a", self.attr1)
print("I'm a", self.attr2)
# Driver code
# Object instantiation
Rodger = Dog()
def show(self):
print("Hello my name is " + self.name+" and I" +
" work in "+self.company+".")
def show(somename):
print("Hello my name is " + somename.name +
" and I work in "+somename.company+".")
# Sample Method
def say_hi(self):
print('Hello, my name is', self.name)
p = Person('Nikhil')
p.say_hi()
Output:
Hello, my name is Nikhil
Explanation:
In this example, we are creating a Person class and we have created a name instance
variable in the constructor. We have created a method named as say_hi() which returns the
string “Hello, my name is {name}”.We have created a person class object and we pass the
name Nikhil to the instance variable. Finally, we are calling the say_hi() of the class.
__str__() method
Python has a particular method called __str__(). that is used to define how a class object
should be represented as a string. It is often used to give an object a human-readable
textual representation, which is helpful for logging, debugging, or showing users object
information. When a class object is used to create a string using the built-in functions
print() and str(), the __str__() function is automatically used. You can alter how objects of
a class are represented in strings by defining the __str__() method.
class GFG:
def __init__(self, name, company):
self.name = name
self.company = company
def __str__(self):
return f"My name is {self.name} and I work in {self.company}."
my_obj = GFG("John", "GeeksForGeeks")
print(my_obj)
Output:
My name is John and I work in GeeksForGeeks.
Explanation:
In this example, We are creating a class named GFG.In the class, we are creating two
instance variables name and company. In the __str__() method we are returning
the name instance variable and company instance variable. Finally, we are creating the
object of GFG class and we are calling the __str__() method.
Class and Instance Variables
Instance variables are for data, unique to each instance and class variables are for attributes
and methods shared by all instances of the class. Instance variables are variables whose
value is assigned inside a constructor or method with self whereas class variables are
variables whose value is assigned in the class.
Defining instance variables using a constructor.
# Python3 program to show that the variables with a value
# assigned in the class declaration, are class variables and
# variables inside methods and constructors are instance
# variables.
class Dog:
# Class Variable
animal = 'dog'
# Instance Variable
self.breed = breed
self.color = color
print('Rodger details:')
print('Rodger is a', Rodger.animal)
print('Breed: ', Rodger.breed)
print('Color: ', Rodger.color)
print('\nBuzo details:')
print('Buzo is a', Buzo.animal)
print('Breed: ', Buzo.breed)
print('Color: ', Buzo.color)
# Class variables can be accessed using class
# name also
print("\nAccessing class variable using class name")
print(Dog.animal)
Output:
Rodger details:
Rodger is a dog
Breed: Pug
Color: brown
Buzo details:
Buzo is a dog
Breed: Bulldog
Color: black
Accessing class variable using class name
dog
Explanation:
A class named Dog is defined with a class variable animal set to the string “dog”. Class
variables are shared by all objects of a class and can be accessed using the class name. Dog
class has two instance variables breed and color. Later we are creating two objects of
the Dog class and we are printing the value of both objects with a class variable named
animal.
Defining instance variables using the normal method:
class Dog:
# Class Variable
animal = 'dog'
# Instance Variable
self.breed = breed
Prerequisites: Object-Oriented Programming in Python, Object-Oriented Programming in
Python | Set 2
Constructors are generally used for instantiating an object. The task of constructors is to
initialize(assign values) to the data members of the class when an object of the class is
created. In Python the __init__() method is called the constructor and is always called
when an object is created.
Syntax of constructor declaration :
def __init__(self):
# body of the constructor
Types of constructors :
default constructor: The default constructor is a simple constructor which
doesn’t accept any arguments. Its definition has only one argument which is a
reference to the instance being constructed.
parameterized constructor: constructor with parameters is known as
parameterized constructor. The parameterized constructor takes its first
argument as a reference to the instance being constructed known as self and the
rest of the arguments are provided by the programmer.
Example of default constructor :
Python3
class GeekforGeeks:
# default constructor
def __init__(self):
self.geek = "GeekforGeeks"
Output
GeekforGeeks
Example of the parameterized constructor :
Python3
class Addition:
first = 0
second = 0
answer = 0
# parameterized constructor
def __init__(self, f, s):
self.first = f
self.second = s
def display(self):
print("First number = " + str(self.first))
print("Second number = " + str(self.second))
print("Addition of two numbers = " + str(self.answer))
def calculate(self):
self.answer = self.first + self.second
Output
First number = 1000
Second number = 2000
Addition of two numbers = 3000
First number = 10
Second number = 20
Addition of two numbers = 30
Example:
Python
class MyClass:
def __init__(self, name=None):
if name is None:
print("Default constructor called")
else:
self.name = name
print("Parameterized constructor called with name", self.name)
def method(self):
if hasattr(self, 'name'):
print("Method called with name", self.name)
else:
print("Method called without a name")
Output
Default constructor called
Method called without a name
('Parameterized constructor called with name', 'John')
('Method called with name', 'John')
Explanation:
In this example, we define a class MyClass with both a default constructor and a
parameterized constructor. The default constructor checks whether a parameter has been
passed in or not, and prints a message to the console accordingly. The parameterized
constructor takes in a single parameter name and sets the name attribute of the object to the
value of that parameter.
We also define a method method() that checks whether the object has a name attribute or
not, and prints a message to the console accordingly.
We create two objects of the class MyClass using both types of constructors. First, we
create an object using the default constructor, which prints the message “Default
constructor called” to the console. We then call the method() method on this object, which
prints the message “Method called without a name” to the console.
Next, we create an object using the parameterized constructor, passing in the name “John”.
The constructor is called automatically, and the message “Parameterized constructor called
with name John” is printed to the console. We then call the method() method on this object,
which prints the message “Method called with name John” to the console.
Overall, this example shows how both types of constructors can be implemented in a single
class in Python.
Inheritance in Python
One of the core concepts in object-oriented programming (OOP) languages is inheritance.
It is a mechanism that allows you to create a hierarchy of classes that share a set of
properties and methods by deriving a class from another class. Inheritance is the capability
of one class to derive or inherit the properties from another class.
Benefits of inheritance are:
Inheritance allows you to inherit the properties of a class, i.e., base class to another, i.e.,
derived class. The benefits of Inheritance in Python are as follows:
It represents real-world relationships well.
It provides the reusability of a code. We don’t have to write the same code again
and again. Also, it allows us to add more features to a class without modifying it.
It is transitive in nature, which means that if class B inherits from another class
A, then all the subclasses of B would automatically inherit from class A.
Inheritance offers a simple, understandable model structure.
Less development and maintenance expenses result from an inheritance.
Python Inheritance Syntax
The syntax of simple inheritance in Python is as follows:
Class BaseClass:
{Body}
Class DerivedClass(BaseClass):
{Body}
# Constructor
def __init__(self, name, id):
self.name = name
self.id = id
Output:
Satyam 102
def Print(self):
print("Emp class called")
Output:
Mayank 103
Emp class called
Example of Inheritance in Python
Let us see an example of simple Python inheritance in which a child class is inheriting the
properties of its parent class. In this example, ‘Person’ is the parent class, and ‘Employee’
is its child class.
# A Python program to demonstrate inheritance
class Person(object):
# Constructor
def __init__(self, name):
self.name = name
# To get name
def getName(self):
return self.name
# Driver code
emp = Person("Geek1") # An Object of Person
print(emp.getName(), emp.isEmployee())
Output:
Geek1 False
Geek2 True
# parent class
class Person(object):
def display(self):
print(self.name)
print(self.idnumber)
# child class
class Employee(Person):
def __init__(self, name, idnumber, salary, post):
self.salary = salary
self.post = post
Output:
Rahul
886012
Python program to demonstrate error if we forget to invoke __init__() of the parent
If you forget to invoke the __init__() of the parent class then its instance variables would
not be available to the child class. The following code produces an error for the same
reason.
class A:
def __init__(self, n='Rahul'):
self.name = n
class B(A):
def __init__(self, roll):
self.roll = roll
object = B(23)
print(object.name)
Output :
Traceback (most recent call last):
File "/home/de4570cca20263ac2c4149f435dba22c.py", line 12, in
print (object.name)
AttributeError: 'B' object has no attribute 'name'
def display(self):
print(self.name, self.age)
# child class
class Student(Person):
def __init__(self, name, age):
self.sName = name
self.sAge = age
# inheriting the properties of parent class
super().__init__("Rahul", age)
def displayInfo(self):
print(self.sName, self.sAge)
Output:
Rahul 23
Mayank 23
Adding Properties
One of the features that inheritance provides is inheriting the properties of the parent class
as well as adding new properties of our own to the child class. Let us see this with an
example:
# parent class
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
def display(self):
print(self.name, self.age)
# child class
class Student(Person):
def __init__(self, name, age, dob):
self.sName = name
self.sAge = age
self.dob = dob
# inheriting the properties of parent class
super().__init__("Rahul", age)
def displayInfo(self):
print(self.sName, self.sAge, self.dob)
Output:
Here we can see that we added a new property to the child class, i.e., date of birth (dob).
Rahul 23
Mayank 23 16-03-2000
class Base1(object):
def __init__(self):
self.str1 = "Geek1"
print("Base1")
class Base2(object):
def __init__(self):
self.str2 = "Geek2"
print("Base2")
def printStrs(self):
print(self.str1, self.str2)
ob = Derived()
ob.printStrs()
Output:
Base1
Base2
Derived
Geek1 Geek2
Multilevel inheritance: When we have a child and grandchild relationship. This
means that a child class will inherit from its parent class, which in turn is
inheriting from its parent class.
# A Python program to demonstrate inheritance
# Constructor
def __init__(self, name):
self.name = name
# To get name
def getName(self):
return self.name
# Constructor
def __init__(self, name, age):
Base.__init__(self, name)
self.age = age
# To get name
def getAge(self):
return self.age
class GrandChild(Child):
# Constructor
def __init__(self, name, age, address):
Child.__init__(self, name, age)
self.address = address
# To get address
def getAddress(self):
return self.address
# Driver code
g = GrandChild("Geek1", 23, "Noida")
print(g.getName(), g.getAge(), g.getAddress())
Output:
Geek1 23 Noida
Hierarchical inheritance More than one derived class can be created from a
single base.
Hybrid inheritance: This form combines more than one form of inheritance.
Basically, it is a blend of more than one type of inheritance.
For more details please read this article: Types of inheritance in Python
Private members of the parent class
We don’t always want the instance variables of the parent class to be inherited by the child
class i.e. we can make some of the instance variables of the parent class private, which
won’t be available to the child class.
In Python inheritance, we can make an instance variable private by adding double
underscores before its name. For example:
# Python program to demonstrate private members
# of the parent class
class C(object):
def __init__(self):
self.c = 21
class D(C):
def __init__(self):
self.e = 84
C.__init__(self)
object1 = D()
Output :
Here we can see that when we tried to print the variable ‘c’, its value 21 is printed on the
console. Whereas when we tried to print ‘d’, it generated the error. This is because the
variable ‘d’ is made private by using the underscores. It is not available to the child class
‘D’ and hence the error.
21
File "/home/993bb61c3e76cda5bb67bd9ea05956a1.py", line 16, in
print (object1.d)
AttributeError: type object 'D' has no attribute 'd'
def get_value(self):
return self.value
Output
10
Static method:-
class MyClass:
def __init__(self, value):
self.value = value
@staticmethod
def get_max_value(x, y):
return max(x, y)
print(MyClass.get_max_value(20, 30))
print(obj.get_max_value(20, 30))
Output
30
30
Below is the complete Implementation
# Python program to demonstrate
# use of class method and static method.
from datetime import date
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
print(person1.age)
print(person2.age)
Output:
21
25
True
Python Exception Handling
Error in Python can be of two types i.e. Syntax errors and Exceptions. Errors are problems
in a program due to which the program will stop the execution. On the other hand,
exceptions are raised when some internal events occur which change the normal flow of
the program.
Different types of exceptions in python:
In Python, there are several built-in Python exceptions that can be raised when an error
occurs during the execution of a program. Here are some of the most common types of
exceptions in Python:
SyntaxError: This exception is raised when the interpreter encounters a syntax
error in the code, such as a misspelled keyword, a missing colon, or an
unbalanced parenthesis.
TypeError: This exception is raised when an operation or function is applied to
an object of the wrong type, such as adding a string to an integer.
NameError: This exception is raised when a variable or function name is not
found in the current scope.
IndexError: This exception is raised when an index is out of range for a list,
tuple, or other sequence types.
KeyError: This exception is raised when a key is not found in a dictionary.
ValueError: This exception is raised when a function or method is called with
an invalid argument or input, such as trying to convert a string to an integer
when the string does not represent a valid integer.
AttributeError: This exception is raised when an attribute or method is not
found on an object, such as trying to access a non-existent attribute of a class
instance.
IOError: This exception is raised when an I/O operation, such as reading or
writing a file, fails due to an input/output error.
ZeroDivisionError: This exception is raised when an attempt is made to divide a
number by zero.
ImportError: This exception is raised when an import statement fails to find or
load a module.
These are just a few examples of the many types of exceptions that can occur in Python.
It’s important to handle exceptions properly in your code using try-except blocks or other
error-handling techniques, in order to gracefully handle errors and prevent the program
from crashing.
Difference between Syntax Error and Exceptions
Syntax Error: As the name suggests this error is caused by the wrong syntax in the code.
It leads to the termination of the program.
Example:
There is a syntax error in the code . The ‘if' statement should be followed by a colon (:),
and the ‘print' statement should be indented to be inside the ‘if' block.
amount = 10000
if(amount > 2999)
print("You are eligible to purchase Dsa Self Paced")
Output:
Exceptions: Exceptions are raised when the program is syntactically correct, but the code
results in an error. This error does not stop the execution of the program, however, it
changes the normal flow of the program.
Example:
Here in this code a s we are dividing the ‘marks’ by zero so a error will occur known
as ‘ZeroDivisionError’
marks = 10000
a = marks / 0
print(a)
Output:
In the above example raised the ZeroDivisionError as we are trying to divide a number by
0.
Note: Exception is the base class for all the exceptions in Python. You can check the
exception hierarchy here.
Example:
1) TypeError: This exception is raised when an operation or function is applied to an
object of the wrong type. Here’s an example:
Here a ‘TypeError’ is raised as both the datatypes are different which are being added.
x=5
y = "hello"
z=x+y
output:
Traceback (most recent call last):
File "7edfa469-9a3c-4e4d-98f3-5544e60bff4e.py", line 4, in <module>
z = x + y
TypeError: unsupported operand type(s) for +: 'int' and 'str'
try catch block to resolve it:
The code attempts to add an integer (‘x') and a string (‘y') together, which is not a valid
operation, and it will raise a ‘TypeError'. The code used a ‘try' and ‘except' block to catch
this exception and print an error message.
x=5
y = "hello"
try:
z=x+y
except TypeError:
print("Error: cannot add an int and a str")
Output
Error: cannot add an int and a str
Try and Except Statement – Catching Exceptions
Try and except statements are used to catch and handle exceptions in Python. Statements
that can raise exceptions are kept inside the try clause and the statements that handle the
exception are written inside except clause.
Example: Here we are trying to access the array element whose index is out of bound and
handle the corresponding exception.
a = [1, 2, 3]
try:
print ("Second element = %d" %(a[1]))
except:
print ("An error occurred")
Output
Second element = 2
An error occurred
In the above example, the statements that can cause the error are placed inside the try
statement (second print statement in our case). The second print statement tries to access
the fourth element of the list which is not there and this throws an exception. This
exception is then caught by the except statement.
Catching Specific Exception
A try statement can have more than one except clause, to specify handlers for different
exceptions. Please note that at most one handler will be executed. For example, we can add
IndexError in the above code. The general syntax for adding specific exceptions are –
try:
# statement(s)
except IndexError:
# statement(s)
except ValueError:
# statement(s)
Example: Catching specific exceptions in the Python
The code defines a function ‘fun(a)' that calculates b based on the input a. If a is less than 4,
it attempts a division by zero, causing a ‘ZeroDivisionError'. The code
calls fun(3) and fun(5) inside a try-except block. It handles the ZeroDivisionError for fun(3) and
prints “ZeroDivisionError Occurred and Handled.” The ‘NameError' block is not
executed since there are no ‘NameError' exceptions in the code.
def fun(a):
if a < 4:
b = a/(a-3)
print("Value of b = ", b)
try:
fun(3)
fun(5)
except ZeroDivisionError:
print("ZeroDivisionError Occurred and Handled")
except NameError:
print("NameError Occurred and Handled")
Output
ZeroDivisionError Occurred and Handled
If you comment on the line fun(3), the output will be
NameError Occurred and Handled
The output above is so because as soon as python tries to access the value of b, NameError
occurs.
Try with Else Clause
In Python, you can also use the else clause on the try-except block which must be present
after all the except clauses. The code enters the else block only if the try clause does not
raise an exception.
Try with else clause
The code defines a function AbyB(a, b) that calculates c as ((a+b) / (a-b)) and handles a
potential ZeroDivisionError. It prints the result if there’s no division by zero error.
Calling AbyB(2.0, 3.0) calculates and prints -5.0, while calling AbyB(3.0, 3.0) attempts to divide
by zero, resulting in a ZeroDivisionError, which is caught and “a/b results in 0” is printed.
def AbyB(a , b):
try:
c = ((a+b) / (a-b))
except ZeroDivisionError:
print ("a/b result in 0")
else:
print (c)
AbyB(2.0, 3.0)
AbyB(3.0, 3.0)
Output:
-5.0
a/b result in 0
Finally Keyword in Python
Python provides a keyword finally, which is always executed after the try and except
blocks. The final block always executes after the normal termination of the try block or
after the try block terminates due to some exception.
Syntax:
try:
# Some Code....
except:
# optional block
# Handling of exception (if required)
else:
# execute if no exception
finally:
# Some code .....(always executed)
Example:
The code attempts to perform integer division by zero, resulting in a ZeroDivisionError. It
catches the exception and prints “Can’t divide by zero.” Regardless of the exception,
the finally block is executed and prints “This is always executed.”
try:
k = 5//0
print(k)
except ZeroDivisionError:
print("Can't divide by zero")
finally:
print('This is always executed')
Output:
Can't divide by zero
This is always executed
Raising Exception
The raise statement allows the programmer to force a specific exception to occur. The sole
argument in raise indicates the exception to be raised. This must be either an exception
instance or an exception class (a class that derives from Exception).
This code intentionally raises a NameError with the message “Hi there” using
the raise statement within a try block. Then, it catches the NameError exception, prints “An
exception,” and re-raises the same exception using raise. This demonstrates how exceptions
can be raised and handled in Python, allowing for custom error messages and further
exception propagation.
try:
raise NameError("Hi there")
except NameError:
print ("An exception")
raise
The output of the above code will simply line printed as “An exception” but a Runtime
error will also occur in the last due to the raise statement in the last line. So, the output on
your command line will look like
Traceback (most recent call last):
File "/home/d6ec14ca595b97bff8d8034bbf212a9f.py", line 5, in <module>
raise NameError("Hi there") # Raise Error
NameError: Hi there
Advantages of Exception Handling:
Improved program reliability: By handling exceptions properly, you can prevent
your program from crashing or producing incorrect results due to unexpected
errors or input.
Simplified error handling: Exception handling allows you to separate error
handling code from the main program logic, making it easier to read and
maintain your code.
Cleaner code: With exception handling, you can avoid using complex
conditional statements to check for errors, leading to cleaner and more readable
code.
Easier debugging: When an exception is raised, the Python interpreter prints a
traceback that shows the exact location where the exception occurred, making it
easier to debug your code.
Disadvantages of Exception Handling:
Performance overhead: Exception handling can be slower than using
conditional statements to check for errors, as the interpreter has to perform
additional work to catch and handle the exception.
Increased code complexity: Exception handling can make your code more
complex, especially if you have to handle multiple types of exceptions or
implement complex error handling logic.
Possible security risks: Improperly handled exceptions can potentially reveal
sensitive information or create security vulnerabilities in your code, so it’s
important to handle exceptions carefully and avoid exposing too much
information about your program.
Overall, the benefits of exception handling in Python outweigh the drawbacks, but it’s
important to use it judiciously and carefully in order to maintain code quality and program
reliability.
# Constructor or Initializer
def __init__(self, value):
self.value = value
try:
raise(MyError(3*2))
Output
A New Exception occurred: 6
Customizing Exception Classes
To know more about class Exception, run the code below
help(Exception)
Output
Help on class Exception in module exceptions:
class Exception(BaseException)
| Common base class for all non-exit exceptions.
|
| Method resolution order:
| Exception
| BaseException
| __builtin__.object
|
| Methods defined here:
|
| __init__(...)
| x.__init__(...) initializes x; see help(type(x)) for signature
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __new__ = <built-in method __new__ of type object>
| T.__new__(S, ...) -> a new object with type S, a subtype of T
|
| ----------------------------------------------------------------------
| Methods inherited from BaseException:
|
| __delattr__(...)
| x.__delattr__('name') <==> del x.name
|
| __getattribute__(...)
| x.__getattribute__('name') <==> x.name
|
| __getitem__(...)
| x.__getitem__(y) <==> x[y]
|
| __getslice__(...)
| x.__getslice__(i, j) <==> x[i:j]
|
| Use of negative indices is not supported.
|
| __reduce__(...)
|
| __repr__(...)
| x.__repr__() <==> repr(x)
|
| __setattr__(...)
| x.__setattr__('name', value) <==> x.name = value
|
| __setstate__(...)
|
| __str__(...)
| x.__str__() <==> str(x)
|
| __unicode__(...)
|
| ----------------------------------------------------------------------
| Data descriptors inherited from BaseException:
|
| __dict__
|
| args
|
| message
Example 1: User-Defined class with Multiple Inheritance
In the below article, we have created a class named “Error” derived from the class
Exception. This base class is inherited by various user-defined classes to handle different
types of python raise an exception with message
# define Python user-defined exceptions
class Error(Exception):
"""Base class for other exceptions"""
pass
class zerodivision(Error):
"""Raised when the input value is zero"""
pass
try:
i_num = int(input("Enter a number: "))
if i_num == 0:
raise zerodivision
except zerodivision:
print("Input value is zero, try again!")
print()
Output
Enter a number: 0
Input value is zero, try again!
Example 2: Deriving Error from Super Class Exception
Superclass Exceptions are created when a module needs to handle several distinct errors.
One of the common ways of doing this is to create a base class for exceptions defined by
that module. Further, various subclasses are defined to create specific exception classes for
different error conditions.
# class Error is derived from super class Exception
class Error(Exception):
class TransitionError(Error):
try:
raise(TransitionError(2, 3*2, "Not Allowed"))
# Value of Exception is stored in error
except TransitionError as error:
print('Exception occurred: ', error.msg)
Output
Exception occurred: Not Allowed
How to use standard Exceptions as a base class?
A runtime error is a class that is a standard exception that is raised when a generated error
does not fall into any category. This program illustrates how to use runtime error as a base
class and network error as a derived class. In a similar way, an exception can be derived
from the standard exceptions of Python.
# NetworkError has base RuntimeError
# and not Exception
class Networkerror(RuntimeError):
def __init__(self, arg):
self.args = arg
try:
raise Networkerror("Error")
except Networkerror as e:
print(e.args)
Output
('E', 'r', 'r', 'o', 'r')
Output :
This statement is raising an arithmetic exception.
4. exception BufferError
This exception is raised when buffer related operations cannot be performed.
5. exception LookupError
This is the base class for those exceptions that are raised when a key or index
used on a mapping or sequence is invalid or not found. The exceptions raised are
:
KeyError
IndexError
Example :
try:
a = [1, 2, 3]
print (a[3])
except LookupError:
print ("Index out of bound error.")
else:
print ("Success")
Output :
Index out of bound error.
Concrete exceptions
The following exceptions are the exceptions that are usually raised.
1. exception AssertionError
An AssertionError is raised when an assert statement fails.
Example :
assert False, 'The assertion failed'
Output :
Traceback (most recent call last):
File "exceptions_AssertionError.py", line 12, in
assert False, 'The assertion failed'
AssertionError: The assertion failed
2. exception AttributeError
An AttributeError is raised when an attribute reference or assignment fails such
as when a non-existent attribute is referenced.
Example :
class Attributes(object):
pass
object = Attributes()
print (object.attribute)
Output :
Traceback (most recent call last):
File "d912bae549a2b42953bc62da114ae7a7.py", line 5, in
print object.attribute
AttributeError: 'Attributes' object has no attribute 'attribute'
3. exception EOFError
An EOFError is raised when built-in functions like input() hits an end-of-file
condition (EOF) without reading any data. The file methods like readline()
return an empty string when they hit EOF.
Example :
while True:
data = input('Enter name : ')
print ('Hello ', data)
Output :
Enter Name :Hello Aditi
Enter Name :Traceback (most recent call last):
File "exceptions_EOFError.py", line 13, in
data = raw_input('Enter name :')
EOFError: EOF when reading a line
4. exception FloatingPointError
A FloatingPointError is raised when a floating point operation fails. This
exception is always defined, but can only be raised when Python is configured
with the–with-fpectl option, or the WANT_SIGFPE_HANDLER symbol is
defined in the pyconfig.h file.
Example :
import math
print (math.exp(1000))
Output :
Traceback (most recent call last):
File "", line 1, in
FloatingPointError: in math_1
5. exception GeneratorExit
This exception directly inherits from BaseException instead of Exception since it
is technically not an error. A GeneratorExit exception is raised when a
generator or coroutine is closed.
Example :
def my_generator():
try:
for i in range(5):
print ('Yielding', i)
yield i
except GeneratorExit:
print ('Exiting early')
g = my_generator()
print (g.next())
g.close()
Output :
Yielding 0
0
Exiting early
6. exception ImportError
An ImportError is raised when the import statement is unable to load a module
or when the “from list” in from … import has a name that cannot be found.
Example :
import module_does_not_exist
Output :
Traceback (most recent call last):
File "exceptions_ImportError_nomodule.py", line 12, in
import module_does_not_exist
ImportError: No module named module_does_not_exist
Example :
from exceptions import Userexception
Output :
Traceback (most recent call last):
File "exceptions_ImportError_missingname.py", line 12, in
from exceptions import Userexception
ImportError: cannot import name Userexception
7. exception ModuleNotFoundError
This is the subclass of ImportError which is raised by import when a module
could not be found. It is also raised when None is found in sys.modules.
8. exception IndexError
An IndexError is raised when a sequence is referenced which is out of range.
Example :
array = [ 0, 1, 2 ]
print (array[3])
Output :
Traceback (most recent call last):
File "exceptions_IndexError.py", line 13, in
print array[3]
IndexError: list index out of range
9. exception KeyError
A KeyError is raised when a mapping key is not found in the set of existing keys.
Example :
array = { 'a':1, 'b':2 }
print (array['c'])
Output :
Traceback (most recent call last):
File "exceptions_KeyError.py", line 13, in
print array['c']
KeyError: 'c'
10.exception KeyboardInterrupt
This error is raised when the user hits the interrupt key such as Control-C or
Delete.
Example :
try:
print ('Press Return or Ctrl-C:',)
ignored = input()
except Exception, err:
print ('Caught exception:', err)
except KeyboardInterrupt, err:
print ('Caught KeyboardInterrupt')
else:
print ('No exception')
Output :
Press Return or Ctrl-C: ^CCaught KeyboardInterrupt
11.exception MemoryError
This error is raised when an operation runs out of memory.
Example :
def fact(a):
factors = []
for i in range(1, a+1):
if a%i == 0:
factors.append(i)
return factors
num = 600851475143
print (fact(num))
Output :
Traceback (most recent call last):
File "4af5c316c749aff128df20714536b8f3.py", line 9, in
print fact(num)
File "4af5c316c749aff128df20714536b8f3.py", line 3, in fact
for i in range(1, a+1):
MemoryError
12.exception NameError
This error is raised when a local or global name is not found. For example, an
unqualified variable name.
Example :
def func():
print ans
func()
Output :
Traceback (most recent call last):
File "cfba0a5196b05397e0a23b1b5b8c7e19.py", line 4, in
func()
File "cfba0a5196b05397e0a23b1b5b8c7e19.py", line 2, in func
print ans
NameError: global name 'ans' is not defined
13.exception NotImplementedError
This exception is derived from RuntimeError. Abstract methods in user defined
classed should raise this exception when the derived classes override the
method.
Example :
class BaseClass(object):
"""Defines the interface"""
def __init__(self):
super(BaseClass, self).__init__()
def do_something(self):
"""The interface, not implemented"""
raise NotImplementedError(self.__class__.__name__ + '.do_something')
class SubClass(BaseClass):
"""Implements the interface"""
def do_something(self):
"""really does something"""
print (self.__class__.__name__ + ' doing something!')
SubClass().do_something()
BaseClass().do_something()
Output :
Traceback (most recent call last):
File "b32fc445850cbc23cd2f081ba1c1d60b.py", line 16, in
BaseClass().do_something()
File "b32fc445850cbc23cd2f081ba1c1d60b.py", line 7, in do_something
raise NotImplementedError(self.__class__.__name__ + '.do_something')
NotImplementedError: BaseClass.do_something
14.exception OSError([arg])
The OSError exception is raised when a system function returns a system-related
error, including I/O failures such as “file not found” or “disk full” errors.
Example :
def func():
print (ans)
func()
Output :
Traceback (most recent call last):
File "442eccd7535a2704adbe372cb731fc0f.py", line 4, in
print i, os.ttyname(i)
OSError: [Errno 25] Inappropriate ioctl for device
15.exception OverflowError
The OverflowError is raised when the result of an arithmetic operation is out of
range. Integers raise MemoryError instead of OverflowError. OverflowError is
sometimes raised for integers that are outside a required range. Floating point
operations are not checked because of the lack of standardization of floating
point exception handling in C.
Example :
import sys
print()
print ('Long integer:')
for i in range(0, 100, 10):
print ('%2d' % i, 2L ** i)
print()
print ('Floating point values:')
try:
f = 2.0**i
for i in range(100):
print (i, f)
f = f ** 2
except OverflowError, err:
print ('Overflowed after ', f, err)
Output :
Regular integer: (maxint=9223372036854775807)
No overflow for i = 27670116110564327421
Long integer:
01
10 1024
20 1048576
30 1073741824
40 1099511627776
50 1125899906842624
60 1152921504606846976
70 1180591620717411303424
80 1208925819614629174706176
90 1237940039285380274899124224
16.exception RecursionError
The RecursionError is derived from the RuntimeError. This exception is raised
when the interpreter detects that the maximum recursion depth is exceeded.
17.exception ReferenceError
The ReferenceError is raised when a weak reference proxy is used to access an
attribute of the referent after the garbage collection.
Example :
import gc
import weakref
class Foo(object):
def __del__(self):
print ('(Deleting %s)' % self)
obj = Foo('obj')
p = weakref.proxy(obj)
Output :
BEFORE: obj
(Deleting )
AFTER:
print (i)
print (i.next())
print (i.next())
print (i.next())
print (i.next())
Output :
3
1
2
Output :
Syntax error (1-9): geeks for geeks
invalid syntax (, line 1)
21.exception SystemError
The SystemError is raised when the interpreter finds an internal error. The
associated value is a string indicating what went wrong.
22.exception SystemExit
The SystemExit is raised when sys.exit() function is called. A call to sys.exit() is
translated into an exception to execute clean-up handlers (finally clauses of try
statements) and to debug a script without running the risk of losing control.
23.exception TypeError
TypeError is raised when an operation or function is applied to an object of
inappropriate type. This exception returns a string giving details about the type
mismatch.
Example :
arr = ('tuple', ) + 'string'
print (arr)
Output :
Traceback (most recent call last):
File "30238c120c0868eba7e13a06c0b1b1e4.py", line 1, in
arr = ('tuple', ) + 'string'
TypeError: can only concatenate tuple (not "str") to tuple
24.exception UnboundLocalError
UnboundLocalError is a subclass of NameError which is raised when a
reference is made to a local variable in a function or method, but no value has
been assigned to that variable.
Example :
def global_name_error():
print (unknown_global_name)
def unbound_local():
local_val = local_val + 1
print (local_val)
try:
global_name_error()
except NameError, err:
print ('Global name error:', err)
try:
unbound_local()
except UnboundLocalError, err:
print ('Local name error:', err)
Output :
Global name error: global name 'unknown_global_name' is not defined
Local name error: local variable 'local_val' referenced before assignment
25.exception UnicodeError
This exception is a subclass of ValueError. UnicodeError is raised when a
Unicode-related encoding or decoding error occurs.
26.exception ValueError
A ValueError is raised when a built-in operation or function receives an
argument that has the right type but an invalid value.
Example :
print (int('a'))
Output :
Traceback (most recent call last):
File "44f00efda935715a3c5468d899080381.py", line 1, in
print int('a')
ValueError: invalid literal for int() with base 10: 'a'
27.exception ZeroDivisionError
A ZeroDivisionError is raised when the second argument of a division or
modulo operation is zero. This exception returns a string indicating the type of
the operands and the operation.
Example :
print (1/0)
Output :
Traceback (most recent call last):
File "c31d9626b41e53d170a78eac7d98cb85.py", line 1, in
print 1/0
ZeroDivisionError: integer division or modulo by zero
Python Try Except
Error in Python can be of two types i.e. Syntax errors and Exceptions. Errors are the
problems in a program due to which the program will stop the execution. On the other
hand, exceptions are raised when some internal events occur which changes the normal
flow of the program. Note: For more information, refer to Errors and Exceptions in Python
Some of the common Exception Errors are :
IOError: if the file can’t be opened
KeyboardInterrupt: when an unrequired key is pressed by the user
ValueError: when the built-in function receives a wrong argument
EOFError: if End-Of-File is hit without reading any data
ImportError: if it is unable to find the module
Syntax:
try:
# Some Code
except:
# Executed if error in the
# try block
How try() works?
First, the try clause is executed i.e. the code between try.
If there is no exception, then only the try clause will run, except clause is
finished.
If any exception occurs, the try clause will be skipped and except clause will
run.
If any exception occurs, but the except clause within the code doesn’t handle it,
it is passed on to the outer try statements. If the exception is left unhandled, then
the execution stops.
A try statement can have more than one except clause
Code 1: No exception, so the try clause will run.
Python3
# Python code to illustrate
# working of try()
def divide(x, y):
try:
# Floor Division : Gives only Fractional Part as Answer
result = x // y
print("Yeah ! Your answer is :", result)
except ZeroDivisionError:
print("Sorry ! You are dividing by zero ")
Output :
Sorry ! You are dividing by zero
Code 2: The other way of writing except statement, is shown below and in this way, it
only accepts exceptions that you’re meant to catch or you can check which error is
occurring.
Python3
# code
def divide(x, y):
try:
# Floor Division : Gives only Fractional Part as Answer
result = x // y
print("Yeah ! Your answer is :", result)
except Exception as e:
# By this way we can know about the type of error occurring
print("The error is: ",e)
divide(3, "GFG")
divide(3,0)
Output:
The error is: unsupported operand type(s) for //: 'int' and 'str'
The error is: integer division or modulo by zero
Else Clause
In Python, you can also use the else clause on the try-except block which must be present
after all the except clauses. The code enters the else block only if the try clause does not
raise an exception.
Syntax:
try:
# Some Code
except:
# Executed if error in the
# try block
else:
# execute if no exception
Code:
Python3
# Program to depict else clause with try-except
Output:
-5.0
a/b result in 0
finally:
# this block is always executed
# regardless of exception generation.
print('This is always executed')
Output:
Can't divide by zero
This is always executed
Regular Expression (RegEx) in Python with Examples
A Regular Expression or RegEx is a special sequence of characters that uses a search
pattern to find a string or set of strings.
It can detect the presence or absence of a text by matching it with a particular pattern and
also can split a pattern into one or more sub-patterns.
Regex Module in Python
Python has a built-in module named “re” that is used for regular expressions in Python.
We can import this module by using the import statement.
Example: Importing re module in Python
Python3
# importing re module
import re
match = re.search(r'portal', s)
Output
Start Index: 34
End Index: 40
Note: Here r character (r’portal’) stands for raw, not regex. The raw string is slightly
different from a regular string, it won’t interpret the \ character as an escape character. This
is because the regular expression engine uses \ character for its own escaping purpose.
Before starting with the Python regex module let’s see how to actually write regex using
metacharacters or special sequences.
Metacharacters
Metacharacters are the characters with special meaning.
To understand the RE analogy, Metacharacters are useful and important. They will be used
in functions of module re. Below is the list of metacharacters.
MetaCharacters Description
1. \ – Backslash
The backslash (\) makes sure that the character is not treated in a special way. This can be
considered a way of escaping metacharacters.
For example, if you want to search for the dot(.) in the string then you will find that dot(.)
will be treated as a special character as is one of the metacharacters (as shown in the above
table). So for this case, we will use the backslash(\) just before the dot(.) so that it will lose
its specialty. See the below example for a better understanding.
Example:
The first search (re.search(r'.', s)) matches any character, not just the period, while the
second search (re.search(r'\.', s)) specifically looks for and matches the period character.
Python3
import re
s = 'geeks.forgeeks'
# without using \
match = re.search(r'.', s)
print(match)
# using \
match = re.search(r'\.', s)
print(match)
Output
<re.Match object; span=(0, 1), match='g'>
<re.Match object; span=(5, 6), match='.'>
2. [] – Square Brackets
Square Brackets ([]) represent a character class consisting of a set of characters that we
wish to match. For example, the character class [abc] will match any single a, b, or c.
We can also specify a range of characters using – inside the square brackets. For example,
[0, 3] is sample as [0123]
[a-c] is same as [abc]
We can also invert the character class using the caret(^) symbol. For example,
[^0-3] means any number except 0, 1, 2, or 3
[^a-c] means any character except a, b, or c
Example:
In this code, you’re using regular expressions to find all the characters in the string that fall
within the range of ‘a’ to ‘m’. The re.findall() function returns a list of all such characters. In
the given string, the characters that match this pattern are: ‘c’, ‘k’, ‘b’, ‘f’, ‘j’, ‘e’, ‘h’, ‘l’,
‘d’, ‘g’.
Python3
import re
string = "The quick brown fox jumps over the lazy dog"
pattern = "[a-m]"
result = re.findall(pattern, string)
print(result)
Output
['h', 'e', 'i', 'c', 'k', 'b', 'f', 'j', 'm', 'e', 'h', 'e', 'l', 'a', 'd', 'g']
3. ^ – Caret
Caret (^) symbol matches the beginning of the string i.e. checks whether the string starts
with the given character(s) or not. For example –
^g will check if the string starts with g such as geeks, globe, girl, g, etc.
^ge will check if the string starts with ge such as geeks, geeksforgeeks, etc.
Example:
This code uses regular expressions to check if a list of strings starts with “The”. If a string
begins with “The,” it’s marked as “Matched” otherwise, it’s labeled as “Not matched”.
Python3
import re
regex = r'^The'
strings = ['The quick brown fox', 'The lazy dog', 'A quick brown fox']
for string in strings:
if re.match(regex, string):
print(f'Matched: {string}')
else:
print(f'Not matched: {string}')
Output
Matched: The quick brown fox
Matched: The lazy dog
Not matched: A quick brown fox
4. $ – Dollar
Dollar($) symbol matches the end of the string i.e checks whether the string ends with the
given character(s) or not. For example-
s$ will check for the string that ends with a such as geeks, ends, s, etc.
ks$ will check for the string that ends with ks such as geeks, geeksforgeeks, ks,
etc.
Example:
This code uses a regular expression to check if the string ends with “World!”. If a match is
found, it prints “Match found!” otherwise, it prints “Match not found”.
Python3
import re
Output
Match found!
5. . – Dot
Dot(.) symbol matches only a single character except for the newline character (\n). For
example –
a.b will check for the string that contains any character at the place of the dot
such as acb, acbd, abbb, etc
.. will check if the string contains at least 2 characters
Example:
This code uses a regular expression to search for the pattern “brown.fox” within the string.
The dot (.) in the pattern represents any character. If a match is found, it prints “Match
found!” otherwise, it prints “Match not found”.
Python3
import re
string = "The quick brown fox jumps over the lazy dog."
pattern = r"brown.fox"
Output
Match found!
6. | – Or
Or symbol works as the or operator meaning it checks whether the pattern before or after
the or symbol is present in the string or not. For example –
a|b will match any string that contains a or b such as acd, bcd, abcd, etc.
7. ? – Question Mark
The question mark (?) is a quantifier in regular expressions that indicates that the preceding
element should be matched zero or one time. It allows you to specify that the element is
optional, meaning it may occur once or not at all. For example,
ab?c will be matched for the string ac, acb, dabc but will not be matched for
abbc because there are two b. Similarly, it will not be matched for abdc because
b is not followed by c.
8.* – Star
Star (*) symbol matches zero or more occurrences of the regex preceding the * symbol. For
example –
ab*c will be matched for the string ac, abc, abbbc, dabc, etc. but will not be
matched for abdc because b is not followed by c.
9. + – Plus
Plus (+) symbol matches one or more occurrences of the regex preceding the + symbol. For
example –
ab+c will be matched for the string abc, abbc, dabc, but will not be matched for
ac, abdc, because there is no b in ac and b, is not followed by c in abdc.
Let’s see the working of these RegEx functions with definition and examples:
1. re.findall()
Return all non-overlapping matches of pattern in string, as a list of strings. The string is
scanned left-to-right, and matches are returned in the order found.
Finding all occurrences of a pattern
This code uses a regular expression (\d+) to find all the sequences of one or more digits in
the given string. It searches for numeric values and stores them in a list. In this example, it
finds and prints the numbers “123456789” and “987654321” from the input string.
Python3
import re
string = """Hello my Number is 123456789 and
my friend's number is 987654321"""
regex = '\d+'
Output
['123456789', '987654321']
2. re.compile()
Regular expressions are compiled into pattern objects, which have methods for various
operations such as searching for pattern matches or performing string substitutions.
Example 1:
The code uses a regular expression pattern [a-e] to find and list all lowercase letters from ‘a’
to ‘e’ in the input string “Aye, said Mr. Gibenson Stark”. The output will be ['e', 'a', 'd',
'b', 'e'], which are the matching characters.
Python
import re
p = re.compile('[a-e]')
Output
['e', 'a', 'd', 'b', 'e', 'a']
p = re.compile('\d+')
print(p.findall("I went to him at 11 A.M. on 4th July 1886"))
Output
['1', '1', '4', '1', '8', '8', '6']
['11', '4', '1886']
Example 3:
The code uses regular expressions to find and list word characters, sequences of word
characters, and non-word characters in input strings. It provides lists of the matched
characters or sequences.
Python
import re
p = re.compile('\w')
print(p.findall("He said * in some_lang."))
p = re.compile('\w+')
print(p.findall("I went to him at 11 A.M., he \
said *** in some_language."))
p = re.compile('\W')
print(p.findall("he said *** in some_language."))
Output
['H', 'e', 's', 'a', 'i', 'd', 'i', 'n', 's', 'o', 'm', 'e', '_', 'l', 'a', 'n', 'g']
['I', 'went', 'to', 'him', 'at', '11', 'A', 'M', 'he', 'said', 'in', 'some_language']
[' ', ' ', '*', '*', '*', ' ...
Example 4:
The code uses a regular expression pattern ‘ab*’ to find and list all occurrences of ‘ab’
followed by zero or more ‘b’ characters in the input string “ababbaabbb”. It returns the
following list of matches: [‘ab’, ‘abb’, ‘abbb’].
Python
import re
p = re.compile('ab*')
print(p.findall("ababbaabbb"))
Output
['ab', 'abb', 'a', 'abbb']
The First parameter, pattern denotes the regular expression, string is the given string in
which pattern will be searched for and in which splitting occurs, maxsplit if not provided is
considered to be zero ‘0’, and if any nonzero value is provided, then at most that many
splits occur. If maxsplit = 1, then the string will split once only, resulting in a list of length
2. The flags are very useful and can help to shorten code, they are not necessary
parameters, eg: flags = re.IGNORECASE, in this split, the case, i.e. the lowercase or the
uppercase will be ignored.
Example 1:
Splits a string using non-word characters and spaces as delimiters, returning
words: ['Words', 'words', 'Words']. Considers apostrophes as non-word characters: ['Word', 's',
'words', 'Words']. Splits using non-word characters and digits: ['On', '12th', 'Jan', '2016', 'at', '11',
'02', 'AM']. Splits using digits as the delimiter: ['On ', 'th Jan ', ', at ', ':', ' AM'].
Python
from re import split
Output
['Words', 'words', 'Words']
['Word', 's', 'words', 'Words']
['On', '12th', 'Jan', '2016', 'at', '11', '02', 'AM']
['On ', 'th Jan ', ', at ', ':', ' AM']
Example 2:
First statement splits the string at the first occurrence of one or more digits: ['On ', 'th Jan
2016, at 11:02 AM']. second splits the string using lowercase letters a to f as delimiters, case-
insensitive: ['', 'y, ', 'oy oh ', 'oy, ', 'ome here']. Third splits the string using lowercase letters a
to f as delimiters, case-sensitive: ['', 'ey, Boy oh ', 'oy, ', 'ome here'].
Python
import re
print(re.split('\d+', 'On 12th Jan 2016, at 11:02 AM', 1))
print(re.split('[a-f]+', 'Aey, Boy oh boy, come here', flags=re.IGNORECASE))
print(re.split('[a-f]+', 'Aey, Boy oh boy, come here'))
Output
['On ', 'th Jan 2016, at 11:02 AM']
['', 'y, ', 'oy oh ', 'oy, ', 'om', ' h', 'r', '']
['A', 'y, Boy oh ', 'oy, ', 'om', ' h', 'r', '']
4. re.sub()
The ‘sub’ in the function stands for SubString, a certain regular expression pattern is
searched in the given string(3rd parameter), and upon finding the substring pattern is
replaced by repl(2nd parameter), count checks and maintains the number of times this
occurs.
Syntax:
re.sub(pattern, repl, string, count=0, flags=0)
Example 1:
First statement replaces all occurrences of ‘ub’ with ‘~*’ (case-
insensitive): 'S~*ject has ~*er booked already'.
Second statement replaces all occurrences of ‘ub’ with ‘~*’ (case-
sensitive): 'S~*ject has Uber booked already'.
Third statement replaces the first occurrence of ‘ub’ with ‘~*’ (case-
insensitive): 'S~*ject has Uber booked already'.
Fourth replaces ‘AND’ with ‘ & ‘ (case-insensitive): 'Baked Beans & Spam'.
Python
import re
print(re.sub('ub', '~*', 'Subject has Uber booked already',
flags=re.IGNORECASE))
print(re.sub('ub', '~*', 'Subject has Uber booked already'))
print(re.sub('ub', '~*', 'Subject has Uber booked already',
count=1, flags=re.IGNORECASE))
print(re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam',
flags=re.IGNORECASE))
Output
S~*ject has ~*er booked already
S~*ject has Uber booked already
S~*ject has Uber booked already
Baked Beans & Spam
5. re.subn()
subn() is similar to sub() in all ways, except in its way of providing output. It returns a
tuple with a count of the total of replacement and the new string rather than just the string.
Syntax:
re.subn(pattern, repl, string, count=0, flags=0)
Example:
re.subn() replaces all occurrences of a pattern in a string and returns a tuple with the
modified string and the count of substitutions made. It’s useful for both case-sensitive and
case-insensitive substitutions.
Python
import re
Output
('S~*ject has Uber booked already', 1)
('S~*ject has ~*er booked already', 2)
2
S~*ject has ~*er booked already
6. re.escape()
Returns string with all non-alphanumerics backslashed, this is useful if you want to match
an arbitrary literal string that may have regular expression metacharacters in it.
Syntax:
re.escape(string)
Example:
re.escape() is used to escape special characters in a string, making it safe to be used as a
pattern in regular expressions. It ensures that any characters with special meanings in
regular expressions are treated as literal characters.
Python
import re
print(re.escape("This is Awesome even 1 AM"))
print(re.escape("I Asked what is this [a-9], he said \t ^WoW"))
Output
This\ is\ Awesome\ even\ 1\ AM
I\ Asked\ what\ is\ this\ \[a\-9\]\,\ he\ said\ \ \ \^WoW
7. re.search()
This method either returns None (if the pattern doesn’t match), or a re.MatchObject
contains information about the matching part of the string. This method stops after the first
match, so this is best suited for testing a regular expression more than extracting data.
Example: Searching for an occurrence of the pattern
This code uses a regular expression to search for a pattern in the given string. If a match is
found, it extracts and prints the matched portions of the string.
In this specific example, it searches for a pattern that consists of a month (letters) followed
by a day (digits) in the input string “I was born on June 24”. If a match is found, it prints
the full match, the month, and the day.
Python3
import re
regex = r"([a-zA-Z]+) (\d+)"
else:
print ("The regex pattern does not match.")
Output
Match at index 14, 21
Full match: June 24
Month: June
Day: 24
SETS
A Set is a set of characters enclosed in ‘[]’ brackets. Sets are used to match a single
character in the set of characters specified between brackets. Below is the list of Sets:
Set Description
Match Object
A Match object contains all the information about the search and the result and if there is
no match found then None will be returned. Let’s see some of the commonly used methods
and attributes of the match object.
print(res.re)
print(res.string)
Output
re.compile('\\bG')
Welcome to GeeksForGeeks
s = "Welcome to GeeksForGeeks"
res = re.search(r"\bGee", s)
print(res.start())
print(res.end())
print(res.span())
Output
11
14
(11, 14)
3. Getting matched substring
group() method returns the part of the string for which the patterns match. See the below
example for a better understanding.
Example: Getting matched substring
The code searches for a sequence of two non-digit characters followed by a space and the
letter ‘t’ in the string “Welcome to GeeksForGeeks” and prints the matched text
using res.group().
Python3
import re
s = "Welcome to GeeksForGeeks"
res = re.search(r"\D{2} t", s)
print(res.group())
Output
me t
In the above example, our pattern specifies for the string that contains at least 2 characters
which are followed by a space, and that space is followed by a t.