<<

PYTHON PROGRAMMING

UNIT-V

NAMESPACES Encapsulation in Functions Encapsulation is the packing of data and functions operating on that data into a single component and restricting the access to some of the object’s components. Encapsulation means that the internal representation of an object is generally hidden from view outside of the object’s definition. A class is an example of encapsulation as it encapsulates all the data that is member functions, variables.

I. Difference between Abstraction and Encapsulation Abstraction is a mechanism which represents the essential features without including implementation. Encapsulation — Information hiding. Abstraction — Implementation hiding. Private members: Using OOP in Python, we can restrict access to methods and variables. This prevents data from direct modification which is called encapsulation. In Python, we denote private attribute using underscore as prefix i.e single “ _ “ or double “ __“..

Example of accessing private member data class Person: def __init__(self): self.name = 'Manjula' self.__lastname = 'Dube' def PrintName(self): return self.name +' ' + self.__lastname #Outside class P = Person()print(P.name) print(P.PrintName()) print(P.__lastname) #AttributeError: 'Person' object has no attribute '__lastname'

II. Code Reuse and Modularity A function is a block of code which is used to perform some action, and it is also called as reusable code. A function provides higher modularity and code re-usability. As Python is an interpreted language, it follows a top-down approach. The most important factor in any is the ‘modules’. The module is a program that can be included or imported to the other programs so that it can be reused in the future without writing the same module again. Python that helps us to invoke the functions automatically by operating the system during run-time or when the program is executed, and this is what we call as the main function.

Example : 1 print(“Good Morning”) 2

3 def main(): 4 print(“Hello Python”) 5

6 print(“Good Evening”)

1

Output: Good Morning Good Evening If we observe the above program, it has printed only ‘Good Morning’ and ‘Good Evening’ and it did not print the term ‘Hello Python’ which is because we didn’t call it manually or we didn’t use the python’s main function here.

Modularity Modularity refers to the act of partitioning the code into modules building them first followed by linking and finally combining them to form a complete project. Modularity ensures re-usability and minimize the duplication. A module in Python is nothing but a file containing Python definitions followed by methods & statements. The module name is generated out of the file name by removing the suffix “.py”. For example, if the file name is fibonacci.py, the module name is fibonacci. Let's create a module. We save the following code in the file fibonacci.py: def fib(n): if n == 0: return 0 elif n == 1: return 1 else: return fib(n-1) + fib(n-2) def ifib(n): a, b = 0, 1 for i in range(n): a, b = b, a + b return a We can import this module in the interactive python shell and call the functions by prefixing them with "fibonacci.": >>> import fibonacci >>> fibonacci.fib(30) 832040

NAMESPACES A name in Python is a way to access a variable like in any other languages. Python is more flexible when it comes to the variable declaration. We can declare a variable by assigning a name to it. We can use names to reference values.

Example: num = 5 str = 'Z' seq = [0, 1, 1, 2, 3, 5] #We can even assign a name to a function. def function(): print('It is a function.') foo = function foo()

A is a simple system to control the names in a program. A namespace is a dictionary of variable names (keys) and their corresponding objects (values). Namespaces play a key role in the execution of function calls and the normal control flow of a program. Python implements namespaces in the form of

2

dictionaries. It maintains a name-to-object mapping where names act as keys and the objects as values. Multiple namespaces may have the same name but pointing to a different variable.

Types of Namespaces

1. Local Namespace Creation of local functions creates the local namespace. This namespace covers the local names inside a function. Python creates this namespace for every function called in a program. It remains active until the function returns.

2. Global Namespace When a user creates a module, a global namespace gets created. This namespace covers the names from various imported modules used in a project. Python creates this namespace for every module included in your program. It’ll last until the program ends.

3. Built-in Namespace This namespace covers the built-in functions and built-in exception names. Python creates it as the interpreter starts and keeps it until you exit. The built-in namespace encompasses global namespace and global namespace encompasses local namespace. Some functions like print(), id() are examples of built in namespaces.

