A Python Expression Evaluator

To start going with my first little Python based web application here I came up with Python Expression Evaluator. What is does ? The name says it all: it evaluates Python expressions, which the user can enter into a form and send to the server where this little 25-liner does its work and returns the result plus all the HTML code to render it nicely on the user’s screen:

It allows the user to type in any type of Python expression, like e.g.

  • 80 / 4, or any other type of basic calculation, thus we can use it as a calculator
  • len("Hellow World!") – we can use it to compute the length of a given string
  • "Hello World".count("o") to find out how often a particular character shows up in a given string
  • … and many more ( ideas ? )

Here is the code:

   1: #!/usr/bin/python
   2:  
   3: import cgitb; cgitb.enable()
   4:  
   5: import cgi
   6: form = cgi.FieldStorage()
   7:  
   8: expr = form.getvalue('expr', None)
   9:  
  10:  
  11:  
  12: if expr != None:
  13:     try: output = expr + " => " + str(eval(expr))
  14:     except Exception,e: output = "<font color=\"red\">%s => %s</font>" % (expr,e)
  15: else: output = ""
  16:  
  17: print '''Content-type: text/html
  18:  
  19: <html>
  20:   <head>
  21:     <title>Python Expression Evaluator</title>
  22:   </head>
  23:   <body>
  24:     <h1>Python Expression Evaluator</h1>
  25:     <div>%s</div>
  26:     <br>
  27:     <form action='py_eval.py'>
  28:     Expression <input type='text' name='expr' />
  29:     <input type='submit' />
  30:     </form>
  31:   </body>
  32: </html>
  33: ''' % output 

Let’s decipher what it does:

  1. Let the script know we are using Python code
  2. Import cgitb module and enable CGI Tracebacks to nicely show error messages on the screen rather than in the web server log file. Not really needed here since my little script basically catches all sorts of exceptions, as we will see in a minute. Thanks to Magnus Lie Hetland and his great book "Beginning Python: From Novice to Professional, Second Edition" for this tip !
  3. Import cgi module, mainly used to retrieve values sent to the server
  4. Implement the cgi FieldStorage to retrieve values sent to the server
  5. Evaluate the expression sent to the server. With the help of exception handling all possible exceptions are handled and translated to a message ( variable output ) sent back to the user
  6. Generate the HTML for the user frontend and insert the output message; either the output from the eval() or the exception message.


Try the expression ("10/0") to see how Python’s exception handling catches that error. If I would remove my own exception handling from the code and change it from

   1: if expr != None:
   2:     try: output = expr + " => " + str(eval(expr))
   3:     except Exception,e: output = "<font color=\"red\">%s => %s</font>" % (expr,e)
   4: else: output = "" 

to just

   1: output = expr + " => " + str(eval(expr)) 

then the cgitb module would kick in and transform the unhandled exception into a message shown in the browser, like here for example:

Nice, so far.

What enhancements can we think of to enhance this little tool ? Here are my ideas, any more to come ?

  1. Support multi-line Python code
  2. Support regular expressions
  3. Support expression storage & retrieval ( partially works thru your browser; try to hit the Down while entry field has focus )
  4. Support a more dynamic user interface
  5. 5. … ?

Happy New Year 2012 everyone !

Happy New Year 2012 everyone ! I hope you have had a good start into the New Year and hopefully don’t start it with too many items sitting in your in-box and waiting for you to get you into the same hectic and trouble like every year.

Still looking for some good New Year resolutions ? Check out this Lifehacker article: Top 10 Easy-to-Keep Resolutions for This New Year. And here are some more general hints and insights about making New Year’s resolutions: The Science Behind New Year’s Resolutions (and How to Use It to Achieve Yours)

Don’t need any of those ? I don’t have any but I actually like this one from Garfield.

