Unit testing in Python

Unit testing

Unit testing is an approach to test the source code as individual units and to determine whether they are working properly.Unit testing is mainly done by program developers to make sure that the code is fit to use.

There are several advantages for unit testing.

First of all we can quote the obvious reason that it helps to identify problems early.
Unit testing provides another advantage that it will allow us to modify the program easily. That means if we modify the program then we can run unit testing again on the remaining parts to check whether they work properly.
Unit testing makes Integration testing easier. Another advantage is that unit testing files will act as documentation. We can easily understand the functionality of the program by referring these files.


Unit testing in Python

In object oriented programming a testing unit may be a class or a method. Even though python ain't  full object oriented Unit testing follows the object oriented align.

From Python 2.1 we can find the module unittest for Unit testing.
Normally we write the testing code before we write our program code.

Here i am trying to shed some light on unit testing by using a small sqrteg.py program.
The program is simple.It contains two functions named as sqIt (means square It) for finding the square and sqrtIt (meaning square root It) to find the square root of a given number.


Lets start by creating a unit test file sqrtegtest.py for this sqrteg.py program before we write any code in it.

First of all i provided some test data in sqrtegtest.py using which the test file checks the conditions.


 class TestData(unittest.TestCase):  
      TestData=( (0,0),  
           (1,1),  
             (2,4),  
           (3,9),  
           (8.5,72.25),  
           (10,100),  
           (55.55,3085.8025),  
           (100,10000) )  

Then we create two methods to check the working of known input with known result.


      def testSqItTestData(self):  
           """sqIt give known result with known output"""  
           for integer,square in self.TestData:  
                result=sqrteg.sqIt(integer)  
                self.assertEqual(square, result)  
      def testSqrtItTestData(self):  
           """sqrtIt give known result with known output"""  
           for integer,square in self.TestData:  
                result=sqrteg.sqrtIt(square)  
                self.assertEqual(integer, result)  

Then we focus on the bad inputs that can be given to the sqIt() and sqrtIt() functions (still not created).

Lets say string input is bad to these programs.So we have to focus on the fact that these methods take only int or float types.
Also assume that sqrtIt (square root method) takes no negative numbers(Just to simplify it from complex numbers).


 class SqItBadInput(unittest.TestCase):  
      def testSqItInput(self):  
           """sqIt fails for bad input"""  
           self.assertRaises(sqrteg.TypeError, sqrteg.sqrtIt, 'hello')  
 class SqrtItBadInput(unittest.TestCase):  
      def testSqrtItInput(self):  
           """sqrtIt fails for bad input"""  
           self.assertRaises(sqrteg.TypeError, sqrteg.sqrtIt, 'hello')  
      def testNegative(self):  
           self.assertRaises(sqrteg.OutOfRangeError, sqrteg.sqrtIt, -1)  

We pass a sample string 'hello' (of string type) as a bad input. Also for sqrtIt() we pass -1 (a negative number) as OutOfRangeError.

Last but not least we do the sanity check.The following code itself explains what it means.



 class SanityCheck(unittest.TestCase):   
      def testSanity(self):   
           """sqrtIt(sqIt(n))==n for all n"""  
           for integer in range(1, 10000):  
                square=sqrteg.sqIt(integer)  
                result=sqrteg.sqrtIt(square)  
                self.assertEqual(integer, result)  

I took a fair range of numbers and applied both functions back to back to obtain the real one. We will check whether the result value is same as the original one.
So thats it. We finished our small test file for our simple program.

Now we start sqrteg.py
First of all we create Classes for the items we did in test file.
(Here in my test file a TypeError and OutOfRangeError).


 class SqrtegError(Exception): pass   
 class TypeError(SqrtegError):pass  
 class OutOfRangeError(SqrtegError): pass  

Here SqrtegError isn't necessary. We can directly add Exception in both TypeError and OutOfRangeError classes. But this is the standard way we follow.

First we just define the two functions with python reserved word 'pass'.

 def sqIt(n):  
      pass  
 def sqrtIt(n):  
      pass  

When we run sqrtegtest.py we can see six failures.
Then we gradually add the function and then provide checking conditions for bad input and eventually the failures will vanish one by one.