Lifetime of a namespace: A lifetime of a namespace depends upon the of objects, if the scope of an object ends, the lifetime of that namespace comes to an end. It is not possible to access inner namespace’s objects from an outer namespace. Scopes A scope refers to a region of a program where a namespace can be directly accessed, i.e. without using a namespace prefix. The scope of a name is the area of a program where this name can be unambiguously used, for example, inside of a function. A name's namespace is identical to its scope. Scopes are defined statically, but they are used dynamically.

During program execution there are the following nested scopes available:  the innermost scope is searched first and it contains the local names  the scopes of any enclosing functions, which are searched starting with the nearest enclosing scope  the next-to-last scope contains the current module's global names  the outermost scope, which is searched last, is the namespace containing the built-in names.

3

Example: # var1 is in the global namespace var1 = 5 def some_func(): # var2 is in the local namespace var2 = 6 def some_inner_func(): # var3 is in the nested local # namespace var3 = 7

Modules as Namespaces Module is a file consisting of Python code. A module can define functions, classes and variables. When the module is executed (imported), and then the module is (also) a namespace. This namespace has a name, which is the name of the module. In this namespace, the names that are defined in the global scope of the module: the names of functions, values, and classes defined in the module. These names are all referred to as the module’s attributes. 1. Module Attributes To get access to all the functions in the Standard Library module math, we import the module: >>> import math Once a module is imported, the Python built-in function dir() can be used to view all the module’s attributes. dir() is a powerful inbuilt function in Python3, which returns list of the attributes and methods of any object (say functions , modules, strings, lists, dictionaries etc.) Syntax : dir({object}) Example: >>> dir(math) ['__doc__', '__file__', '__name__', '__package__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'exp', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'hypot', 'isinf', 'isnan', 'ldexp', 'log', 'log10', 'log1p', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']

Python - Math Module Some of the most popular mathematical functions are defined in the math module. These include trigonometric functions, representation functions, logarithmic functions, angle conversion functions, etc. Pie (π) is a well-known mathematical constant, which is defined as the ratio of the circumference to the diameter of a circle and its value is 3.141592653589793. >>> import math >>>math.pi 3.141592653589793 Another well-known mathematical constant defined in the math module is e. It is called Euler's number and it is a base of the natural logarithm. Its value is 2.718281828459045. >>>math.e 2.718281828459045

Locating Modules When you import a module, the Python interpreter searches for the module in the following sequences  The current .  If the module is not found, Python then searches each directory in the shell variable PYTHONPATH.  If all else fails, Python checks the default . On UNIX, this default path is normally /usr/local/lib/python3/. 4

The module search path is stored in the system module sys as the sys.path variable. The sys.path variable contains the current directory, PYTHONPATH, and the installation dependent default.

2. Python - Sys Module The sys module provides functions and variables used to manipulate different parts of the Python runtime environment. i) sys.path This is an environment variable that is a search path for all Python modules. >>>sys.path ['', 'tag">C:\\python36\\Lib\\idlelib', 'C:\\python36\\python36.zip', 'C:\\python36\\DLLs', 'C:\\python36\\lib', 'C:\\python36', 'C:\\Users\\acer\\AppData\\Roaming\\Python\\Python36\\site- packages', 'C:\\python36\\lib\\site-packages'] ii) sys.version This attribute displays a string containing the version number of the current Python interpreter. >>>sys.version '3.7.0 (v3.7.0:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit (AMD64)]' iii) sys.maxsize Returns the largest integer a variable can take. >>> import sys >>>sys.maxsize 9223372036854775807 iv) sys.exit This causes the script to exit back to either the Python console or the command prompt. This is generally used to safely exit from the program in case of generation of an exception.