May be you are just curious about the most successful blog postings on Lifehacker last year ? Here they are: This Is the Best of Lifehacker 2011: about How-To guides, DIY projects, photography, Mac and linux downloads, desktops and workspaces, browser extensions and Android apps. How about starting an information diet this year ? Or some very basic means to improve your health: “A Half-Hour Walk Can Make a Big Difference, Even If It’s Your Only Activity” ?

Many seem to say the world will end this year: the Bible, the Maya Calendar, Nostradamus, http://www.polereversal.com/. Most likely this will be a mis-interpretation of “information” one can find there or elsewhere; don’t forget my last posting from last year: Common knowledge doesn’t exist. : It is more a question of belief which evidence you accept and who you trust … and how you interpret information.

Nevertheless, even if the world would end this year, let’s just continue to do what we do now, let’s do it right and with our full power, let’s follow the philosophy of Martin Luther, to whom the following quote was attributed:

“If I knew that tomorrow was the end of the world, I would plant an apple tree today.”

Image from Wikiquote.

2011 in review

The WordPress.com stats helper monkeys prepared a 2011 annual report for this blog.

Here’s an excerpt:

The concert hall at the Syndey Opera House holds 2,700 people. This blog was viewed about 20,000 times in 2011. If it were a concert at Sydney Opera House, it would take about 7 sold-out performances for that many people to see it.

Click here to see the complete report.

How do you celebrate Christmas ?

Yesterday my wife and I visited my grandma in the home of the aged where she lives now. They had an interesting session there where one lady was telling about the different ways people celebrate Christmas in different cultures.
We Germans, she said, seem to take Christmas quiet serious. May be true. In other countries in Africa or South America Christmas seems to be a quiet happy fest.
Different cultures have very different traditions how to celebrate, and also different traditional meals and habits for the holidays around Dec. 24th.
In the household of my mother we have a woman from Poland. While carp is supposed to be a traditional Polish Christmas dinner as we learned yesterday she actually is always cooking a soup of beetroot with some sort of filled noodles, called Pierogi. Very delicious ! They also have the nice tradition to pass around a large baked wafer from which everyone breaks apart a little piece to give to someone else; a nice way to symbolize charity, may be the true sense of Christmas.

So folks, since we are hopefully a multi-cultural community here: let us know how you celebrate Christmas every year. What are you special traditions, habits and meals during those festive days at the end of the year ?

Common knowledge doesn’t exist.

Over the weekend my wife and I visited some relatives living in Regensburg and we have had some good discussions about several topics – from blood cholesterol level to politics to the magnetic polar reversal scheduled for December 21, 2012

Big Moon
"Big Moon" by KM&G-Morris.

I noticed: common knowledge doesn’t exist. People know, what they want to know. They filter and interpret facts according to their believes. A common body of knowledge doesn’t exist for human mankind, nor for any group of people, for any culture, community or company. People are different, and everyone is having his own version of the truth.

I was reminded to this when reading this quote today by Edwin Abbott Abbott:

Men are divided in opinion as to the facts. And even granting the facts, they explain them in different ways.

And so I sit, poor silly man No wiser now than when I began..

For every fact you can come up with evidences, but you can also come up with evidences to refute it. It is more a question of belief which evidence you accept and who you trust, who’s book you read and who’s you criticize, probably without even reading it. Do you trust your doctor more than one who you don’t know and who has written a book titled “The Cholesterol Lie” ? Do you believe those who announce world’s end knowing that so far the world never ended before, which of course is no evidence that some time in the future it might happen ? Do you think our politicians are telling us the truth, our leaders really lead us, scientist and experts acknowledge wisdom and insight more than their carrier ?

“I know that I know nothing” said Johann Wolfgang von Goethe’s Faust. This is probably the only truth you can come up with, besides certain facts from mathematics where true evidences really exist – as far as I can tell.

The secret of success of social networks

These web sites are like email on crack..

Yesterday I have been watching episode 5×22 of the TV show Criminal Minds: “The internt is forever”. It is about a murderer who successfully seeks his victims thru social networks.