The final sqrteg.py will look like


 class SqrtegError(Exception): pass   
 class TypeError(SqrtegError):pass  
 class OutOfRangeError(SqrtegError): pass  
 def sqIt(n):  
      if type(n)==int or type(n)==float:  
           return n**2            
      else:       
           raise TypeError,"Invalid"  
 def sqrtIt(n):  
      if n<0:  
           raise OutOfRangeError,"No negatives please"  
      if type(n)==int or type(n)==float :  
           return n**.5  
      else:       
           raise TypeError,"Invalid"  


Finally you can see this 'ok' if  it passes the test.




Lot of other options are available in unittest module in python.

To see the sample programs used above, Click here

Paint app with flask

The paint app i made using html 5 canvas and javascript has been modified with a save option and flask is given as the backend.
When each picture is drawn details are stored as a json object. Like while a circle is drawn each detail is stored as a json object and pushed to a list.This list of objects is send to the database(here postgresql) and it is shown in the gallery.
When we click in any name in gallery it will retrieve the picture info from that name in database and will redraw in the canvas.

For example given below is the code for drawing circle in paint app.We added an extra line to store details about the circle on mouseup function.Then it is pushed into the list(here list name is  jsondata).


1:  function circle(){  
2:  canvas.onmousedown=circledown;  
3:  canvas.onmouseup=circleup;  
4:  canvas.onmousemove=circlemove;  
5:  function circledown(e){  
6:   img=context.getImageData(0,0,canvas.width,canvas.height);  
7:   startx=e.x;  
8:   starty=e.y;  
9:   drag3=true;  
10:  }  
11:  function circleup(e){  
12:  jsondata.push({"Type":"circle", "X0":startx,"Y0":starty,"X1":endx,"Y1":endy,"width":context.lineWidth,"color":context.strokeStyle,"fill":f})  
13:  drag3=false;  
14:  }  
15:  function circlemove(e){  
16:  if (drag3){  
17:  context.putImageData(img,0,0);  
18:  endx=e.x;  
19:  endy=e.y;  
20:  context.beginPath();  
21:  context.arc(Math.abs(endx+startx)/2,Math.abs(endy+starty)/2,Math.sqrt(Math.pow(endx-startx,2)+Math.pow(endy-starty,2))/2, 0, Math.PI*2, true);   
22:  context.closePath();  
23:  context.stroke();  
24:  if (f==1){  
25:  context.fill();  
26:  }  
27:  }}}  



In line number 12 the data is stored as a json variable.

Now the following code redraws the circle when the name is selected.


 if (l[i]["Type"]=='circle'){  
 context.beginPath();  
 context.arc(Math.abs(l[i]["X1"]+l[i]["X0"])/2,Math.abs(l[i]["Y1"]+l[i]["Y0"])/2,Math.sqrt(Math.pow(l[i]["X1"]-l[i]["X0"],2)+Math.pow(l[i]["Y1"]-l[i]["Y0"],2))/2, 0, Math.PI*2, true);   
 context.strokeStyle=l[i]['color']  
 context.fillStyle=l[i]['color']  
 context.lineWidth=l[i]['width']  
 if(l[i]['fill']==1){  
 context.fill()  
 }  
 context.stroke();  
 context.closePath();  
 }  


where l is defined as

 l=JSON.parse(imagedata);  

That is the json variable is stored as string in database.We take it back and redraw it by parsifying that data.

By using flask the whole paint app became efficient ,interactive and useful.

Following shows the screen shots from my paint app.




when we click the save button a "saved" alert wil pop up.

Then if we check out the gallery we can see the name of pic in there.




If there are more than one picture ,the names will appear as a list.

Then when we click on that this canvas page will appear.





Click on the load button and the image will be retrieved from database.




And thats how the paint app works.

My app is stored in heroku. You test it by clicking this link.

Click here to see the code in github .

Blog app with flask

Blog app with options for posting,viewing post,and commenting option enabled on each post can be efficiently developed using flask.


So what is flask?
The following definition from http://flask.pocoo.org/ explains it perfectly.

"Flask is a microframework for Python based on Werkzeug, Jinja 2 and good intentions."

Here i used postgresql for the database part. psycopg2 module is widely used in python for the postgresql database handling.I used the same in my app.In the app a sign_in part is provided so that posting is allowed only to the admin. Username for my app is 'admin' and password is'1234'.

If we grab a basic knowledge in flask then it will be easy to grasp the code i wrote for this app.The main modules i used are Flask,render_template,request etc.

