Basics of Python Programming
Basics of Python Programming
Basics of Python Programming
Week 3 Mr.K.Raju
Python interactive:
using Python as a calculator
Using variables
MODULE -2
Durations Topics Resource Person
Mathematical functions
Python scripts (programs)
Variables and objects Mr.K.Raju
Week 4 User input, Iterating with indexing
Assignment 3
MODULE -3
Durations Topics Resource Person
Understanding Data with Statistics
Methods for python programming Mr.K.Raju
Week 5
W when to use closures?
Basics of python programming
1. Python installation
On Linux systems, Python 2.x is already installed. To download Python for Windows and OSx, and for
documentation see http://python.org/ It might be a good idea to install the Bethought distribution Canopy that
contains already the very useful modules Numpy, Scipy and Matplotlib: https://www.enthought.com/downloads/
Help commands:
modules: available modules
keywords: list of reserved Python keywords
quit: leave help
>>> 3.14*5
15.700000000000001
Supported operators:
Operator Example Explication
+, - add, substract,
*, / multiply, divide
% modulo 25 % 5 = 0 25/5 = 5, remainder = 0
84 % 5 = 4 84/5 = 16, remainder = 4
** exponent 2**10 = 1024
// floor division 84//5 = 16 84/5 = 16, remainder = 4
In the first example, 35 and 6 are interpreted as integer numbers, so integer division is used and
the result is an integer.
This uncanny behavior has been abolished in Python 3, where 35/6 gives 5.833333333333333.
In Python 2.x, use floating point numbers (like 3.14, 3.0 etc ... ) to force floating point division!
Another workaround would be to import the Python 3 like division at the beginning:
>>> from future import division
>>> 3/4
0.75
Builtin functions:
>>> hex(1024)
'0x400'
>>> bin(1024)
'0b10000000000'
Expressions:
>>> (20.0+4)/64
>>> (2+3)*525
4. Using variables
To simplify calculations, values can be stored in variables, and and these can be used as in
normal mathematics.
>>> a=2.0
>>> b = 3.36
>>> a+b
5.359999999999999
>>> a-b
-1.3599999999999999
>>> a**2 + b**2 15.289599999999998
>>> a>b
False
Keywords are:
and elif if print
as else import raise
assert except in return
break exec is try
class finally lambda while
continue for not with
def from or yield
del global pass
5. Mathematical functions
Mathematical functions like square root, sine, cosine and constants like pi etc. are available in
Python. To use them it is necessary to import them from the math module:
Note:
There is more than one way to import functions from modules. Our simple method imports all functions available in
the math module. For more details see appendix.
Take care:
• In Python white spaces are important!
The indentation of a source code is important!
A program that is not correctly indented shows either errors or does not what you
want!
7. A simple program
This small program calculates the area of a circle:
8. User input
In the above program the diameter is hard coded in the program.
If the program is started from IDLE or an editor like Geany, this is not really a problem, as it is
easy to edit the value if necessary.
This little program in Python 2.7 asks the user for his name and greets him:
In other programming languages, values are stored in variables. This is not exactly the same as an object, as an
object has "methods", that means functions that belong to the object.
For our beginning examples the difference is not important.
Now we can modify our program to calculate the area of a circle, so we can input the diameter:
Diameter: 25
Area = 490.873852123
Note:
The text at the beginning of the program is a description of what it does. It is a special comment
enclosed in triple quote marks that can spread over several lines.
Every program should have a short description of what it does.
0 0.0
1 1.0
2 1.41421356237
3 1.73205080757
.....
98 9.89949493661
99 9.94987437107
100 10.0
READY!
The syntax is :
while <condition> :
<....
block of statements
...>
The block of statements is executed as long as <condition> is True, in our example as long as i
<= 100.
Take care:
• Don't forget the ":" at the end of the while statement
• Don't forget to indent the block that should be executed inside the while loop!
The indentation can be any number of spaces ( 4 are standard ), but it must be consistent for the
whole block.
Examples of conditions:
Example
x == 3 True if x = 3
x != 5 True if x is not equal to 5
x<5
x>5
x <= 5
x >= 5
Note:
i = i +1 can be written in a shorter and more "Pythonic" way as i += 1
The following program greets the user with "Hello Tom", if the name he inputs is Tom:
if s == "Tom":
print "HELLO ", s
The above program can be extended to do something if the testing condition is not true:
s = raw_input ("Input your name: ")
if s == "Tom":
print "Hello ", s
else :
print "Hello unknown"
It is possible to test more than one condition using the elif statement:
Note the indentation and the ":" behind the if, elif and else statements!
13. Tuples
In Python, variables can be grouped together under one name. There are different ways to do this,
and one is to use tuples.
Tuples make sense for small collections of data, e.g. for coordinates:
(x,y) = (5, 3)
coordinates = (x,y)
print coordinates
(5, 3)
(8, 5.0, 3.14)
8
5.0
3.14
Note:
The brackets may be omitted, so it doesn't matter if you write x, y or (x, y)
Note:
Unlike other programming languages Python's arrays may contain different types of objects in one list.
a.append(5)
a.append( "Zapzoo")
print a
[0, 1, 2]
[0, 1, 2, 5, 'Zapzoo']
black
red
orange
r1 = range(11) # 0...10
print r1 # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
r2 = range(5,16) # 5...15
print r2 # [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
Take care:
• A strange (and somewhat illogical) detail of the range function is that the end value is
excluded from the resulting list!
• The range function only works for integers!
The next example gives 9 logarithmically spaced values between 100 = 102 and 1000 = 103:
r6 = np.logspace(2, 3, 9)
print r6
for n in mynames:
print "HELLO ", n
HELLO Sam
HELLO Pit
HELLO Misch
0 0.0
1 1.0
2 1.41421356237
3 1.73205080757
4 2.0
Notes:
• Python's for loop is somewhat different of the for ... next loops of other programming
languages. in principle it can iterate through anything that can be cut into slices. So it can be
used on lists of numbers, lists of text, mixed lists, strings, tuples etc.
• In Python the for ... next construction is often not to be missed, if we think in a
"Pythonic" way. Example: if we need to calculate a lot of values, it is not a good idea to use a
for loop, as this is very time consuming. It is better to use the Numpy module that provides
array functions that can calculate a lot of values in one bunch (see below).
18. Iterating with indexing
Sometimes you want to iterate through a list and have access to the index (the numbering) of the
items of the list.
The following example uses a list of colour codes for electronic parts and prints their index and
the colour. As the colours list is well ordered, the index is also the colour value.
""" Dispay resistor colour code values"""
colours = [ "black", "brown", "red", "orange", "yellow",
"green", "blue", "violet", "grey","white" ]
for c in cv:
print c[0], "\t", c[1]
The list(enumerate (. .. )) function gives back a list of tuples cv that contain each an index (the
numbering) and the color value as text. If we print this we see
[(0, 'black'), (1, 'brown'), (2, 'red'), (3, 'orange'), (4, 'yellow'), (5,
'green'), (6, 'blue'), (7, 'violet'), (8, 'grey'), (9, 'white')]
Now we iterate on this, so we get the different tuples one after the other.
From these tuples we print c[0], the index and c[1], the colour text, separated by a tab.
So as a result we get:
0 black
1 brown
2 red
...
8 grey
9 white
19. Functions
It is a good idea to put pieces of code that do a clearly defined task into separate blocks that are
called functions. Functions must be defined before they are used.
Once they are defined, they can be used like native Python statements.
A very simple example calculates area and perimeter of a rectangle:
# function definitions
def area(b, h):
""" calculate area of a rectangle"""
A = b * h return A
If the function doesn't need to return a value, the return statement can simply be omitted.
Example:
# function definition
def greeting():
print "HELLO"
One good thing about functions is that they can be easily reused in another program.
Notes:
• Functions that are used often can be placed in a separate file called a module. Once this
module is imported the functions can be used in the program.
• It is possible to pass a variable number of arguments to a function.
For details see here: http://en.wikibooks.org/wiki/Python_Programming/Functions
• It is possible to pass named variables to a function
20. Avoiding for loops: vector functions
For loops tend to get slow if there are many iterations to do.
They are not necessary for calculations on numbers, if the Numpy module is used. It can befound
here http://www.numpy.org/ and must be installed before using it.
In this example we get 100 values of a sine function in one line of code:
import numpy as np
print x
print y
21. Diagrams
Once you have calculated the many function values, it would be nice to display them in adiagram. This
is very simple if you use Matplotlib, the standard Python plotting library.
Matplotlib can be found here: http://matplotlib.org/downloads
The following program calculates the values of a function and draws a diagram:
from numpy import linspace, sin, exp, pi
import matplotlib.pyplot as mp
# make diagram
mp.plot(x,y)
mp.show()
Notes:
• Matplotlib offers much more than this, see online documentation.
• There are two ways to use Matplotlib: a simple functional way that we have just
used, and a more complicated object oriented way, that allows for example to
embed a diagram into a GUI.
1.the simplest way: import everything from a moduleadvantage: simple usage e.g. of math functions
disadvantage: risk of naming conflicts when a variable has the same name as a module function
2.import module under an alias name that is short enough to enhance code clarityadvantage: it is
clear to see which function belongs to which module
import numpy as np
print np.sin(np.pi/4)
3.import only the functions that are needed advantage: simple usage e.g. of math functions naming
conflict possible, but less probable than with
1.disadvantage: you must keep track of all the used functions and adapt the import statement if anew
function is used
Python Directory
If there are a large number of files to handle in our Python program, we can arrange our code within
different directories to make things more manageable. A directory or folder is a collection of files and
subdirectories. Python has the os module that provides us with many useful methods to work with
directories (and files as well).
Get Current Directory
We can get the present working directory using the getcwd() method of the os module.
This method returns the current working directory in the form of a string. We can also use
the getcwdb() method to get it as bytes object.
>>> import os
>>> os.getcwd()
'C:\\Program Files\\PyScripter'
>>> os.getcwdb()
b'C:\\Program Files\\PyScripter'
The extra backslash implies an escape sequence. The print() function will render this properly.
>>> print(os.getcwd())
C:\Program Files\PyScripter
Changing Directory
We can change the current working directory by using the chdir() method.
The new path that we want to change into must be supplied as a string to this method. We can use both
the forward-slash / or the backward-slash \ to separate the path elements.
It is safer to use an escape sequence when using the backward slash.
>>> os.chdir('C:\\Python33')
>>> print(os.getcwd())
C:\Python33
>>> os.listdir()
['DLLs',
'Doc',
'include',
'Lib',
'libs',
'LICENSE.txt',
'NEWS.txt',
'python.exe',
'pythonw.exe',
'README.txt',
'Scripts',
'tcl',
'Tools']
>>> os.listdir('G:\\')
['$RECYCLE.BIN',
'Movies',
'Music',
'Photos',
'Series',
'System Volume Information']
Exceptions in Python
Python has many built-in exceptions that are raised when your program encounters an error (something
in the program goes wrong).
When these exceptions occur, the Python interpreter stops the current process and passes it to the
calling process until it is handled. If not handled, the program will crash.
For example, let us consider a program where we have a function A that calls function B, which in turn
calls function C. If an exception occurs in function C but is not handled in C, the exception passes
to B and then to A.
If never handled, an error message is displayed and our program comes to a sudden unexpected halt.
Catching Exceptions in Python
In Python, exceptions can be handled using a try statement.
The critical operation which can raise an exception is placed inside the try clause. The code that handles the
exceptions is written in the except clause.
We can thus choose what operations to perform once we have caught the exception. Here is a simple example.
# import module sys to get the type of exception
import sys
randomList = ['a', 0, 2]
The entry is 0
Oops! <class 'ZeroDivisionError'> occured.
Next entry.
The entry is 2
The reciprocal of 2 is 0.5
In this program, we loop through the values of the randomList list. As previously mentioned, the
portion that can cause an exception is placed inside the try block.
If no exception occurs, the except block is skipped and normal flow continues(for last value). But if
any exception occurs, it is caught by the except block (first and second values).
Here, we print the name of the exception using the exc_info() function inside sys module. We can see
that a causes ValueError and 0 causes ZeroDivisionError.
Catching Specific Exceptions in Python
In the above example, we did not mention any specific exception in the except clause.
This is not a good programming practice as it will catch all exceptions and handle every case in the same way.
We can specify which exceptions an except clause should catch.
A try clause can have any number of except clauses to handle different exceptions, however, only one will be
executed in case an exception occurs.
We can use a tuple of values to specify multiple exceptions in an except clause. Here is an example pseudo code.
try:
# do something
pass
except ValueError:
# handle ValueError exception
pass
except:
# handle all other exceptions
pass
One of the popular approaches to solve a programming problem is by creating objects. This is known as Object-
Oriented Programming (OOP).
attributes
behavior
The concept of OOP in Python focuses on creating reusable code. This concept is also known as DRY (Don't
Repeat Yourself).
In Python, the concept of OOP follows some basic principles:
Class
We can think of class as a sketch of a parrot with labels. It contains all the details about the name, colors, size
etc. Based on these descriptions, we can study about the parrot. Here, a parrot is an object.
class Parrot:
pass
Here, we use the class keyword to define an empty class Parrot. From class, we construct instances. An instance
is a specific object created from a particular class.
Object
An object (instance) is an instantiation of a class. When class is defined, only the description for the object is
defined. Therefore, no memory or storage is allocated.
obj = Parrot()
Here, obj is an object of class Parrot.
Suppose we have details of parrots. Now, we are going to show how to build the class and objects of parrots.
# class attribute
species = "bird"
# instance attribute
def __init__(self, name, age):
self.name = name
self.age = age
Methods
Methods are functions defined inside the body of a class. They are used to define the behaviors of an object.
# instance attributes
def __init__(self, name, age):
self.name = name
self.age = age
# instance method
def sing(self, song):
return "{} sings {}".format(self.name, song)
def dance(self):
return "{} is now dancing".format(self.name)
Inheritance
Inheritance is a way of creating a new class for using details of an existing class without modifying it. The newly
formed class is a derived class (or child class). Similarly, the existing class is a base class (or parent class).
def __init__(self):
print("Bird is ready")
def whoisThis(self):
print("Bird")
def swim(self):
print("Swim faster")
# child class
class Penguin(Bird):
def __init__(self):
# call super() function
super().__init__()
print("Penguin is ready")
def whoisThis(self):
print("Penguin")
def run(self):
print("Run faster")
peggy = Penguin()
peggy.whoisThis()
peggy.swim()
peggy.run()
Output
Bird is ready
Penguin is ready
Penguin
Swim faster
Run faster
In the above program, we created two classes i.e. Bird (parent class) and Penguin (child class). The child class
inherits the functions of parent class. We can see this from the swim() method.
Again, the child class modified the behavior of the parent class. We can see this from the whoisThis() method.
Furthermore, we extend the functions of the parent class, by creating a new run() method.
Additionally, we use the super() function inside the __init__() method. This allows us to run
the __init__() method of the parent class inside the child clas
Encapsulation
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 attributes using underscore as the
prefix i.e single _ or double __.
Example 4: Data Encapsulation in Python
class Computer:
def __init__(self):
self.__maxprice = 900
def sell(self):
print("Selling Price: {}".format(self.__maxprice))
c = Computer()
c.sell()
#instantiate objects
blu = Parrot()
peggy = Penguin()
In the above program, we defined two classes Parrot and Penguin. Each of them have a common fly() method.
However, their functions are different.
To use polymorphism, we created a common interface i.e flying_test() function that takes any object and calls
the object's fly() method. Thus, when we passed the blu and peggy objects in the flying_test() function, it ran
effectively.
Iterators in Python
Iterators are everywhere in Python. They are elegantly implemented within for loops, comprehensions,
generators etc. but are hidden in plain sight.
Iterator in Python is simply an object that can be iterated upon. An object which will return data, one element at
a time.
Technically speaking, a Python iterator object must implement two special
methods, __iter__() and __next__(), collectively called the iterator protocol.
An object is called iterable if we can get an iterator from it. Most built-in containers in Python
like: list, tuple, string etc. are iterables.
The iter() function (which in turn calls the __iter__() method) returns an iterator from them.
We use the next() function to manually iterate through all the items of an iterator. When we reach the end and
there is no more data to be returned, it will raise the StopIteration Exception. Following is an example.
# define a list
my_list = [4, 7, 0, 3]
# Output: 4
print(next(my_iter))
# Output: 7
print(next(my_iter))
# Output: 0
print(my_iter.__next__())
# Output: 3
print(my_iter.__next__())
Python generators are a simple way of creating iterators. All the work we mentioned above are automatically
handled by generators in Python.
Simply speaking, a generator is a function that returns an object (iterator) which we can iterate over (one value at
a time).
It is fairly simple to create a generator in Python. It is as easy as defining a normal function, but with
a yield statement instead of a return statement. If a function contains at least one yield statement (it may contain
other yield or return statements), it becomes a generator function. Both yield and return will return some value
from a function. The difference is that while a return statement terminates a function entirely, yield statement
pauses the function saving all its states and later continues from there on successive calls.
Methods like __iter__() and __next__() are implemented automatically. So we can iterate through the items
using next().
Once the function yields, the function is paused and the control is transferred to the caller.
Local variables and their states are remembered between successive calls.
Finally, when the function terminates, StopIteration is raised automatically on further calls.
Here is an example to illustrate all of the points stated above. We have a generator function
named my_gen() with several yield statements.
# A simple generator function
def my_gen():
n=1
print('This is printed first')
# Generator function contains yield statements
yield n
n += 1
print('This is printed second')
yield n
n += 1
print('This is printed at last')
yield n
An interactive run in the interpreter is given below. Run these in the Python shell to see the output.
>>> # It returns an object but does not start execution immediately.
>>> a = my_gen()
>>> # Local variables and theirs states are remembered between successive calls.
>>> next(a)
This is printed second
2 >>> next(a)
This is printed at last
3 >>> # Finally, when the function terminates, StopIteration is raised automatically on further calls.
>>> next(a)
Traceback (most recent call last):
...
StopIteration
>>> next(a)
Traceback (most recent call last):
...
StopIteration
One interesting thing to note in the above example is that the value of variable n is remembered between each
call.
Unlike normal functions, the local variables are not destroyed when the function yields. Furthermore, the
generator object can be iterated only once.
To restart the process we need to create another generator object using something like a = my_gen().
One final thing to note is that we can use generators with for loops directly.
This is because a for loop takes an iterator and iterates over it using next() function. It automatically ends
when StopIteration is raised. Check here to know how a for loop is actually implemented in Python.
# A simple generator function
def my_gen():
n=1
print('This is printed first')
# Generator function contains yield statements
yield n
n += 1
print('This is printed second')
yield n
n += 1
print('This is printed at last')
yield n
Python Closures
Before getting into what a closure is, we have to first understand what a nested function and nonlocal variable is.
A function defined inside another function is called a nested function. Nested functions can access variables of
the enclosing scope.
In Python, these non-local variables are read-only by default and we must declare them explicitly as non-local
(using nonlocal keyword) in order to modify them.
Following is an example of a nested function accessing a non-local variable.
def print_msg(msg):
# This is the outer enclosing function
def printer():
# This is the nested function
print(msg)
printer()
In the example above, what would happen if the last line of the function print_msg() returned
the printer() function instead of calling it? This means the function was defined as follows:
def print_msg(msg):
# This is the outer enclosing function
def printer():
# This is the nested function
print(msg)
Output
Hello
That's unusual.
The print_msg() function was called with the string "Hello" and the returned function was bound to the
name another. On calling another(), the message was still remembered although we had already finished
executing the print_msg() function.
This technique by which some data ("Hello in this case) gets attached to the code is called closure in Python.
This value in the enclosing scope is remembered even when the variable goes out of scope or the function itself
is removed from the current namespace.
Try running the following in the Python shell to see the output.
The criteria that must be met to create closure in Python are summarized in the following points.
The nested function must refer to a value defined in the enclosing function.
Closures can avoid the use of global values and provides some form of data hiding. It can also provide an object
oriented solution to the problem.
When there are few methods (one method in most cases) to be implemented in a class, closures can provide an
alternate and more elegant solution. But when the number of attributes and methods get larger, it's better to
implement a class.
Python RegEx
In this tutorial, you will learn about regular expressions (RegEx), and use Python's re module to work with
RegEx (with the help of examples).
A Regular Expression (RegEx) is a sequence of characters that defines a search pattern. For example,
^a...s$
The above code defines a RegEx pattern. The pattern is: any five letter string starting with a and ending
with s.
A pattern defined using RegEx can be used to match against a string.
Expression String Matched?
abs No match
alias Match
Alias No match
An abacus No match
pattern = '^a...s$'
test_string = 'abyss'
result = re.match(pattern, test_string)
if result:
print("Search successful.")
else:
print("Search unsuccessful.")
Here, we used re.match() function to search pattern within the test_string. The method returns a match object if
the search is successful. If not, it returns None.
There are other several functions defined in the re module to work with RegEx. Before we explore that, let's
learn about regular expressions themselves.