3. Top-Level Module A computer application is a program that is typically split across multiple files (i.e., modules). In every Python program, one of the modules is special: It contains the “main program” by which we mean the code that starts the application. This module is referred to as the top-level module. The remaining modules are essentially “library” modules that are imported by the top-level module and contain functions and classes that are used by the application. We have seen that when a module is imported, the Python interpreter creates a few “bookkeeping” variables in the module namespace. One of these is variable __name__. Python will set its value in this way: • If the module is being run as a top-level module, attribute __name__ is set to the string __main__. • If the file is being imported by another module, whether the top-level or other, at- tribute __name__ is set to the module’s name. We use the next module to illustrate how __name__ is assigned: print('My name is {}'.format(__name__)) When this module is executed by running it from the shell (e.g., by hitting F5 in the IDLE shell), it is run as the main program (i.e., the top-level module): >>> My name is __main__ So the __name__ attribute of the imported module is set to __main__. The module name is also the top-level module when it is run at the command line: > python name.py My name is __main__ If, however, another module imports module name, then module name will not be top level. In the next import statement, the shell is the top-level program that imports the mod- ule name.py: >>> import name My name is name Here is another example. The next module has only one statement, a statement that imports module name.py: import name When module import.py is run from the shell, it is run as the main program that imports module name.py:

5

>>> My name is name In both cases, the __name__ attribute of the imported module is set to the name of the module. The __name__ attribute of a module is useful for writing code that should be executed only when the module is run as the top-level module. This would be the case, for example, if the module is a “library” module that contains function definitions and the code is used for debugging. All we need to do is make the debugging code a code block of this if statement: if __name__ == '__main__': # code block If the module is run as a top-level module, the code block will be executed; otherwise it will not.

Different Ways to Import Module Attributes We have three different ways to import a module and its attributes. We again use the module example as our running example: 1 'an example module' 2 def f(): 3 print('Executing f()') 4 5 def g(): 6 print('Executing g()') 7 8 x=0 # global var One way to get access to functions f() or g(), or x, is to: >>> import example This import statement will find the file example.py and run the code in it. This will instantiate two function objects and one integer object and create a namespace, called example, where the names of the created objected will be stored. In order to access and use the module attributes, we need to specify the module namespace: >>> example.f() Executing f() As we have seen, calling f() directly would result in an error. Therefore, the import statement did not bring name f into the namespace of module __main__ (the module that imported example); it only brings the name of the module example, as illustrated below.

Instead of importing the name of the module, it is also possible to import the names of the needed attributes themselves using the from command: >>> from example import f As illustrated in above diagram, from copies the name of attribute f to the scope of the main program, the module doing the import, so that f can be referred to directly, without having to specify the module name. >>> f() Executing f() Finally, is is also possible to use from to import all the attributes of a module using the wild card *: >>> from example import * >>> f() Executing f() >>> x 0 The below diagram shows that all the attributes of example are copied to the namespace__main__.

6

Exceptional Control Flow Exception is an abnormal condition that halts the execution of the program. The default exceptional control flow is to stop the program and print the error message contained in the exception object.

I. Exceptions and Exceptional Control Flow When an exception occurs, the normal flow of execution is interrupted and leads to an error message.

Example : 1. a = int(input("Enter a:")) 2. b = int(input("Enter b:")) 3. c = a/b; 4. print("a/b = %d"%c) 5. 6. #other code: 7. print("Hi I am other part of the program")

Output: Enter a:10 Enter b:0 Traceback (most recent call last): File "exception-test.py", line 3, in c = a/b; ZeroDivisionError: division by zero When execution returns to the shell, the information contained in the exception object is printed in the shell. In addition to the type of error and a friendly error message, the output also includes a traceback, which consists of all the function calls that got interrupted by the error.

II. Catching and Handling Exceptions All the runtime (and syntax) errors that we have encountered are called exceptions in Python. All exceptions are subclasses of the Exception class. When an exception occurs, the normal flow of execution is interrupted. Python checks to see if the line of code which caused the exception is inside a try block. If it is, it checks to see if any of the except blocks associated with the try block can handle that type of exception. If an appropriate handler is found, the exception is handled, and the program continues from the next statement after the end of that try-except. The format of a try/except pair of statements is: try: except: The execution of is attempted first. If it goes through without any raised exceptions, then is ignored and execution continues with .