For a quick reference i will explain the post_store function in my app.

The HTML part is as given below

 <h4>Post your thoughts here</h4>  
 <form method="post" action="{{ url_for('post_store')}}">  
 <div align="center">  
 <p> Title </p>  
 <input type="text" name="name" style="width: 250px"><br>  
 <textarea name="blogpost" cols="45" rows="15">  
 </textarea><br>  
 <input type="submit" value="Submit" />  
 </div>  
 </form>  

so here you can see form's action part given as '{{ url_for('post_store')}}'.Which means after submitting the form the action is to connect to the post store function in python.I hope you are already aware on "form" tag in html.

Given below is the post_store function written in python.

  
 @app.route('/post',methods=['POST'])  
 def post_store():  
      conn=psycopg2.connect(database='nidhin')  
      c=conn.cursor()  
      c.execute("INSERT INTO blogspot (author,post,day,time) VALUES (%s,%s,%s,%s)",[request.form['name'],request.form['blogpost'],strftime("%d %b %Y ", gmtime()),strftime("%H:%M:%S ", gmtime())])  
      conn.commit()  
      conn.close()  
      return render_template('post.html')  

The first line @app.route('/post',methods=['POST']) indicates that the following function will work if the url is 'some_main_url'/post and the method is POST.
app is connected to the postgresql using psycopg2 and the data is from the form is stored in it.

If you are a beginner and cannot make a word out of the things above, then you should try this Flask mega tutorial by miguelgrinberg.It helped me a lot.

So in this way i tried to test flask by creating a blog app and honestly i am very much satisfied with the outcome.I felt the differnce after getting tired by using conventional commands in python.django is prior to flask i know.But i never tried it.So from my experience flask made my day.If you are reading this you should give it a try.

And i stored my app in heroku.So you can test it by clicking this link.
For the funky version click here.


To see the code click the links below.There are three versions.

version one is blog app built on virtual environment.
version two is blog app built normally.
version three is the blog app with funky theme.






Paint App

Paint app using javascript in HTML 5 canvas

            HTML 5 provides a canvas element using which we can draw shapes on it,colour it etc.
So this is a simple paint app i created using javascript in canvas which provides tools like pencil,line,rectangle,circle,spray,brush etc.

This is how my app looks like in chrome browser.


























Canvas element in html 5 provides the drawing surface.More about canvas can be read from Dive into html 5 book.
The following is an example of canvas declaration.
 <canvas id="canvas" width="650" height="450" style="border:5px solid black; background-color:white;">  
 </canvas>  

Inside the script we have to initialize two variables.
1:  var canvas = document.getElementById("canvas");  
2:  var context=canvas.getContext('2d');  

We have to initialize a variable to access canvas using canvas id and another variable to set the context to 2 dimension as above.

No temporary canvas is used in this app.Instead i used the getImageData() function which captures the canvas as a whole ( ofcourse we have to specify the start and ending points correctly) and used putImageData() to update the canvas with the captured image.

Pencil tool

Pencil tool is implemented by using the basics of line draw in canvas.On a mouse press it will track its movement and on mouse move we will update the x,y coordinates.Also we will draw a small line from previous tracked x,y coordinte to updated x,y coordinate.
Here is the code.
1:  function pencil(){  
2:  canvas.onmousedown=pencildown;  
3:  canvas.onmouseup=pencilup;  
4:  canvas.onmousemove=pencilmove;  
5:  function pencildown(e){  
6:  x=e.x;  
7:  y=e.y;  
8:  draw=true;  
9:  }  
10:  function pencilup(){  
11:  draw=false;  
12:  }  
13:  function pencilmove(event){  
14:  if (draw){  
15:    a =event.x;  
16:    b =event.y;  
17:    context.beginPath();  
18:    context.moveTo(x,y);  
19:    context.lineTo(a,b);  
20:    context.stroke();  
21:    context.closePath();  
22:    x=a;  
23:    y=b;  
24:   }}}  

Line tool

