Thursday 29 December 2011

Sending email via Gmail in Django

While I was learning how to use django-registration application, I need to know that how to send an email for the user to activate the registration.
During this post I want to show how to test it using shell, 
  1. Create a project, django-admin.py startproject pjtname
  2. Edit settings.py with code below:
         EMAIL_USE_TLS =True
         EMAIL_HOST = 'smtp.gmail.com'
         EMAIL_HOST_USER = 'youremail@gmail.com'
         EMAIL_HOST_PASSWORD = 'your password'
         EMAIL_PORT = 587
     3. Run interactive mode, python manage.py shell
     4. Import the EmailMessage module,
         from django.core.mail import EmailMessage
     5. Send the email,
         email = EmailMessage ('Subject', 'Body', to=['receiver email id'])
         email.send()

Thursday 22 December 2011

Asynchronous Socket Programming in Python

How to transfer data from one client to another through a server? The solution is very easy using the select call supported in sockets.

To understand the benefit of select call in sockets, one should understand asynchronous socket programming. Assume a case where many clients connect to a server and send data for processing concurrently, then the server has to handle the clients asynchronously.

In synchronous socket programming, the server processes each client sequentially, in this case when it waits for a response/data from a client using the recv call, it blocks or in other words the recv call cannot return until there is some data received from the socket, in a real time scenario, this way of handling clients is inefficient in the sense that all other connected clients need to wait till the server completes processing the current one.

Therefore one needs a more elegant way to asynchronously handle client requests or the ability to read, write from multiple sockets whenever they are ready to be read or written, which is where the select call comes handy.

To explain the use of select system call, I will illustrate a TCP/IP chat Client server program, where the functionalities of the server and the client program were mentioned below.


TCP/IP Chat Server:

1. Accepts connection from multiple clients
2. Use select call to get the list of available sockets which are ready to be read.
3. Whenever a client connects, the server notifies all other connected clients of this new connection, in the same way the server notifies all when a client quits or that client connection is lost.
4. The server broadcasts data sent by a client to all other connected clients.

TCP/IP Chat Client:

1. Connects to the server and starts two threads, one to process received data and one for getting data input to be sent to other connected clients through the server.
2. When the client quits (using q or Q) or the server is suddenly down (handle the worst case scenario), the socket is closed and the process exits.
3. Whenever any thread closes the socket connection, it interrupts the main program using the thread.interrupt_main() call, then the main exits.

The syntax used for the select call is as follows

read_sockets,write_sockets,error_sockets = select.select(CONNECTION_LIST,[],[])

The select call returns three lists, the list of sockets which are ready to be read, written and those which caused an error, since we are interested only in the list of sockets which are ready to be read, we use only a single select input parameter.


The client and server Chat program were implemented in python for the ease of understanding. Try to see how the chat client/server works by launching multiple clients in different windows connected to the chat server.

Server.py
# The server accepts connection from multiple clients and
# broadcasts data sent by a client to all other clients
# which are online (connection active with server)

import socket
import select
import string

def broadcast_data (sock, message):
    """Send broadcast message to all clients other than the
       server socket and the client socket from which the data is received."""
    
    for socket in CONNECTION_LIST:
        if socket != server_socket and socket != sock:            
            socket.send(message)

if __name__ == "__main__":

    # List to keep track of socket descriptors
    CONNECTION_LIST=[]

    # Do basic steps for server like create, bind and listening on the socket
    
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(("127.0.0.1", 5000))
    server_socket.listen(10)

    # Add server socket to the list of readable connections
    CONNECTION_LIST.append(server_socket)

    print "TCP/IP Chat server process started."

    while 1:
        # Get the list sockets which are ready to be read through select
        read_sockets,write_sockets,error_sockets = select.select(CONNECTION_LIST,[],[])

        for sock in read_sockets:

            if sock == server_socket:
                # Handle the case in which there is a new connection recieved
                # through server_socket
                sockfd, addr = server_socket.accept()
                CONNECTION_LIST.append(sockfd)
                print "Client (%s, %s) connected" % addr
                broadcast_data(sockfd, "Client (%s, %s) connected" % addr)

            else:
                # Data recieved from client, process it
                try:
                    #In Windows, sometimes when a TCP program closes abruptly,
                    # a "Connection reset by peer" exception will be thrown
                    data = sock.recv(4096)
                except:
                    broadcast_data(sock, "Client (%s, %s) is offline" % addr)
                    print "Client (%s, %s) is offline" % addr
                    sock.close()
                    CONNECTION_LIST.remove(sock)
                    continue

                if data:
                    # The client sends some valid data, process it
                    if data == "q" or data == "Q":
                        broadcast_data(sock, "Client (%s, %s) quits" % addr)
                        print "Client (%s, %s) quits" % addr
                        sock.close()
                        CONNECTION_LIST.remove(sock)
                    else:
                        broadcast_data(sock, data)                       
                
    server_socket.close()    