Example : >>> n = int(raw_input("Please enter a number: ")) Please enter a number: 23.5 Output: Traceback (most recent call last): File "", line 1, in ValueError: invalid literal for int() with base 10: '23.5'

7

Assuming we want to ask the user to enter an integer number. If we use a raw_input(), the input will be a string, which we have to cast into an integer. If the input has not been a valid integer, we will generate (raise) a ValueError. With the aid of exception handling, we can write robust code for reading an integer from input: while True: try: n = raw_input("Please enter an integer: ") n = int(n) break except ValueError: print("No valid integer! Please try again ...") print "Great, you successfully entered an integer!"

The while loop is entered. The code within the try clause will be executed statement by statement. If no exception occurs during the execution, the execution will reach the break statement and the while loop will be left. If an exception occurs, i.e. in the casting of n, the rest of the try block will be skipped and the except clause will be executed. The raised error, in our case a ValueError, has to match one of the names after except. In our example only one, i.e. "ValueError:". After having printed the text of the print statement, the execution does another loop. It starts with a new raw_input().

Advantages of exception handling: 1. It separates normal code from code that handles errors. 2. Exceptions can easily be passed along functions in the stack until they reach a function which knows how to handle them. The intermediate functions don’t need to have any error-handling code. 3. Exceptions come with lots of useful error information built in – for example, they can print a traceback which helps us to see exactly where the error occurred.

III. Declaring multiple exceptions The python allows us to declare the multiple exceptions with the except clause. Declaring multiple exceptions is useful in the cases where a try block throws multiple exceptions. Syntax: try: #block of code except (,,,...) #block of code else: #block of code Example: try: a=10/0; except ArithmeticError,StandardError: print "Arithmetic Exception" else: print "Successfully Done"

Output: Arithmetic Exception

IV. The finally block We can use the finally block with the try block in which, we can pace the important code which must be executed before the try statement throws an exception. ntax

8

try: # block of code # this may throw an exception finally: # block of code # this will always be executed

The finally clause will be executed at the end of the try-except block – if there is no exception, if an exception is raised and handled, if an exception is raised and not handled, and even if we exit the block using break, continue or return. We can use the finally clause for cleanup code that we always want to be executed: try: age = int(input("Please enter your age: ")) except ValueError: print("Hey, that wasn't a number!") else: print("I see that you are %d years old." % age) finally: print("It was really nice talking to you. Goodbye!")

Important Two Mark Questions with Answers

1) What is Python? What are the benefits of using Python? Python is a programming language with objects, modules, threads, exceptions and automatic memory management. It is a high-level, interpreted, interactive, and object-oriented scripting language. Python is designed to be highly readable. The benefits of pythons are that it is simple and easy, portable, extensible, build-in data structure and it is an open source. 2) What are the applications of Python? Python is used in various software domains some application areas are given below.  Web and Development  Games  Scientific and computational applications  Language development  Image processing and graphic design applications  What are the advantages of Python?  Interpreted  Free and open source 9

 Extensible  Object-oriented  Built-in data structure  Readability  High-Level Language  Cross-platform 3) What are the supported data types in Python? Python has five standard data types:  Numbers  Strings  Lists  Tuples  Dictionaries 4) What are the built-in type does python provides? There are mutable and Immutable types of Pythons built in types Mutable built-in types  List  Sets  Dictionaries Immutable built-in types  Strings  Tuples  Numbers 5) What is namespace in Python? In Python, every name introduced has a place where it lives and can be hooked for. This is known as namespace. It is like a box where a variable name is mapped to the object placed. Whenever the variable is searched out, this box will be searched, to get corresponding object. 6) What is a dictionary in Python? Python dictionary is one of the supported data types in Python. It is an unordered collection of elements. The elements in dictionaries are stored as key–value pairs. Dictionaries are indexed by keys. For example, we have a dictionary named ‘dict’. It contains some keys: Country, Capital along with their corresponding values: India and New Delhi. dict={‘Country’:’India’,’Capital’:’New Delhi’, } 7) What is the difference between arrays and lists. Arrays Lists

