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.