client.py
# The client program connects to server and sends data to other connected 
# clients through the server
import socket
import thread
import sys

def recv_data():
    "Receive data from other clients connected to server"
    while 1:
        try:
            recv_data = client_socket.recv(4096)            
        except:
            #Handle the case when server process terminates
            print "Server closed connection, thread exiting."
            thread.interrupt_main()
            break
        if not recv_data:
                # Recv with no data, server closed connection
                print "Server closed connection, thread exiting."
                thread.interrupt_main()
                break
        else:
                print "Received data: ", recv_data

def send_data():
    "Send data from other clients connected to server"
    while 1:
        send_data = str(raw_input("Enter data to send (q or Q to quit):"))
        if send_data == "q" or send_data == "Q":
            client_socket.send(send_data)
            thread.interrupt_main()
            break
        else:
            client_socket.send(send_data)
        
if __name__ == "__main__":

    print "*******TCP/IP Chat client program********"
    print "Connecting to server at 127.0.0.1:5000"

    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect(('127.0.0.1', 5000))

    print "Connected to server at 127.0.0.1:5000"

    thread.start_new_thread(recv_data,())
    thread.start_new_thread(send_data,())

    try:
        while 1:
            continue
    except:
        print "Client program quits...."
        client_socket.close()       



Sunday 4 December 2011

How to strip of mulitiple white spaces.

During this post, I want to share some different solutions for stripping multiple white spaces in the  sentence.
We need to strip the multiple spaces betweens the words. look the following solution. 

Example:
>>> str='Multiple      white  spaces'
>>> for i in str.split():
...     print i,
... 
Multiple white spaces
you can strip off trailing and leading whitespaces using strip(). So there's no need for lstrip,rstrip
Example:
>>> str='    multiple white     spaces    '
>>> str.strip()
'multiple white     spaces'

If you know the number of multiple white spaces in the middle, example, 2 white spaces, you can use replace() , example for 2 white spaces:
Example:
>>> str='How  to strip    multiple  white  spaces'
>>> str.replace("  "," ")
'How to strip  multiple white spaces'
Example for stripping multiple white spaces :
>>> str='How  to strip    multiple  white  spaces'
>>> ' '.join(str.split())
'How to strip multiple white spaces'

Saturday 3 December 2011

__repr__ in python

_repr__ is used to print a human readable presentation of an object. In this case it prints the class name and some other attributes. A simple example:
>>> class point:
...     def __init__(self,x,y):
...             self.x,self.y=x,y
...     def __repr__(self):
...             return 'point(x=%s, y=%s)' %(self.x,self.y)
... 
>>> p=point(1,2)
>>> p
point(x=1, y=2)

String reverse in Python

During this post I want share an interesting string reverse solution in python. Here is the question.
Write a simple program that reads a line from the keyboard and outputs the same line where every word is reversed. A word is defined as a continuous sequence of alphanumeric characters or hyphen (‘-’). For instance, if the input is
“We are at Ignite Solutions!”
the output should be
“eW era ta etingI snoituloS!”

At first, I just tried with the following simple code,
    print"Enter the string:"
    str1=raw_input()
    print (' '.join((str1[::-1]).split(' ')[::-1])) 
It prints the outputs like, eW era ta etingI !snoituloS. Is it correct??
At first look we thought its a correct answer, but actually it is  wrong. Can you got the problem?
The real problem is in the position of exclamation(!).

I have found one new solution for this problem, please listen here.
    str1=raw_input("Enter the string: ")
    #re.sub() used to find each word and reverse it
    print re.sub(r'[-\w]+', lambda w:w.group()[::-1],str1)
It prints the output like this, eW era ta etingI snoituloS!

os.path.walk python example

Last week, I was interviewed by ignite solution recruitment team, I really enjoyed every part of it. During the interview process, I was needed to attend an online test. There are only three more questions on the test. I want to share one of the interesting question on the test with this blog post. Here is the question,

Write a program that accepts a string on the command line and prints out the list of files within a folder (or subfolders) that have the string within them.

Solution:
import os,re,sys
def fun(arg, dirname, fnmes):
    out_list = []
    for fname in fnmes:
        filepath = os.path.join(dirname,fname)
        if os.path.isfile(filepath):
            fp = open(filepath ,'r')
            text = fp.read()
            fp.close()
            if re.search(arg,text):
                # print full path. Calling os.path.basename will
                # give us just the name.
                print filepath

