Wednesday, July 20, 2011

How to get user input in python?

In Python we can use the raw_input() and input() to take inputs from user.

Example for raw_input()..
>>> lastName = raw_input("What is your Last Name?")
What is your Last Name?pk
>>> firstName = raw_input("What is your First Name?")
What is your First Name?amala
>>> print("Is your name {0} {1}?".format(firstName, lastName))
Is your name amala pk?
>>>

Example for input()..
>>> x = input("Enter a number:")
Enter a number:6
>>> print x
6

Now let's think how these inputs are interpreted....
Using raw_input, the data is always interpreted as a string...Using input, the data is always interpreted as integer type...

We can check this...

>>> a=raw_input()
5
>>> print type(a)
>>> digit=int(a)
>>> print type(digit)
>>>

also

>>> a=input()
6
>>> print type(a)
>>> string=str(a)
>>> print type(string)

Thus we can use int() and str() to convert to integer type and string type respectively.



Tuesday, July 12, 2011

Some Programs involving Recursion

We can find a^b using recursion.The code is..

def power(a, b):
if (b == 0):
return 1
else:
a=a*power(a, b-1)
return a

print power(3, 9)


We can optimise the above program and reduce the time complexity.
Here is the code for that..

def power(a, b):
if(b == 0):
return 1
else:
if(b%2 == 0):
v = power(a, b/2)
return v**2
else:
v = power(a, (b-1)/2)
return a*v**2

print power(3, 5)


Next we can move on to finding the nth element of Fibonacci series.
For that we have a recursive code..

def fib(n):
if n<2 :
return n
else:

return fib(n-1)+fib(n-2)

print fib(6)


We can optimise the above code using the technique of memorisation.
Then the code will be..

def fib(n):
if not n in memory:
memory[n] = fib(n-1) + fib(n-2)
return memory[n]

memory={0:0,1:1}
print fib (250)





Thursday, July 7, 2011

Object-Oriented Programming

One of the way of organising our program is to combine data and functionality and wrap it inside an object. This is called the object oriented programming paradigm. This way is used when we want to write large programs or have a solution that is better suited to it.

Classes and objects are the two main aspects of object oriented programming. A class creates a new type where objects are instances of the class. Even integers are treated as objects (of the int class)

Objects can store data using ordinary variables that belong to the object. Variables that belong to an object or class are called as fields. Objects can also have functionality by using functions that belong to a class. Such functions are called methods of the class. This terminology is important because it helps us to differentiate between functions and variables which are separate by itself and those which belong to a class or object. Collectively, the fields and methods can be referred to as the attributes of that class.

Fields are of two types - they can belong to each instance/object of the class or they can belong to the class itself. They are called instance variables and class variables respectively.

A class is created using the class keyword. The fields and methods of the class are listed in an indented block.

Class methods have only one specific difference from ordinary functions - they must have an extra first name that has to be added to the beginning of the parameter list, but you do do not give a value for this parameter when you call the method, Python will provide it. This particular variable refers to the object itself, and by convention, it is given the name self.

Although, you can give any name for this parameter, it is strongly recommended that you use the name self - any other name is definitely frowned upon.

>>> class person:
... pass
...
>>> p=person()
>>> print p
<__main__.person instance at 0xb776586c>

We have already discussed that classes/objects can have methods just like
functions except that we have an extra
self variable. We will now see
an example.


>>> class person:

... def sayHi(self):
... print "Hai,friend"
...
>>> p=person()
>>> p.sayHi()
Hai,friend
>>>


The __init__ method
There are many method names which have special significance in Python classes.

The __init__ method is run as soon as an object of a class is instantiated. The method is useful to do any initialization you want to do with your object. Notice the double underscore both in the beginning and at the end in the name.

>>> class person:
... def __init__(self,name):
... self.name=name
... def sayHi(self):
... print "Hai, my name is",self.name
...
>>> p=person('amala')
>>> p.sayHi()
Hai, my name is amala

Here, we define the __init__ method as taking a parameter name (along with the usual self). Here, we just create a new field also called name. Notice these are two different variables even though they have the same name. The dotted notation allows us to differentiate between them.

Most importantly, notice that we do not explicitly call the __init__ method but pass the arguments in the parentheses following the class name when creating a new instance of the class. This is the special significance of this method.


Sunday, July 3, 2011

Exception Handling

Error reporting and processing through exceptions is one of Python’s key features. In Python a programmer can raise an exception at any point in a program. When the exception is raised, program execution is interrupted as the interpreter searches back up the stack to find a context with an exception handler.

Lets start with a simple program.

>>> a=6
>>> b=0
>>> c=a/b

Python "crashes" on divide by zero.

Traceback (most recent call last):
File "", line 1, in
ZeroDivisionError: integer division or modulo by zero

Now let's try that with exception handling:

>>> a=6
>>> b=0
>>> try:
... print " a = ",a
... print " b = ",b
... c=a/b
... print " c = ",c
... except:
... print " division failed !!!"
... c=0
... print " c default to ",c
... else:
... print "division went very well"
...
This time the program will not crash, we will get an error message printed instead. Our program will continue to execute.

Our output looks like this:

a = 6
b = 0
division failed !!!
c default to 0

The statements in the try: block are attempted.The first failure jumps to the except: block If nothing in the try block fails, the program jumps to the else: block. The 1st two print statements execute, but then the try block fails, so - print 'c=',c - does not. The except block executes.The else block does not execute.