OK, that’s a TV show with lots of fiction and thrill. But this episode contains a big portion of realism. Many people are scared of participating in social networks. Many of them probably don’t even know exactly why they are afraid of social networks, they just follow their instincts or have a kind of unspecified phobia that someone could abuse their data in some form.

And they might be right. While social  networks provide some great opportunities to “meet” a lot of “remote” people, discover new knowledge, find experts and hints and tips and solutions to problems, boost someone’s own reputation, they also come with a lot of risk as well. If for instance you post by the minute where you are foreigners easily can figure out when you are not at home. If they also found out where that is you should not be surprised that your home has been robbed when you return. Hint # 1: post your travel plans after the fact. Hint # 2: don’t post your address. Nevertheless, you might have posted a photo somewhere of your house which has been geo-tagged and thus one does not have to be a good hacker to find out your address.

This is just one example of a risk. There are many and thus it is vital to use social networks right and smart once you decided to use them at all. But be aware: the more you publish, the higher your risk. And once you have joined there is always some risk that someone abuses your data. You simply have to accept this when joining some social network.

Is it worth it ? Boosting ones own reputation is certainly one motivation to use social networks. Is it the main reason for many ? In this TV show one agent is making an interesting statement: The success of social network lies in the fact that people believe other people are interested in what they are posting.

A nasty statement. Or a true one ? I actually believe there is much truth in that statement. If you are an active participant in social networks, think for yourself: how much do you worry about your own writings and feedback you get ? And how much do you worry about what others write ?

Good bye delicious, hello Google Bookmarks !

After delicious has decided to come up with new functions I don’t need and brake the old essential functionality I have been using since years ( this mess is discussed here on the review page for the Firefox extension Delicious Bookmarks ) I decided to migrate over to Goolge Bookmarks. Luckily Google Bookmarks provides an “Import Delicious Bookmarks” function and that function works quiet nicely and is smart enough to also figure out which bookmarks I already imported some time ago when I first tried out Google Bookmarks.

Google Bookmarks performs much better than delicious now (as a matter of fact it is really fast!) and comes with a simple user interface which … just works and provides the essentials I need ( except that I could not figure out yet how to get my bookmarks sorted by date as a default ). I am using the GBookmarks Firefox extension for bookmarking and so far I am happy with Google Bookmarks now.

Whether I ever will return to delicious certainly also depends on whether they provide a service to easily migrate back my bookmarks from Google Bookmarks. Nevertheless, as soon as I figure out some way to include a list of my recent bookmarks from Google Bookmarks in my blog as I do it nowadays with delicious bookmarks there is probably no reason for me to ever return to delicious.

Update: Getting a “502 Bad Gateway” Error today when trying to login to delicious.

Strange behavior of Firefox 5

Since yesterday I observe some strange behavior of my Firefox 5 browser. Two of my extensions stopped working:

Both add-ons worked before and used to display some dialog box for bookmarking / sharing. Now nothing happens when trying to invoke these add-ons.

Besides Firebug 1.8.0 does not seem to work as well; I can’t find any means to enable / start it, there is for instance no icon showing up in the Add-On Toolbar, even after trying this recommendation.

The weird thing is: after I tried to use any of the two extensions mentioned above the Tools –> Add-ons feature in Firefox stops working as well: no add-ons page is displayed anymore.

And: after exiting Firefox it stays in memory ( I can see the process in Windows Task Manager ) and thus I can not re-start it without first killing that process.

Time of switch to Google Chrome as my default browser like many others are doing it these days ? Or does anyone have any idea how I can debug, investigate, mitigate or solve these problems ?

Running a sub process from a Python script

Python is such a powerful language that “Python scripts” actually deserve to be called “Python programs” or “Python applications”, but nevertheless, let’s go with this title for todays’s blog posting: “Running a sub process from a Python script”.

Currently I am writing test scripts for one of our storage products and thus apparently I have the need to invoke commands from my Python script, capture the output and look at the return code.