Line tool can be easily implemented.The hard work lies in handling the mouse events.Here on mouse down(or press) we store the starting points to a variable.On mouse move we update the end points of the line using the coordinates from the mouse move  event.
I used the getImageData() on mouse down event.That is, on mouse down event it will take the image of the canvas.And on mouse move it will update the canvas background with that image.
1:  function line(){  
2:  canvas.onmousedown=linedown;  
3:  canvas.onmouseup=lineup;  
4:  canvas.onmousemove=linemove;  
5:  function linedown(e){  
6:   img=context.getImageData(0,0,canvas.width,canvas.height);  
7:   startx=e.x;  
8:   starty=e.y;  
9:   drag1=true;  
10:  }  
11:  function lineup(e){  
12:   drag1=false;  
13:  }  
14:  function linemove(e){  
15:   if (drag1){  
16:   context.putImageData(img,0,0);  
17:   endx=e.x;  
18:   endy=e.y;  
19:   context.beginPath();  
20:   context.moveTo(startx,starty);  
21:   context.lineTo(endx,endy);  
22:   context.stroke();  
23:   context.closePath();  
24:  }}}  


Rectangle tool

Two types of rectangle are there for canvas.Stroke and Fill.So i provide radio buttons to select the type of rectangle(or Circle) we want.If radio button of Fill is checked value of variable fill become 1 and if Border is checked fill value become zero.
Here is the code
1:  function rectangle(){  
2:  canvas.onmousedown=rectdown;  
3:  canvas.onmouseup=rectup;  
4:  canvas.onmousemove=rectmove;  
5:  function rectdown(e){  
6:   img=context.getImageData(0,0,canvas.width,canvas.height);  
7:   startx=e.x;  
8:   starty=e.y;  
9:   drag2=true;  
10:  }  
11:  function rectup(e){  
12:  drag2=false;  
13:  }  
14:  function rectmove(e){  
15:  if (drag2){  
16:  context.putImageData(img,0,0);  
17:  rectw=e.x-startx;  
18:  recth=e.y-starty;  
19:  context.strokeRect(startx,starty,rectw,recth);  
20:  if (f==1){  
21:  context.fillRect(startx,starty,rectw,recth);  
22:  }  
23:  }}}  

Here on mouse press it will store the x,y coordinates as starting point of rectangle.On mouse move event it updates the height and width of the rectangle until mouse up event is performed.If the fill variable is "1" it will overwrite strokeRect with fillRect.

Circle tool

There is no direct function in canvas to draw circle like fillRect or strokeRect.But we can draw arc.So we will extend the arc to a circle by giving starting angle as zero and ending angle as square of 3.14(pi value).

 context.arc(centerx,centery,radius, 0, Math.PI*2, true);  

0 notates starting angle and Math.PI*2 notates ending angle.
Here is how the function circle looks like,
1:  function circle(){  
2:  canvas.onmousedown=circledown;  
3:  canvas.onmouseup=circleup;  
4:  canvas.onmousemove=circlemove;  
5:  function circledown(e){  
6:   img=context.getImageData(0,0,canvas.width,canvas.height);  
7:   startx=e.x;  
8:   starty=e.y;  
9:   drag3=true;  
10:  }  
11:  function circleup(e){  
12:  drag3=false;  
13:  }  
14:  function circlemove(e){  
15:  if (drag3){  
16:  context.putImageData(img,0,0);  
17:  endx=e.x;  
18:  endy=e.y;  
19:  context.beginPath();  
20:  context.arc((endx+startx)/2,(endy+starty)/2,Math.sqrt(Math.pow(endx-startx,2)+Math.pow(endy-starty,2))/2, 0, Math.PI*2, true);   
21:  context.closePath();  
22:  context.stroke();  
23:  if (f==1){  
24:  context.fill();  
25:  }  
26:  }}}  


Even though the arc coordinates look complex,its actually the javascript representation for length equation of line when end points are given.

Eraser

For a eraser tool we use the clearRect function in canvas.ClearRect function clears the pixels in the specified rectangle.
 context.clearRect(10,10,20,20)  

The code above will clear pixels on rectangle that has starting points from 10,10 having a width of 20 and height of 20.
Eraser function is as given below.
1:  function erase(){  
2:  canvas.onmousedown=erasedown;  
3:  canvas.onmouseup=eraseup;  
4:  canvas.onmousemove=erasemove;  
5:  function erasedown(e){  
6:   drag5=true;  
7:  }  
8:  function eraseup(e){  
9:  drag5=false;  
10:  }  
11:  function erasemove(e){  
12:  if(drag5){  
13:  x=e.x;  
14:  y=e.y;  
15:  context.clearRect(x,y,20,20);  
16:  }}}  

