UNIT II
EXCEPTIONS
Exception handling is one of the most important feature of Python programming
language that allows us to handle the errors caused by exceptions. Even if a
statement or expression is syntactically correct, it may cause an error when an
attempt is made to execute it. Errors detected during execution are called
exceptions. An exception is an unwanted event that interrupts the normal flow of
the program. When an exception occurs in the program, execution gets
terminated. In such cases, we get a system-generated error message. However,
these exceptions can be handled in Python. By handling the exceptions, we can
provide a meaningful message to the user about the issue rather than a system-
generated message, which may not be understandable to the user.
Python Built-in Exceptions Python has a set of built-in exceptions that are
raised when certain errors occur during the execution of a program. These
exceptions are defined in the builtin “exceptions” module and are derived
from the base class “BaseException”. Here is a list of some common built-in
exceptions in Python:
Exception Handling
When a python program terminates as soon as it encounters an error. In Python, an error
can be a syntax error or an exception. Hence, the exceptions should be properly handled so
that an abrupt termination of the program is prevented.
Exception handling in Python is a mechanism for handling errors and exceptional
conditions in your code. It allows you to write code that can gracefully handle unexpected
conditions, such as a missing file or a network connection error, without causing the entire
program to crash. In Python, exceptions are raised when something unexpected or
exceptional occurs in the program, such as a divide-by-zero error or an attempt to access a
nonexistent element in a list. When an exception is raised, the normal flow of control in
the program is interrupted, and the program looks for a piece of code that can handle the
exception.
Process of Exception Handling involves following important
terms:
• try : try block used to keep the block of code that may raise
• except : to handle the exception after catching it.
• else : it runs when no exception exist
• finally : finally block will always execute no matter what
To handle exceptions in Python, you use the try and except
statements. The
try block contains the code that may raise an exception, and the
except block
contains the code that will be executed if an exception is raised.
try:
x=1/0
except ZeroDivisionError:
print(“Cannot divide by zero.”)
finally:
print(“This block will always be executed.”)
Program to Check for ValueError Exception
while True:
try:
number = int(input("Please enter a number: "))
print(f "The number you have entered is {number}")
break
except ValueError:
print("Oops! That was no valid number. Try again…")
Output
Please enter a number: g
Oops! That was no valid number. Try again…
Please enter a number: 4
The number you have entered is 4
Program to Check for ZeroDivisionError Exception
x = int(input("Enter value for x: "))
y = int(input("Enter value for y: ")
try: Output
result = x / y Case 1
Enter value for x: 8
except ZeroDivisionError:
Enter value for y: 0
print("Division by zero!") Division by zero!
else: Executing finally clause
print(f"Result is {result}")
finally:
print("Executing finally clause")
Python Functions
Python functions are a fundamental concept in programming that allow you to
encapsulate and reuse code. Functions in Python are blocks of code that
perform a specific task and can be called multiple times throughout a program.
They can take input parameters, return values, and modify global variables.
Functions are defined using the “def” keyword, followed by a function name
and any necessary parameters, and then the function body. To use a function,
you simply call it by its name, passing any necessary arguments.
Python functions can greatly simplify complex programs by breaking them
down into smaller, reusable pieces of code.
For example, you can define a function called “greet” that takes in a
parameter called “name” and prints out a greeting message: “Hello,
name!”. Functions can also return a value using the “return” statement, for
example, a function called “add” that takes in two parameters “a” and “b”
and returns their sum.
Functions are called by their name, followed by the parentheses and any
necessary input arguments. Functions are useful for organizing and
modularizing your code, making it easier to read, understand, and
maintain. They also allow you to reuse the same code multiple times,
without having to write it over and over again.
Advantages of Python
There are several advantages to using Python as a programming language:
1. Easy to Learn and Read: Python has a simple, easy-to-learn syntax which
makes it a great language for beginners. It also uses indentation to indicate
code blocks, making it more readable than other languages.
2. Large and Active Community: Python has a large and active community,
which means that there are many resources available for learning and
troubleshooting. Additionally, the community continually
develops and maintains a wide range of libraries and frameworks, which makes
development faster and more efficient.
3. Versatile and Cross-Platform: Python can be used for a wide range of tasks,
including web development, scientific computing, data analysis, artificial
intelligence, and more. It also runs on a variety of platforms, including
Windows, Mac, and Linux.
4. Plenty of Libraries and Frameworks: Python has a wealth of
libraries and frameworks available, including NumPy and SciPy
for scientific computing, Pygame for game development, and
Django and Flask for web development.
5. Good for Prototyping: Python’s easy-to-read syntax and short
development cycle make it a great choice for prototyping and
experimenting with new ideas.
6. High-Demand: Python is one of the most popular programming
languages, in demand by many industries, such as data science,
machine learning, artificial intelligence, and web development.
Types of Functions
A function in Python is a block of reusable code that performs a specific
task. Functions can accept input (referred to as arguments or parameters)
and return output. Functions are defined using the def keyword, and are
called using their name followed by parentheses, with any input passed
within the
parentheses.
There are two types of functions in Python:
1. Python User-defined Functions
2. Python Built-in Functions
3. Lambda Function
4. Recursive Function
1. Built-in functions: These are the functions that are already available in
Python and can be used without importing any modules. Examples include
print(), len(), and str().
2. User-defined functions: These are the functions that are defined by the user
and can be reused throughout the program. These can take inputs and can return
values.
3. Anonymous or lambda functions: These are the functions that are small
and single-expression functions that are defined without a name, using the
“lambda” keyword. These functions are useful for simple operations that can be
defined in a single line of code.
4. Recursive Function: A function that calls itself is said to be recursive. In
Python, recursion is a technique where a function calls itself in order to solve a
problem.
Built-in Functions Built-in functions are functions that are already available in Python and can be used
without importing any modules. These functions are part of the Python standard library and are always
available for use in your code. They can be used to perform a wide variety of tasks, such as converting data
types, manipulating strings, and working with mathematical operations.Here’s a table of some common
built-in functions in Python:
Python User Defined Functions User-defined functions are functions that are created and defined by
the user, as opposed to being built-in to the programming language or software system. These
functions can be used to perform specific tasks or operations, and can be reused throughout a
program or project.
Here’s a table of some characteristics of user-defined functions in Python:
Function Definition
Function definition refers to the process of creating and specifying a
function’s code, its name, input parameters, and return value. In most
programming languages, this is done using a specific syntax, such as
the def keyword in Python. A user-defined function in Python is
defined using the def keyword, followed by the function name, a set of
parentheses (which may include input parameters), and a colon. The
code that makes up the function’s operations is then indented and
placed beneath the definition.
Function Call
A function call is the process of invoking or executing a function. In
other words, it’s the process of telling the program to run the code
inside a function. When a function is defined, it’s created but not
executed. It’s only when the function is called that its code is
executed. In order to call a function, you need to use the function’s
name followed by a set of parentheses, and inside these parentheses,
you can pass any required parameters.
To call a function we simply type the function name with/without
parameters as per functions definition.
A program to add two numbers
def add_numbers(a, b):
return a + b
result = add_numbers(3, 4)
print(result)
# Output: 7
In this example, the function is named add_numbers and takes two input
parameters a and b. The function’s code is a single line that calculates the sum of a
and b using the + operator and returns the result using the return keyword. When
the function is called with the arguments 3 and 4, the return value is 7. It’s
important to note that the same function can be called multiple times with different
parameters, and it will execute its code each time, returning a different result based
on the input values.
The return Statement and void Function
Most of the times you may want the function to perform its specified task to calculate a value
and return the value to the calling function so that it can be stored in a variable and used
later. This can be achieved using the optional return statement in the function definition.
The syntax for return statement is,
return [expression_list] Keyword
If an expression list is present, it is evaluated, else None is substituted. The return statement
leaves the current function definition with the expression_list (or None) as a return value.
The return statement terminates the execution of the function definition in which it appears
and returns control to the calling function. It can also return an optional value to its calling
function.
In Python, it is possible to define functions without a return statement. Functions like
this are called void functions, and they return None
Types of Function Arguments(Parameters)
Function arguments, also known as parameters, are values that are passed
to a function when it is called. These values are then used by the function to
perform its designated task. In programming, there are several types of function
arguments that can be used, each with their own specific characteristics and use
cases.
There are several types of function arguments (also known as parameters) in
programming:
1. Function with No Arguments:A function with no arguments is a
function that does not require any input values to be passed to it when it is called.
2. Function with Required Arguments: A function with required arguments is a
function that requires specific input values to be passed to it when it is called. If
these required arguments are not provided, the function will not be able to run or
will raise an error.
3.Function with Arbitrary Length Arguments: A function with arbitrary length
arguments is a function that can accept a variable number of input values. These values
can be passed to the function using the *args or **kwargs notation.
4. Function with Keyword Based Arguments: A function with keywordbased
arguments is a function that accepts input values that are passed to it by explicitly
specifying the argument name and its value. This allows for more flexibility and
readability in function calls.
5. Function with Default Arguments: A function with default arguments is a function
that assigns default values to certain input parameters. If a value for these parameters is
not provided when the function is called, the default value will be used.
6. Python Anonymous Functions: Anonymous functions are functions that are defined
without a name. They are also known as lambda functions and can be used in situations
where a function is required but a named function is not necessary. Anonymous
functions can be defined using the lambda keyword in Python.
Function with No Arguments
A function with no arguments is a function that does not require any input
values to be passed to it when it is called. Such functions can still perform
useful operations, such as printing text, performing calculations, or returning
a value. In Python, a function with no arguments can be defined using the def
keyword, followed by the function name, a set of parentheses, and a colon.
In this example, the greet() function is defined using the def
keyword, followed by the function name and a set of parentheses.
There are no arguments defined within the parentheses, indicating
that the function does not require any input values. The function
simply prints a greeting message to the console when it is called.
When the function is called by using the function name followed by
parentheses, greet(), the function runs and prints “Hello, World!” as
a output. This example shows that a function with no arguments
can still perform useful operations, such as printing a message or
performing calculations.
Function with Required Arguments
A function with required arguments is a function that requires specific input
values to be passed to it when it is called. These input values are defined as
parameters within the function definition and are used by the function to
perform its designated task. If these required arguments are not provided, the
function will not be able to run or will raise an error. In Python, a function with
required arguments can be defined using the def keyword, followed by the
function name, a set of parentheses containing the required argument names,
and a colon.
In this example, the greet() function is defined using the def
keyword, followed by the function name and a set of parentheses
containing one required argument named name. This argument is
used to customize the greeting message that is printed to the console.
When the function is called by using the function name followed by
parentheses containing the required argument, greet(“John”), the
function runs and replaces the name placeholder in the greeting
message with the provided value “John” , then it prints “Hello,
John!” as a output.
Function with Arbitrary Length Arguments
A function with arbitrary length arguments is a function that can accept a
variable number of input values. These values can be passed to the function
using the *args or **kwargs notation. In Python, *args allows a function to
accept any number of positional arguments, while **kwargs allows a function
to accept any number of keyword arguments.
In this example, the add_numbers() function is defined using the def
keyword, followed by the function name and a set of parentheses
containing *numbers. The * before the argument name numbers
indicates that the function can accept any number of positional
arguments. The function then iterates over the numbers passed as
arguments, adding them together and storing the result in a variable.
Finally, the function returns the result. When the function is called
by using the function name followed by parentheses containing the
arbitrary length arguments, add_numbers(1,2,3,4,5), the function
runs and adds all the numbers passed as arguments, then it prints 15
as a output.
It’s also possible to use **kwargs to accept any number of
keyword arguments, in this case the function would look like this:
In this example, the function is defined to accept any number of
keyword arguments using **kwargs. The function then accesses the
value of the “name” keyword argument and uses it to create a
personalized greeting message.
Function with Keyword Based Arguments
A function with keyword-based arguments is a function that accepts input
values that are passed to it by explicitly specifying the argument name and
its value. This allows for more flexibility and readability in function calls,
as it allows the developer to specify the arguments in any order, as well as
to specify only the arguments that are relevant for the current call. In
Python, keyword arguments are defined by including the argument name
followed by an equal sign(=) and its value in the function call.
In this example, the greet() function is defined using the def keyword,
followed by the function name and a set of parentheses containing two
arguments name and age. When the function is called by using the
function name followed by parentheses containing the keyword-based
arguments, greet(age=25, name=”John”), the function runs and replaces
the name and age placeholders in the greeting message with the provided
values “John” and 25, respectively, then it prints “Hello, John. You are 25
years old.” as a output.
It’s also possible to specify some of the arguments as keyword arguments
and others as positional arguments, for example:
greet(“John”, age=25)
This will also run the same way and prints the same output as before.
Function with Default Arguments
A function with default arguments is a function that assigns default
values to certain input parameters. If a value for these parameters is
not provided when the function is called, the default value will be
used. In Python, default arguments are defined by including the
argument name followed by an equal sign(=) and its default value
in the function definition. Here is an example of a function with
default arguments in Python:
In this example, the greet() function is defined using the def
keyword, followed by the function name and a set of
parentheses containing two arguments name and age. The
age argument has a default value of 25. When the function
is called by using the function name followed by
parentheses containing the only required argument,
greet(“John”), the function runs and uses the default value
of 25 for the age argument, then it prints “Hello, John. You
are 25 years old.” as a output.
Scope and Lifetime of Variables
Python programs have two scopes: global and local. A variable is a global
variable if its value is accessible and modifiable throughout your program.
Global variables have a global scope. A variable that is defined inside a
function definition is a local variable. The lifetime of a variable refers to the
duration of its existence.
The local variable is created and destroyed every time the function is
executed, and it cannot be accessed by any code outside the function
definition. Local variables inside a function definition have local scope and
exist as long as the function is executing.
It is possible to access global variables from inside a function, as long as you
have not defined a local variable with the same name. A local variable can
have the same name as a global variable, but they are totally different so
changing the value of the local variable has no effect on the global variable.
Only the local variable has meaning inside the function in which it is defined.
Python Anonymous Functions
In Python, anonymous functions are functions that are defined without a
name. They are also known as lambda functions and can be used in
situations where a function is required but a named function is not
necessary. Anonymous functions can be defined using the lambda
keyword in Python.
Syntax:
lambda arguments: expression
The lambda keyword is used to define an anonymous functions in
Python. Usually, such a function is meant for one-time use. This function
can have any number of arguments but only one expression, which is
evaluated and returned. One is free to use lambda functions wherever
function objects are required.
x = lambda a : a + 10
print(x(5))
In this example, the anonymous function is defined using the
lambda keyword, followed by the argument(s) and the function’s
expression. The function takes one argument a and returns the
value of a plus 10. When the function is called by providing the
argument 5 as input, x(5), the function runs and returns the value
5+10=15 as output.
Recursion
In computer science, recursion is a method of solving a problem by
breaking it down into smaller, identical problems. A function that
calls itself is said to be recursive. In Python, recursion is a
technique where a function calls itself in order to solve a problem.
Recursion is a powerful problem-solving technique that can be
used to solve many types of problems, such as mathematical
problems, tree traversals, and more. The key to using recursion
effectively is to find the base case, which is the simplest version of
the problem that can be solved directly, and the recursive case,
which is the problem broken down into smaller identical parts.
This function calculates the factorial of a number. The base case is when n is 0, and
the function returns 1. In the recursive case, the function calls itself with the
argument n-1, which is a smaller version of the problem. The function will continue
to call itself with smaller and smaller arguments until the base case is reached and the
function can return a value.
Recursion can be a powerful and elegant way to solve problems, but it can also be
hard to understand, and it can consume a lot of memory if not used carefully, as each
call creates a new call stack frame, and if the recursion depth is large it can cause a
stack overflow error.
Advantages of Recursion
Recursion is a powerful problem-solving technique that can be used to solve
many types of problems in Python, and it has several advantages:
1. Clarity and Simplicity: Recursive solutions can be simple and easy to
understand, especially for problems that have a natural recursive
structure.
2. Conciseness: Recursive solutions can be more concise than their iterative
counterparts, as they eliminate the need for explicit looping and counter
variables.
3. Reusability: Recursive functions can be reused for solving similar
problems with different inputs, making the code more modular and easy to
maintain.
4. Elegance: Recursive solutions can be elegant and visually pleasing, as they
capture the natural structure of the problem and express it in a clear and
concise way.
5. Flexibility: Recursive solutions can be adapted and extended to solve more
complex problems, as they can be combined with other techniques, such as
dynamic programming and memorization, to optimize their
performance.
It’s worth noting that recursion has also some drawbacks, like consuming a
lot of memory and the risk of stack overflow errors, and it might not always
be the best solution for a given problem, it’s important to consider the
complexity and performance of the algorithm before choosing recursion as
the solution.
Disadvantages of Recursion
Recursion is a programming technique where a function calls itself in order to solve a problem.
This technique is used to solve problems that can be broken down into smaller, similar
problems. In Python, recursion is implemented using function calls.
Disadvantages of recursion in python are:
1. It can be more difficult to understand and debug compared to iterative solutions.
2. It can consume a large amount of memory due to the call stack.
3. The risk of stack overflow error if the recursion goes too deep.
4. It can be less efficient as compared to iterative solution due to the overhead of function
calls.
5. Recursive solutions may be less readable and harder to maintain than their iterative
counterparts.
6. A problem that can be solved using a loop may use unnecessary additional function calls
with recursion.
7. Recursive solutions may not always be the best choice for solving a problem and may result
in slower performance.
Command Line Arguments
A Python program can accept any number of arguments from the command line.
Command line arguments is a methodology in which user will give inputs to the
program through the console using commands. You need to import sys module to
access command line arguments. All the command line arguments in Python can
be printed as a list of string by executing sys.argv.
Python Strings
A string consists of a sequence of characters, which includes letters, numbers, punctuation
marks and spaces. To represent strings, you can use a single quote, double quotes or triple
quotes.
Creating a String in Python
Here is a single Python program that demonstrates several ways to create a
string:
Accessing String Characters
Here is a single Python program that demonstrates several ways to access the
characters of a string:
This program demonstrates several ways to access the characters
of a string. The first method uses indexing to access individual
characters. The second method uses slicing to access a range of
characters. The third and fourth method uses for and while loop
respectively to access all characters one by one. The last method
uses the enumerate function to access the index and character at
the same time. Please note that string in python is immutable,
which means the individual elements of the string cannot be
changed once it is created.
Python String Operations
In Python, there are several built-in operations that can be
performed on strings, such as concatenation, repetition, and
comparison.
• String concatenation is the process of joining two or more
strings together. This can be done using the + operator, or the
join() method.
• String repetition is the process of repeating a string a certain
number of times. This can be done using the * operator.
• String comparison is the process of comparing two strings to
see if they are equal, or if one comes before the other in
lexicographic order. This can be done using the ==, !=, >, =, and
<= operators.
Concatenation
String
concatenation is
the process of
joining two or
more strings
together to form
a new string. In
Python, there are
several ways to
concatenate
strings, such as
using the +
operator, the +=
operator, the
join() method or
the f-strings.
Iteration and Membership Test
Iteration is the process of repeatedly executing a block of code for
a given number of times or until a certain condition is met. In
Python, this can be done using loops such as the for and while
loops.
Membership test is the process of checking if a specific element is
present in a container object such as a list, tuple, set, or string. In
Python, this can be done using the in and not in operators.
The first example uses a for loop to iterate over the characters of a string. The second
example uses a while loop to iterate over the characters of a string, using the string’s
length to determine when to stop the loop. The last example uses the in and not in
operators to check if a specific character is present in the string. The in operator
returns True if the character is found in the string, False otherwise. The not in operator
returns True if the character is not found in the string and False otherwise.
String Formatting
String formatting is the process of inserting values into a string. This can be
done using string formatting methods such as format(), f-strings and string
interpolation. These methods allow you to insert values into a string by
defining placeholders in the string and then providing the values to be
inserted.
Python String Built-in Methods
In Python, strings have a variety of built-in methods that can be used to
manipulate and interact with them. Some examples of these methods
include:
• upper(): Converts all characters in a string to uppercase
• lower(): Converts all characters in a string to lowercase
• replace(old, new): Replaces all occurrences of the old substring with the
new substring
• find(sub): Returns the index of the first occurrence of the substring
• count(sub): Returns the number of occurrences of the substring
• split(sep): Returns a list of substrings separated by the specified
separator
• strip(): Removes leading and trailing whitespace from a string
• join(iterable): Joins all elements in an iterable(list, tuple, etc) with the
string as a separator