There are various ways in Python how to do this. One way is popen which allows to run an external command in a sub process and return its output in form of a file like stream, so that it can be read and analyzed any further ( see this easy example ). Nevertheless, there are many popens available for Python, from the standard popen provided by the os module to several variations in other modules like popen2 and subprocess, called popen, popen2, popen3, popen4.  A bit confusing for a Python newbie, especially since I had come up with some specific requirements:

  1. I wanted to capture stderr as well – the file stream for error messages – and actually treat it like the standard output stream so that in case of an error the error messages are displayed where usually the output is displayed. And depending on my future test scenarios I probbaly have the need to analyze the error message stream as well.
  2. I need to capture the return code from the command executed in the sub process.

After working on this for 2 to 3 hours and exploring all the possibilities I got to the point where I thought I either can have 1 or 2, but not both. Until I figured out this solution based on the popen2 module:

   1: import popen2
   2: # ...
   3: cmd = "ping bla"            # No, I am not using foo here ;-) 
   4: f = popen2.Popen4(cmd)
   5: while True:
   6:     try: line = f.fromchild.readline()
   7:     except IOError: break
   8:     if not line: break
   9:     # ...
  10: rc = f.poll()
  11: f.fromchild.close()

Popen4 from the popen2 module by default combines stderr and stdout into one stream, thus no need to handle both streams. This implementation actually seemed to work nicely, except … I got a “depreciation” warning about the popen2 module when importing it saying basically that this module will go away in the future and will be replaced by the subprocess module.

Thus I had to continue my research and find a working solution based on the subprocess module. Here it is:

   1: import subprocess
   2: # ...
   3: cmd = "ping blabla"                 # Still not using foo, but never mind ;-) 
   4: f = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
   5: while True:
   6:     line = f.stderr.readline()
   7:     if not line: break
   8:     m = re.match("shell-init",line)        # Ignore shell-init errors
   9:     if not m:
  10:         # ...
  11: while True:
  12:    line = f.stdout.readline()
  13:    if not line: break
  14:    # ...
  15: rc = f.poll()
  16: f.stderr.close()
  17: f.stdout.close() 

Here I get two message streams, one for stdout and one for stderr to be handled independently. One hurdle is that I get strange “shell-init” errors always in my stderr stream, wheter or not the command itself finishs successfully. The other observation to make: the return code obtained by using this implementation is different than the one I get from the first implementation. If the command is okay – in my case I ping an existing network address, I get 0 in both cases. If I ping some non-existing network address ( like “foo”, “bla” or “blabla” ) I get a return code 512 with the first code snippet and a return code of 2 with the second alternative.

Even I have a solution now working quiet well I guess there is still more to explore for me.

Sitting kills

After we know how dangerous it is too spend too much time in a chair ( see e.g. these articles here and here )  I think chairs should be labeled in the same way as cigarette packages need to be labeled nowadays, with signs like:

“Sitting kills”,

“Sitting for more than 23 hours a week increases your chance of dying from heart disease by 64 %”

“Get up every hour ! Exercising after work is not sufficient !”

What do you think ?

May be we should re-design our work places to force us getting out of our chairs regularly and more often, keeping in mind that the human body is not designed to sit for hours. We are designed to cross the savanna and chase animals, everything in our body works much better if we are moving, using our legs, driving up our heart beats once in a while. Instead of hunting animals some long distance walk, many short walks and other sorts of physical training might do the trick as well.

How about computer operating systems, media, entertainment and gaming gadgets going into suspend mode automatically after 1 or 2 hours, being wirelessly connected to some step counter a user has to carry and starting up again after you have walked so many steps ?  Or asking you for a password displayed on some screen half a kilometer away ? How about “buying” extra computer or TV hours through your step counter, thus paying with number of steps done or amount of calories burned ?

How about a system assigning a network printer to your computer farthest away from your work place ?

How about forgetting about meeting rooms, doing meetings while doing a little hike ?

How about … any  more ideas ?

Follow

Get every new post delivered to your Inbox.