On mouse down it will update clearRect  with x,y coordinates recieved from each mouse move event and clears pixels in that area of rectangle.


Spray

Spray function is just the mixing of little rectangles and squares near to the coordinates obtained from mouse events.

1:  function spray(){  
2:  canvas.onmousedown=spraydown;  
3:  canvas.onmouseup=sprayup;  
4:  canvas.onmousemove=spraymove;  
5:  function spraydown(e){  
6:  x=e.x;  
7:  y=e.y;  
8:   drag8=true;  
9:  for (var i=0;i<20;i=i+6){  
10:  context.fillRect(x+i,y+i,1.5,1.5);  
11:  context.fillRect(x-i,y-i,1.5,1.5);  
12:  context.fillRect(x-i,y+i,1.5,1.5);  
13:  context.fillRect(x+i,y-i,1.5,1.5);  
14:  context.fillRect(x-i,y,1,1);  
15:  context.fillRect(x,y-i,1,1);  
16:  context.fillRect(x,y+i,1,1);  
17:  context.fillRect(x+i,y,1,1);  
18:  }  
19:  context.beginPath();  
20:  for(var i=0;i<12;i=i+4){  
21:  context.arc(x+i,y+i,1.3, 0, Math.PI*2, true);   
22:  context.arc(x-i,y+i,1.3, 0, Math.PI*2, true);  
23:  context.arc(x+i,y-i,1.3, 0, Math.PI*2, true);  
24:  context.arc(x-i,y-i,1.3, 0, Math.PI*2, true);   
25:  context.arc(x,y-i,1.3, 0, Math.PI*2, true);  
26:  context.arc(x-i,y,1.3, 0, Math.PI*2, true);  
27:  context.arc(x,y+i,1.3, 0, Math.PI*2, true);  
28:  context.arc(x+i,y,1.3, 0, Math.PI*2, true);  
29:  }   
30:  context.closePath();  
31:  context.fill();  
32:  }  
33:  function sprayup(e){  
34:  drag8=false;  
35:  }  
36:  function spraymove(e){  
37:  if (drag8){  
38:  x=e.x;  
39:  y=e.y;  
40:  for (var i=0;i<20;i=i+6){  
41:  context.fillRect(x+i,y+i,1,1);  
42:  context.fillRect(x-i,y-i,1,1);  
43:  context.fillRect(x+i,y-i,1,1);  
44:  context.fillRect(x-i,y+i,1,1);  
45:  context.fillRect(x-i,y,1,1);  
46:  context.fillRect(x,y-i,1,1);  
47:  context.fillRect(x,y+i,1,1);  
48:  context.fillRect(x+i,y,1,1);  
49:  }  
50:  context.beginPath();  
51:  for(var i=0;i<12;i=i+4){  
52:  context.arc(x+i,y+i,1.3, 0, Math.PI*2, true);   
53:  context.arc(x-i,y+i,1.3, 0, Math.PI*2, true);  
54:  context.arc(x+i,y-i,1.3, 0, Math.PI*2, true);  
55:  context.arc(x-i,y-i,1.3, 0, Math.PI*2, true);    
56:  context.arc(x,y-i,1.3, 0, Math.PI*2, true);  
57:  context.arc(x-i,y,1.3, 0, Math.PI*2, true);  
58:  context.arc(x,y+i,1.3, 0, Math.PI*2, true);  
59:  context.arc(x+i,y,1.3, 0, Math.PI*2, true);  
60:  }  
61:  context.closePath();  
62:  context.fill();  
63:  }}  
64:  }  


Here we can see that i created small rectangle and squares around the coordinate obtained from mouse event so that it will give spray effect.

The Brush tool is easy to implement.It can be implemented in many different ways.I used 3 small circles in a line manner at the coordinates obtained from mouse events.

Below given is an image drawn using the Paint App..































See full code from my GitHub...

Lisp Interpreter


What is Lisp?



Lisp (historically, LISP) is a family of computer programming languages with a long history and a distinctive, fully parenthesized Polish prefix notation.

Lisp was originally created as a practical mathematical notation for computer programs, influenced by the notation of Alonzo Church's lambda calculus.

Lisp was invented by John McCarthy in 1958 while he was at the Massachusetts Institute of Technology (MIT).