Arrays can only store homogeneous data Lists can store heterogenous and arbitrary (data of the same type). data.

Since only one type of data can be stored, Lists can store data of multiple data types and arrays use memory for only one type of thus require more memory than arrays. objects. Thus, mostly, arrays use lesser memory than lists.

Length of an array is pre-fixed while creating Since the length of a list is not fixed, it, so more elements cannot be added. appending items in it is possible. 8) What is negative index in Python?

10

Python sequences can be index in positive and negative numbers. For positive index, 0 is the first index, 1 is the second index and so forth. For negative index, (-1) is the last index and (-2) is the second last index and so forth. 9) What are local variables and global variables in Python? Global Variables: Variables declared outside a function or in global space are called global variables. These variables can be accessed by any function in the program. Local Variables: Any variable declared inside a function is known as a local variable. This variable is present in the local space and not in the global space. Example: 1 a=2 2 def add(): 3 b=3 4 c=a+b 5 print(c) 6 add() 10) What is the difference between lists and tuples? Lists Tuples

Lists are mutable, i.e., they can be Tuples are immutable (Tuples are lists which cannot edited. be edited).

Lists are usually slower than tuples. Tuples are faster than lists.

Syntax: list_1 = [10, ‘Intellipaat’, 20] Syntax: tup_1 = (10, ‘Intellipaat’ , 20)

11) What are functions in Python? A function is a block of code which is executed only when it is called. To define a Python function, the def keyword is used. Example: 1 def Newfunc(): 2 print("Hi, Welcome to Edureka") 3 Newfunc(); #calling the function Output: Hi, Welcome to Edureka 12) How can you generate random numbers in Python? Random module is the standard module that is used to generate a random number. The method is defined as: 1 import random 2 random.random 13) How do you write comments in python? Comments in Python start with a # character. However, alternatively at times, commenting is done using docstrings(strings enclosed within triple quotes). Example: #Comments in Python start like this print("Comments in Python start with a #") Output: Comments in Python start with a # 14) What are docstrings in Python? Docstrings are not actually comments, but, they are documentation strings. These docstrings are within triple quotes. They are not assigned to any variable and therefore, at times, serve the purpose of comments as well. Example:

11

""" Using docstring as a comment. This code divides 2 numbers """ 15) What is tuple in Python? A tuple is a built-in data collection type. It allows us to store values in a sequence. It is immutable, so no change is reflected in the original data. It uses () brackets rather than [] square brackets to create a tuple. We cannot remove any element but can find in the tuple. We can use indexing to get elements. It also allows traversing elements in reverse order by using negative indexing. Tuple supports various methods like max(), sum(), sorted(), Len() etc. 16) What are the different types of operators in Python? Python uses a rich set of operators to perform a variety of operations. Some individual operators like membership and identity operators are not so familiar but allow to perform operations.  Arithmetic Operators  Relational Operators  Assignment Operators  Logical Operators  Membership Operators  Identity Operators  Bitwise Operators 17) What is slicing in Python? Slicing is a mechanism used to select a range of items from sequence type like list, tuple, and string. It is beneficial and easy to get elements from a range by using slice way. It requires a : (colon) which separates the start and end index of the field. 18) What is an error in Python? Error caused by not following the proper structure (syntax) of the language is called syntax error or parsing error. >>> if a < 3 File "", line 1 if a < 3 SyntaxError: invalid syntax 19) What is an exception? Errors can also occur at runtime and these are called exceptions. For example, when a file we try to open does not exist (FileNotFoundError), dividing a number by zero (ZeroDivisionError), module we try to import is not found (ImportError) etc.

12