def main():
    strg=sys.argv[1]
    os.path.walk('.', fun, strg)

if __name__=='__main__':
    main()
Here is a simple os.path.walk() example which walks your directory tree and returns the list of file names that contains the given string.

Tuesday 29 November 2011

Find the Union and Intersection of two lists in python

Here are three functions using sets to remove duplicate entries from a list, find the intersection of two lists, and find the union of two lists. Note, sets were introduced in Python 2.4, so Python 2.4 or later is required.
def unique(a):
    """ return the list with duplicate elements removed """
    return list(set(a))

def intersect(a, b):
    """ return the intersection of two lists """
    return list(set(a) & set(b))

def union(a, b):
    """ return the union of two lists """
    return list(set(a) | set(b))

if __name__ == "__main__":
    a = [1,2,3,4,3,2,1,0,9,8,7,6,5,4,3,1]
    b = [19,18,17,12,1,4,5,6,13,14,15,13,16,20]
    print unique(a)
    print unique(b)
    print intersect(a, b)
    print union(a, b)

Output
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 4, 5, 6, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[1, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 16, 17, 18, 19, 20] 

For more information on Python sets, see the Library Reference.


Monday 7 November 2011

AVL Tree Implementation in C

An AVL tree is a self-balancing binary search tree. It was invented by G.M. Adelson-Velski and E.M. Landis. In an AVL tree, heights of the two paired subtrees of any node differ by at most one and maintain an O(logn) search time. An AVL tree has the following properties:
     1. Every sub-tree is an AVL tree.
     2. The sub-trees of every node differ in height by at most one.
The balance factor of a node is the height of its left subtree minus the height of its right subtree (sometimes opposite) and a node with balance factor 1, 0, or −1 is considered balanced. A node with any other balance factor is considered unbalanced and requires rebalancing the tree. The balance factor is either stored directly at each node or computed from the heights of the subtrees. The following is an example for a balanced tree.


Balance factor of root node = height of left sub-tree - height of right sub-tree. Here, "4" is the root node. Its balance factor =0.

The code for defining each node is,

struct avl_node {
    int data;
    struct avl_node *left;
    struct avl_node *right;
};

The code for finding the balance factor is,

int find_height(struct avl_node *node)
{
    int height=0;
    if (node !=NULL){
        int left_height= find_height(node ->left);
        int right_height= find_height(node -> right);
        int max=(left_height > right_height) ? left_height : right_height;
        height = 1+ max;
    }
    return height;
}

int get_diff(struct avl_node *node)
{
    int left_height=find_height(node -> left);
    int right_height=find_height(node -> right);
    int b_factor= left_height - right_height;
    return b_factor;
}  


Operations on AVL Tree
The basic operation that carried out on an unbalanced binary search tree is the tree rotations. It helps to restore the height balance of the sub-trees.
Insertion
After inserting a node, it is necessary to check whether  the trees satisfies the rules of AVL. For each node checked, if the balance factor remains −1, 0, or +1 then no rotations are necessary. However, if the balance factor becomes ±2 then the subtree rooted at this node is unbalanced. Rotations are necessary in this case.
 There are four cases which need to be considered. Let P be the root of the unbalanced subtree, with R and L denoting the right and left children of P respectively.

1. Right-Right case 

If the balance factor of P is -2 then the right subtree outweights the left subtree of the given node, and the balance factor of the right child (R) must be checked. If the balance factor of R is -1, a single left rotation (with P as the root) is needed.
The code for Right-Right rotation is ,

struct avl_node* right_right_rotation(struct avl_node *parent)
{
    struct avl_node *node1;
    node1=parent ->right;
    parent->right = node1 -> left;
    node1 -> left= parent;
    return node1;
}

2. Right-Left case 

If the balance factor of P is -2 then the right subtree outweights the left subtree of the given node, and the balance factor of the right child (R) must be checked.
If the balance factor of R is +1, two different rotations are needed. The first rotation is a right rotation with R as the root. The second is the left rotation with P as the root (Right-Left case).
The code for Right-Left rotation is,

struct avl_node* right_left_rotation(struct avl_node *parent)
{
    struct avl_node *node1;
    node1=parent -> right;
    parent->right = left_left_rotation(node1);
    return right_right_rotation(parent);
}

3. Left-Left case

If the balance factor of P is +2, then the left subtree outweighs the right subtree of the given node, and the balance factor of the left child (L) must be checked. 
If the balance factor of L is +1, a single right rotation (with P as the root) is needed.
Code for Left-Left rotation is,