Monday, June 27, 2011

Python Generators

When we write a program it mat contain a series of named blocks. Each of those performs a single logical action. Named blocks are usually performed one after another as a sequence of statements from within another block.

In this example, the pow2 function is performed completely before the for loop is run.

The list called "powers" is constructed completely and stored in memory while the for loop is run. That's not a problem in this case with a list of ten values, but it could be a problem if the list was to contain a billion values.

def pow2(upto):
powers = []
sat = 1
spwr = 1
while spwr <= upto:
powers.append(sat)
sat *= 2
spwr += 1
return powers

def main():
for w in pow2(10):
print w
main()


Python provides an alternative way.i.e. Generator Functions. A generator function is one that does NOT run to completion when it's first called - instead, it only runs until it has a value available to return.

A generator function is any function which uses the yield statement.

When the for loop asks for the next element the generator starts or continues function execution at the place it left off. It runs until it reaches a yield statement. The function call is suspended at the yield statement. The generator stores the function call state and returns the given element.

Here's the program provided above, modified to use a generator.

def pow2(upto):
sat=1
spwr=1
while spwr<=upto:
yield sat
sat*=2
spwr+=1

def main():
for w in pow2(10):
print w
main()

Operation is exactly the same as the example above ... but there is NOT an intermediate list produced.Generators provide a very neat way of providing data as required on applications that potentially use huge intermediate lists.


Saturday, June 25, 2011

List comprehensions

Python supports a concept called "list comprehensions". It can be used to construct lists in a very easy way.

In mathematics we can describe lists this way:

S = {x² : x in {0 ... 9}}
V = (1, 2, 4, 8, ..., 2¹²)
M = {x | x in S and x even}

In Python we can do this as::

>>> S = [x**2 for x in range(10)]
>>> V = [2**i for i in range(13)]
>>> M = [x for x in S if x % 2 == 0]

Let's see the result:

>>> print S
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>>
print V
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096]
>>>
print M
[0, 4, 16, 36, 64]

More examples:
>>> [(x, x**2) for x in vec]
[(2, 4), (4, 16), (6, 36)]
>>> vec1 = [2, 4, 6]
>>> vec2 = [4, 3, -9]
>>> [x*y for x in vec1 for y in vec2]
[8, 6, -18, 16, 12, -36, 24, 18, -54]
>>> [x+y for x in vec1 for y in vec2]
[6, 5, -7, 8, 7, -5, 10, 9, -3]
>>> [vec1[i]*vec2[i] for i in range(len(vec1))]
[8, 12, -54]
any type of elements, including strings, nested lists and functions. We can even mix different types within a list.

list comprehensions work for any type of elements

>>> words='You can nest list comprehensions inside of each other'.split()
>>> words
['You', 'can', 'nest', 'list', 'comprehensions', 'inside', 'of', 'each', 'other']
>>> new=[[w.upper(), w.lower(), len(w)] for w in words]
>>> for i in new:
... print i
...
['YOU', 'you', 3]
['CAN', 'can', 3]
['NEST', 'nest', 4]
['LIST', 'list', 4]
['COMPREHENSIONS', 'comprehensions', 14]
['INSIDE', 'inside', 6]
['OF', 'of', 2]
['EACH', 'each', 4]
['OTHER', 'other', 5]
>>>



Tuesday, June 21, 2011

Lambda, map, filter and reduce

lambda

Python supports functions that are not bound to a name.we can use a construct called "lambda" for this. It can be used with functions like filter(), map() and reduce().

The general syntax of a lambda function is quite simple:
lambda argument_list: expression

For example:

>>> value=lambda x:x*x
>>> value(7)
49

More than one arguments are supported and these are separated by comma.The expression is an arithmetic expression using these arguments.

For example:

>>> value=lambda x,y:x/y
>>> value(47,5)
9

map()

map() is a function with two arguments:
r = map(func, seq)
The first argument func is the name of a function.Second argument is a sequence like list.
map() applies the function func to all the elements of the sequence seq. It returns a new list with the elements changed by func.

>>> value=[1,4,7,5,8]
>>> def sqrt(x):
... return x*x
>>> map(sqrt,value)
[1, 16, 49, 25, 64]

The advantage of the lambda operator can be seen when it is used in combination with the map() function.

>>> a=[5,6,4,8]
>>> b=[4,3,2,7]
>>> map(lambda x,y:x*y, a,b)
[20, 18, 8, 56]


filter()

This function is used to filter out all the elements of a list.

filter(fun, list)

The first argument, fun needs a function which returns a Boolean value, i.e. either True or False. This function will be applied to every element of the list l. If the fun returns true for a particular element of the list,that will be included in the result list.

>>> a=[4,5,76,34,7,32,45,89]
>>> result = filter(lambda x: x % 2, a)
>>> print result
[5, 7, 45, 89]

reduce()

The function reduce(func, seq) continually applies the function func() to the sequence seq. It returns a single value.

Suppose seq = [ s1, s2, s3, ... , sn ].When we call reduce(func, seq) , first 2 elements of the seq will be applied to func at first.In the next step func will be applied on the previous result and the third element of the list.It will continue like this until just one element is left and return this element as the result of reduce() .

>>> reduce(lambda x,y:x+y,[34,78,435,23,78])
648