Lisp was first implemented by Steve Russell on an IBM 704 computer. Russell had read McCarthy's paper, and realized that the Lisp eval function could be implemented in machine code.The result was a working Lisp interpreter which could be used to run Lisp programs, or more properly, 'evaluate Lisp expressions.'



Lisp interpreter in Javascript


A language interpreter has two parts: Parsing and Execution.

In PARSING it 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.

In EXECUTION the internal representation is then processed according to the semantic rules of the language, thereby carrying out the computation.


The parser

Parsing has two phases: read and parse.
At first the input read as a string.In the tokenizing part it is then converted in to list.Say if the input is "(set! twox (* x 2))" then after tokenizing it will look as 
['(', 'set!', 'twox', '(', '*', 'x', '2', ')', ')']
So here is the function tokenize.....

1:  function tokenize(s){  
2:    return s.replace(/\(/g,' ( ')  
3:    .replace(/\)/g,' ) ')  
4:    .trim()  
5:    .split(/\s+/);  
6:  }  


Here read works by calling read_from on the tokens obtained by tokenize.It will try to read an expression from a sequence of tokens.

1:  function read_from(tokens)  
2:  {  
3:   if (tokens.length==0){console.log("SyntaxError:unexpected EOF while reading");}  
4:   var token=tokens.shift();  
5:   if ('('===token)  
6:   {  
7:   var L=[];   
8:   while(')'!==tokens[0])  
9:   {  
10:     L.push(read_from(tokens));  
11:   }  
12:   tokens.shift();  
13:   return L;  
14:   }  
15:   else{  
16:   if (')'===token){  
17:    console.log("SyntaxError:unexpected )");  
18:   }  
19:   else {  
20:   return atom(token);}  
21:   }  
22:   }  



Execution

In execution phase nine forms (variable reference, constant literal, quotation, conditional, assignment, definition, procedure, sequencing, procedure call) are evaluated.

1:  function eval(x,env)  
2:  {  
3:   env=env || global_env;  
4:   if (typeof x==='string')  
5:   {  
6:   return env.find(x.valueOf())[x.valueOf()];  
7:   }  
8:   else if (typeof x==='number')  
9:   {  
10:   return x;  
11:   }  
12:   else if (x[0]==='quote')  
13:   {  
14:   return x[1];  
15:   }  
16:   else if (x[0]=='if')  
17:   {  
18:   var test=x[1],conseq=x[2],alt=x[3];  
19:   if (eval(test,env))  
20:   {  
21:   return eval(conseq,env);  
22:   }  
23:   else{  
24:   return eval(alt,env);}  
25:   }  
26:   else if(x[0]==='set!')  
27:   {  
28:   env.find(x[1])[x[1]]=eval(x[2],env);  
29:   }  
30:   else if (x[0]==='define')  
31:   {  
32:   env[x[1]]=eval(x[2],env);  
33:   }  
34:   else if (x[0]==='lambda')  
35:   {  
36:   var vars=x[1],exp=x[2];  
37:   return function()  
38:   {  
39:    return eval(exp,Env({parms:vars,args:arguments,outer:env}));  
40:   };   
41:   }  
42:   else if (x[0]==='begin')  
43:   {  
44:   var val;  
45:   for (var i=1;i<x.length;i+=1)  
46:    val=eval(x[i],env);  
47:   return val;  
48:  }  
49:  else  
50:  {  
51:  var exps=[];  
52:  for (i=0;i<x.length;i+=1)  
53:   exps[i]=eval(x[i],env);  
54:  var proc=exps.shift();  
55:  return proc.apply(env,exps);  
56:  }  
57:  }  


Environments

Environments are mappings of variable names (symbols) to the values (data objects) held by them.

1:  function Env(dict)  
2:  {  
3:  var env={},outer=dict.outer || {};  
4:  if (dict.parms.length!=0)  
5:  {  
6:  for (var i=0;i<dict.parms.length;i+=1)  
7:  {  
8:   env[dict.parms[i]]=dict.args[i];  
9:  }  
10:  }  
11:  env.find=function(variable)  
12:  {  
13:  if (env.hasOwnProperty(variable))  
14:  {  
15:  return env;  
16:  }  
17:  else  
18:  {  
19:  return outer.find(variable);  
20:  }  
21:  }  
22:  return env;  
23:  }  


Go to the Github respository to see all the code. And here is  lis.py , the simple Scheme interpreter that Peter Norvig wrote in Python.