struct avl_node* left_left_rotation(struct avl_node *parent)
{
    struct avl_node *node1;
    node1 = parent -> left;
    parent -> left = node1 -> right;
    node1 -> right = parent;
    return node1;
}

4. Left-Right case

If the balance factor of P is +2, then the left subtree outweighs the right subtree of the given node, and the balance factor of the left child (L) must be checked. If the balance factor of L is -1, two different rotations are needed. The first rotation is a left rotation with L as the root. The second is a right rotation with P as the root.
Code for Left-Right rotation is,

struct avl_node* left_right_rotation(struct avl_node *parent)
{
    struct avl_node *node1;
    node1= parent -> left;
    parent-> left = right_right_rotation(node1);
    return left_left_rotation(parent);
}
The following figure shows the above four operations,


The following functions check the balance factor of the parent nodes, and will decide the necessary rotations,


struct avl_node* balancing(struct avl_node *node)
{
    int b_f= get_diff(node);
    if (b_f >1) {
        if (get_diff(node->left) >0)
            node=left_left_rotation(node);
        else
            node=left_right_rotation(node);
    }
    else if(b_f < -1) {
        if(get_diff(node ->right) >0)
            node=right_left_rotation(node);
        else
            node=right_right_rotation(node);
    }
    return node;
}       


struct avl_node* insert(struct avl_node *root,int val)
{
    if (root==NULL) {
        root = (struct avl_node*) malloc(sizeof(struct avl_node));
        root -> data = val;
        root -> left = NULL;
        root -> right = NULL;
        return root;
    }
    else if (val < root->data) {
        root->left = insert(root->left, val);
        root=balancing(root);
    }
    else if (val > root->data) {
        root->right = insert(root->right, val);
        root=balancing(root);
    }
    return root;
}

Tree traversal

Three types of traversals are Inorder traversal, Preorder traversal and Postorder traversal.
Inorder traversal
To traverse a non-empty binary tree in inorder , perform the following operations recursively at each node:
  1. Traverse the left subtree.
  2. Visit the root.
  3. Traverse the right subtree.
Code for Inorder traversal is,

void inorder(struct avl_node *tree)
{
    if(tree == NULL)
        return;
    else {
         inorder(tree -> left);
         printf("%d\t",tree ->data);
         inorder(tree ->right);
    }
}

2. preorder traversal

To traverse a non-empty binary tree in preorder, perform the following operations recursively at each node, starting with the root node:
  1. Visit the root.
  2. Traverse the left subtree.
  3. Traverse the right subtree.
Code for preorder traversal is,

void preorder(struct avl_node *tree)
{
    if(tree == NULL)
        return;
    else {
        printf("%d\t", tree ->data);
        preorder(tree ->left);
        preorder(tree ->right);
    }
}

3. Postorder traversal

To traverse a non-empty binary tree in postorder, perform the following operations recursively at each node:
  1. Traverse the left subtree.
  2. Traverse the right subtree.
  3. Visit the root.
Code for postorder traversal is,

void postorder(struct avl_node *tree)
{
    if(tree == NULL)
        return;
    else {
        postorder(tree ->left);
        postorder(tree ->right);
        printf("%d\t",tree ->data);
    }
}
 

Monday 8 August 2011

How to create a simple shell script

Shell scripts are short programs that are written in a shell programming language and interpreted by a shell process. A shell is a program that provides the traditional, text-only user interface for Unix-like operating systems. Its primary function is to read commands that are typed into a console or terminal window and then execute (i.e., run) them. The default shell on Linux is the very commonly used and highly versatile bash. 
A feature of bash and other shells used on Unix-like operating systems is that each contains a built-in programming language, referred to as a shell programming language or shell scripting language, which is used to create shell scripts. 
A First Script
The following example provides a useful introduction to creating and using shell scripts. The script clears the monitor screen of all previous lines and then writes the text Good morning, world. on it.
For that open a text editor such as gedit or vi, and type the following three lines exactly as shown on a new, blank page:
#!/bin/bash
clear
echo "Good morning, world."
 
After saving this plain text file, with a file name such as morning or anything else desired, the script is complete and almost ready to run. Scripts are typically run by typing a dot, a forward slash and the file name (with no spaces in between) and then pressing the ENTER key. Thus, for example, if the above script were saved with the name morning, an attempt could be made to execute it by issuing the following command:
./morning
However, the script probably will not run, in which case an error message will appear on the screen such as bash: ./morning: Permission denied. This is because the permissions for the file first have to be set to executable. The problem can easily be solved by using the chmod command with its 755 option (which will allow the file creator to read, write and execute the file) while in the same directory as that in which the file is located as follows:
chmod 755 morning
Now the script is ready to run by typing the following, again while in the same directory, and then pressing the ENTER key:
./morning
Now it display a message on the screen
Good morning, world.
At the same time the script clears all previous lines from the screen.
How it works?
The first of the three lines tells the operating system what shell to use to interpret the script and the location of the shell. The shell is bash, which is located in the /bin directory. Thus the line contains /bin/bash. This instruction is always preceded by a pound sign and an exclamation mark in order to inform the operating system that it is providing the name and location of the shell.
The second line tells the shell to issue the clear command. This is a very simple command that removes all previous commands and output from the console or terminal window in which the command was issued. 
The third line tells the shell to write the phrase Good morning, world. on the screen. It uses the echo command, which instructs the shell to repeat whatever follows it. The quotation marks are not necessary in this case.

Lisp in Python

I already discussed about Lisp in my previous post. I think you got an idea regarding Lisp Programming language. Now I almost completed my project "Design of a Lisp Interpreter with a web front-end". In this post I want to explore the development stages of my Lisp Interpreter.

This Lisp implemented in Python is mostly a translation of the original Lisp. If you have a chance to look at the original Lisp in Lisp, I think you'll agree with me that the Python code is much easier to get your head around. During the study stage of my project I have searched for the existing Lisp interpreters, at that time I had found alot of standalone Lisp interpreters in different languages but I could not found any online lisp. Major advantage of this project is the online accessibility, I mean user can easily use this Lisp interpreter via internet.
    In this project web.py is the framework used for the web interface development. Three major files used in this project are app.py, lisp.py and lispio.py. Here app.py is the web application file, project execution also started from this file. Other two modules (lisp.py and lispio.py) used for lisp interpretation process.
    A language interpreter has two parts.
  1. Parsing :The parsing component takes an input program in the form of a sequence of characters, verifies it according to the syntactic rules of the language, and translates the program into an internal representation.
  2. Execution : The internal representation is then processed according to the semantic rules of the language, thereby carrying out the computation. 
Here is a picture of the interpretation process and an interactive session showing how parse and eval operate on a short program:
In this project parsing and execution are done by the lispio.py and lisp.py module respectively. Now I think you got an idea about what an interpreter actually do in its process stage.

Now we know that basis for both programs and data in Lisp is the S (symbolic) expression. An S expression may be a symbol, a number, or a series of S expressions in parentheses. Here are some examples.
style="text-align: left;">hello
3455
(hello 34 (world 56))
As a web based application here user interaction is done with the browser. User can write their Lisp code in textarea field. After that they need to press the Evaluate button. Now I welcome you all to the code section.
I have already told that lispio.py module used for parsing. It imports other two modules are string and sys. It declare one variable 'inline' and assign it to null.
import string, sys
inline=""
 
This module have been built up on a number of simple functions, such as getSexp(), getToken(), nextChar(), getChar() and putSexp(). Next I want to explain the working of each functions.
First of all getSexp() used to read input from the user.  Here is the function
def getSexp () :       # get an S expression from the user
    "return and discard the next S expression, along with any nested ones in input" 
    a = getToken()
    if   a == "'" : return ['quote', getSexp()]
    elif a != '(' : return a
    a = []
    while 1 :
        b = getSexp()
        if b == ')' : return a
        a.append(b)
getSexp() used to input an S expression from the user and return the equivalent  python list. This function uses getToken function to extract symbols, numbers and special characters from the input provided by the user. It also uses itself to extract nested S expressions. getSexp() uses these tokens to generate the corresponding list in python and return this list back to the app.py module.
def getToken () :
    "return and discard the next symbol, number or special character in input"
    while nextChar() <= ' ': getChar()  # skip whitespace
    a = getChar()
    if a in ['(',')',"'"] : return a
    while nextChar() > ' ' and nextChar() not in ['(',')'] :
        a = a + getChar()
    try    : return float(a)   # if a number, make it a float
    except : return str(a)          # otherwise a string with the symbol name
  
GetToken() uses nextChar() to see if the next character is part of the token it is building and getChar() to grab it.
def nextChar() :
    """return (but don't discard) the next character in the input stream
       get more from the user if needed"""
    global inlin, data
    import app
    data=app.data1 
    if inline == ""
        inlin = data
        if inlin == "" : raise "EOF error"
    return inlin[0:1]

So nextChar() actually has to deal with getting input from the user. This function import app.py module, because user write their expressions on the textarea in web page not on the console. Userinput should assigned to a global variable 'data1' on app.py, nextChar() use these global variable  to access the userinput. This accessed data must be assigned to another global variable 'inline' . nextChar() then take one by one characters from this data. Here is the last function
def getChar() :
    """return and discard the next character in the input stream"""
    global inlin
    c = nextChar()
    inlin = inlin[1:]
    return c
getToken() uses this function to take one by one characters from the global variable inline.
Next we have to show the working of getToken()  and getSexp() a bit.
Note: Here I show the working of functions using terminal. Using existing code we cannot run it on terminal. since I want to show you the output of getToken() and getSexp(), for that i made some changes on the code. You can not run it on terminal, So you just need to look out the output of each functions and realize its working only. I am sure, following example provide more informations regarding the working of getSexp() and getToken() to you.
anoop@anoop-laptop:~$ python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import lispio
>>> while 1:
...     print lispio.getToken()
... 
Lisp>(+ a b)
(
+
a
b
)
Lisp>(car '(a b))
(
car
'
(
a
b
)
)
Lisp>
Here first i gives an S expression (+ a b) to getToken(), after processing this function returns the corresponding tokens. Next i gives another S expression (car ' (a b)) it also returns the corresponding tokens. getToken() returns these tokens back to the getSexp(). Next we have to see how lisp S expressions are converted to Python lists
anoop@anoop-laptop:~$ python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import lispio
>>> while 1:
...     print lispio.getSexp()
... 
Lisp>(cdr '(a b))
['cdr', ['quote', ['a', 'b']]]
Lisp>(= 5 6)
['=', 5.0, 6.0]
Lisp>
getSexp() returns the corresponding list of S expressions. Above examples shows all working of getToken() and getSexp(). 
putSexp() is also included in this module. The main purpose of this function is to provide result back in the proper manner. Here is the function
def putSexp (s):
    "return string form of an S expression"
    if type(s) == type([]) :
        if 0 and len(s) and s[0] == 'quote' : return "'" + putSexp(s[1:])
        else : return '(' + string.join(map(putSexp,s)) + ')'
    else : return str(s) 
You can download the full code of lispio.py from here
lisp.py 

The main functions in lisp.py are eval and apply. Each is a set of if/elif/else statements. The other functions, pairlis, assoc, evcon, and evlis are just auxillary functions. You will notice that they are tail recursive.
Tail Recursion
We should talk about tail recursion a bit. It is used in our python code although sometimes we could used a for or while loop instead. However if you want to create Lisp functions then you must use tail recursion because we are not providing any other means of iteration. 
Lets look at an example. A call to assoc(x, alist) walks down the name/value pairs in the alist until it finds a pair whose first element matches x. Then it returns the second element (the value). Here is how to write assoc using a for loop.
def assoc (x, alist) :
     for pair in alist :
         if pair[0] == x : return pair[1]
     raise "Lisp error"
With tail recursion the function look like this
def assoc (x, alist) :
     if not alist : raise "Lisp error"
     elif alist[0][0] == x : return alist[0][1]
     else : return assoc(x,alist[1:])

There are 3 possibilities. If the first pair on the alist is the one we want, return its 2nd element. If there is no 1st element, raise an error. Or simply search the rest of the alist recursively. Eventually either the right pair will be found or an error will be raised.
After getting the result back from the getSexp(), app.py module calls the eval() of lisp.py. An important term used in this module is the 'alist' (association list). It is permanently set to the global variable. It is used to hold the value of variables in alist, so we can hold many variables and their values in list, also we can access these values in various situation during the execution process. 
 
Functions in lisp.py:
eval() and apply() are the main functions in this module. First of all I want to discuss other simple functions used here, then only I can explain this main functions efficiently.
pairlis()
def pairlis (x,y,alist) :
    """push symbols in x along with respective values in y onto the alist"""
    if not x : return alist
    else : return [[x[0],y[0]]] + pairlis(x[1:],y[1:],alist)
pairlis() adds pairs to the alist (returning an expanded list). When we define a variable or a function ( I will explain it latter) eval() calls the pairlis(). Arguments (x, y, alist), here x and y are two list's and 'alist' is a global variable. After processing return alist back to the calling function.

assoc()
def assoc (x, alist) :
    "look up x on the alist and return its value"
    if   not alist        : raise "Lisp error"
    elif alist[0][0] == x : return alist[0][1]
    else                  : return assoc(x,alist[1:])
I have already explained it above this document. This function used to find the value of variable x in the given alist.

Power() 
def power(x,y):
    if y==0:
        return 1
    elif x==0:
        return 0
    elif y==1:
        return x
    elif y%2==0:
        var_even=power(x,y/2)
        return var_even*var_even
    else:
        var_odd=power(x,(y-1)/2)   
        return x*var_odd*var_odd
This function used to find the power of a number. I think all of you are familiar  with this code.

ifcon()
def ifcon(s,alist):
    if eval(s[0],alist) == 't':
        return eval(s[1],alist)
    else:
        return eval(s[2],alist)
This function used to implement the if/else condition. It recursively calls the eval() to check the condition is true or false.

evcon() and evlis()
def evcon (c, alist) :
    "evaluate cond. Note just the pairs passed in c"
    if   len(c) == 0           : return []
    elif eval (c[0][0], alist) : return eval (c[0][1],alist)
    else                       : return evcon(c[1:],  alist)

def evlis (l, alist) :
    "evaluate all elements in a list, returning list of the values"
    if not l : return []
    else     : return [eval(l[0], alist)] + evlis(l[1:], alist)
 

evcon() is special for handling condition expressions. evlis() similar to the python map(). It evaluates each item in the list passed and returns a list of the values.
Two other simple functions are,
def isSymbol(x) : return type(x) == type('')  
def isNumber(x) : return type(x) == type(0.0)  
These functions return boolean values.
Important functions:
eval()
def eval (exp, alist) :
    "evaluate an S expression using the alist"
    global Alist
    if debug : print "--Eval---", sxp(exp), " alist=",sxp(alist)
    if   exp == 't'     : return 't'      # true evaluates to itself
    elif exp == 'nil'   : return 'nil'       # symbol nil same as a null list
    elif exp == 'alist' : return Alist    # special command to examine alist
    elif isNumber(exp)    : return exp      # numbers eval to themselves
    elif isSymbol(exp)    : return assoc(exp,alist)  # look up variables
    else :               # check for special forms
        if   exp[0] == 'quote' : return exp[1]
        elif exp[0] == 'def' : # special extra. Let user define functions that stick
            alist = Alist = pairlis([exp[1]],[exp[2]],alist)
            return exp[1]         # return function name
    elif exp[0] == 'if'   : return ifcon(exp[1:],alist)
        elif exp[0] == 'cond'  : return evcon(exp[1:], alist)
        else :
            x = evlis(exp[1:], alist)
            return apply (exp[0],x , alist) 
After getting result (list) from the getSexp(), calls the eval(). List and alist are the arguments passed to it.


def eval (exp, alist) :
'exp' contain list representation of S expression and 'alist' means global variable.

if   exp == 't'     : return 't'      # true evaluates to itself
    elif exp == 'nil'   : return 'nil'       # symbol nil same as a null list
    elif exp == 'alist' : return Alist    # special command to examine alist
If the given expression is 't', 'nil' and 'alist' means the function returns 't', 'nil' and 'alist' respectively. 't' means true, 'nil' means false and 'alist' means the current values in the alist. 

elif isNumber(exp)    : return exp      # numbers eval to themselves
elif isSymbol(exp)    : return assoc(exp,alist)  # look up variables
If the given expression is a number, then function returns the same number. If it is a symbol, then call assoc() to retrieve the current value of that symbol and return that value back to calling function.

else :               # check for special forms
        if   exp[0] == 'quote' : return exp[1]
        elif exp[0] == 'def' :    # special extra. Let user define functions that stick
            alist = Alist = pairlis([exp[1]],[exp[2]],alist)
            return exp[1]         # return function name
        elif exp[0] == 'if'   : return ifcon(exp[1:],alist)
        elif exp[0] == 'cond'  : return evcon(exp[1:], alist)
        else :
            x = evlis(exp[1:], alist)
            return apply (exp[0],x , alist)
If exp[0] contain 'quote' then it returns the content of exp[1]. For example

(quote charlie)    yields  charlie
(quote (a b c))     yields (a b c)  



'def' allows us to set variables or define functions by adding a pair on to the global Alist. Also returns exp[1]. For example
Note: Here I shows the examples using terminal, using existing code we canot run it on terminal. Just try to realize its working.
Lisp>(def a 7)       # here assign 7 to variable 'a'
a
Lisp>a         # display the value of a
7.0
Lisp>(def a (lambda (x) (b)))    # Define a function 'a'
a

If exp[0] contain 'if' , then calls the ifcon() to evaluate the condition to return result. For example.
(if (> 4 5) (+ 4 3)(- 6 7))    It means if 4>5 then 4+3 else 6-7. here function return -1.
(if (< 4 5) (+ 4 3)(- 6 7))    function return 7

If all these conditions are false, then eval() calls the apply().
Apply()

def apply (fn,args,alist) :
    "apply a function fn to its arguments in args"
    if debug : print "--Apply--", sxp(fn), " Args=",sxp(args), " alist=",sxp(alist)
    if isSymbol(fn) :   # name of a function
        if   fn == 'atom' : return [[],'t'][type(args[0]) != type([])]
        elif fn == 'car'  : return args[0][0]   # first element of 1st arg
        elif fn == 'cdr'  : return args[0][1:]  # tail of 1st arg
        elif fn == '+'    : return args[0]+args[1]
        elif fn == '*'    : return args[0]*args[1]
        elif fn == '-'    : return args[0]-args[1]
        elif fn == '/'    : return args[0]/args[1]
        elif fn == '^'    : return power(args[0],args[1])
        elif fn == '<'   : return ['nil','t'][args[0] < args[1]]
        elif fn == '<='   : return ['nil','t'][args[0] <= args[1]]
        elif fn == '>'   : return ['nil','t'][args[0] > args[1]]
        elif fn == '>='   : return ['nil','t'][args[0] >= args[1]]
        elif fn == '='   : return ['nil','t'][args[0] == args[1]]
        elif fn == 'not'  : return [[],'t'][args[0] == []]
        elif fn == 'cons' :
            if type(args[1]) != type([]) : args[1] = [args[1]]
            return [args[0]] + args[1]
        else : return (apply(eval(fn,alist),args,alist))
    elif fn[0] == 'lambda' : # a function definition
        return eval (fn[2], pairlis(fn[1],args,alist))
    else                   : raise "Lisp error"
Arguments passed to it is the function name, arguments and alist. Based on the function name perform arithmetic functions such as addition, subraction, multiplication, division. Also perform <, <=, >, >=, = operations. We can also find the power of a number.
Examples:
(+ 1 (+ 2 (+ 3 4))) is the same as (+ 1 (+ 2 7)) is the same as (+ 1 9) which yields 10, 
(+ (+ 1 2) (+ 3 4)) is the same as (+ 3 7) which yields 10, 
(- 10 7) yields 3, 
(- 7 10) yields 0, 
(+ (* 3 4) (* 5 6)) is the same as (+ 12 30) which yields 42, 
(^ 2 10) yields 1024, 
(< (* 10 10) 101) is the same as (< 100 101) which yields true, 
(= (* 10 10) 101) is the same as (= 100 101) which yields false.


elif fn == 'car'  : return args[0][0]   # first element of 1st arg
elif fn == 'cdr'  : return args[0][1:]  # tail of 1st arg
If the function name is 'car', then it returns the first element of the first argument. If the function name is 'cdr', then it returns the tail of the first argument. For example
(car ' (a b c)) yields a, 
(cdr ' (a b c)) yields (b c), 
(car ' ((a) (b) (c))) yields (a), 
(cdr ' ((a) (b) (c))) yields ((b) (c)), 
(car ' (a)) yields a, 
(cdr ' (a)) yields (), 

elif fn == 'cons' : 
if type(args[1]) != type([]) : args[1] = [args[1]]
            return [args[0]] + args[1] 

If the function name is 'cons', then it combines the arguments to make a new list. For example.
(cons ' a ' (b c)) yields (a b c), 
(cons ' (a) ' ((b) (c))) yields ((a) (b) (c)), 
(cons ' a ' ()) yields (a), 

elif fn[0] == 'lambda' : # a function definition
        return eval (fn[2], pairlis(fn[1],args,alist))
Another special form used for user defining functions. It is easiest to provide an example and explain it. The following is a function definition to square a number.

(lambda (x) (* x x))
The symbol lambda introduces this form. It is followed by an S expression with the function parameters, and an S expression which is the body of the function. It may be applied to arguments just like any primitive function.
((lambda (x) (* x x)) 2)     evaluates to 4.
I added one special form not in the original code. (def x y) will bind a name x to an S expression y. The alist is saved in a global variable when these definitions are made and therefore remain for later evaluations. This form is especially useful to bind names to functions. For example,
(def square (lambda (x) (* x x)))
(square 4)                   evaluates to 16
Here is a definition for the function length which returns the number of S expressions in a list. I used an indentation style that matches left and right parens either on the same line or vertically.
(def length
   (lambda (x)
      (cond
         ((not x) 0)
         (   t   (+ 1 (length (cdr x))))
      )
   )
)
(length '(a b c d e f g))   yields 7
This function is another example of tail recursion. It counts one for the first element of a list and adds that to the length of the rest of the list. An empty list returns zero.

We can define a function , that find the factorial of a number.
(def fact (lambda (n) (if (< n 1) 1 (* n (fact (- n 1))))))
(fact 9)
             Evaluates to  362880
(def fact (lambda (n) (if (<= n 1) 1 (* n (fact (- n 1))))))
(fact -5)    Evaluates to 1


This is the structure of my project. I think you are satisfied with this explanation. You can download the lisp.py module from here