SunQuest
           Python Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming LanguagesPython Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
Get inside! Sample the range of functionality easily built with JMSL Library for Time Series Data Analysis, Heat Maps, Portfolio Optimization, Monte Carlo Simulation, Stock Price Charting and more. Download Now!
  #1  
Old April 9th, 2004, 09:16 PM
caroundw5h caroundw5h is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Oct 2003
Location: Canada
Posts: 181 caroundw5h User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 13 h 55 m 34 sec
Reputation Power: 0
My first CGI PROGRAM.

I would like to know how to refactor this code so it works better and more effiecently. It is a hack, as it is my first cgi project - ever. Please be gentle.
The problems i am having are 1) if a user enters a invalid email address it still gives the error message however it also still writes to the file
2)Every time an item is written to the file, part of the previous information is overwritten by whitespace. This seems to be incremental by a value incremented by at least 2 on each line:
for example if the file was accessed x times.
first time:abcdefghiklmno
second time:abcdefghik
third:abcdefghijk
and so on

this is my code so far. again please be gentle. I'm pretty much finished- i think:
Code:
#c_parser.py
#import appropiate modules

import cgi
import time
import cgitb; cgitb.enable()
form = cgi.FieldStorage()
print "Content-type: text/html"
print

open = 0


#get form information
    
try:
    
    name = form["name"].value
    if name.isalpha():
        name = name.lower()
    else:
        print "Enter a valid name"
        
    exp = form["Experience"].value
    level = form["Level"].value
    product = form["Product"].value
    
    area_code = form["area_code"].value
    if area_code.isalpha():
        print "Enter a valid area code"
        
    phone_prefix = form["p_prefix"].value
    if phone_prefix.isalpha():
        print "Enter a valid Phone Prefix"
        
    phone_suffix = form["p_suffix"].value
    if phone_suffix.isalpha():
        print "Enter a valid Phone Suffix"
        
    email = form["email"].value
    if "@" not in email:
        print "Enter a valid email"

    phone = area_code + "-" + phone_prefix + "-"+ phone_suffix

except Exception, e:
    print "please input your", e

else:

    try:
        open+=1
        f = file(r"C:\Program Files\Abyss Web Server\htdocs\log.txt", "r+")
        length = len(f.read())
        f.seek(length+open)
        f.write("\n")"""with newline some values of preceeding line still truncated"""
        f.write(time.asctime())
        f.close()
        print "info written to file now"

    except Exception, e:
        print e



__________________
"In theory, there is no difference between theory and practice.
But, in practice, there is."


Reply With Quote
  #2  
Old April 19th, 2004, 08:14 PM
caroundw5h caroundw5h is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Oct 2003
Location: Canada
Posts: 181 caroundw5h User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 13 h 55 m 34 sec
Reputation Power: 0
wow my code is excellent? gee thanks:

Reply With Quote
  #3  
Old April 20th, 2004, 03:47 AM
DevCoach DevCoach is offline
Contributing User
Dev Shed Beginner (1000 - 1499 posts)
 
Join Date: Feb 2004
Location: London, England
Posts: 1,196 DevCoach User rank is Captain (20000 - 30000 Reputation Level)DevCoach User rank is Captain (20000 - 30000 Reputation Level)DevCoach User rank is Captain (20000 - 30000 Reputation Level)DevCoach User rank is Captain (20000 - 30000 Reputation Level)DevCoach User rank is Captain (20000 - 30000 Reputation Level)DevCoach User rank is Captain (20000 - 30000 Reputation Level)DevCoach User rank is Captain (20000 - 30000 Reputation Level)DevCoach User rank is Captain (20000 - 30000 Reputation Level)DevCoach User rank is Captain (20000 - 30000 Reputation Level) 
Time spent in forums: 1 Week 5 Days 13 h 42 m 7 sec
Reputation Power: 252
I missed this post first time around.

First a comment on efficiency in CGI scripts: don't worry about it. In a CGI program like this the bulk of the time is going to be spent loading Python, loading the script, and compiling it to bytecodes. Unless you have a loop in you script that is doing heavy processing then nothing you can do to the code will make any noticeable difference. If execution time is an issue for you then look into one of the alternatives to CGI where Python is running full time so does not need to be loaded: mod_python, mod_cgi, FastCGI, WebWare, Zope etc.

Now down to the code:

1)
Code:
    if name.isalpha():
        name = name.lower()

Don't bother with the isalpha test - name = name.lower() is all you need, since it will make all alpha characters lowercase and leave the rest. The test for isalpha will return False if any character in the string is non-alpha, including spaces. So "John Doe" will not be made lowercase since it will fail the test.

2)
Code:
    if area_code.isalpha():
        print "Enter a valid area code"

I presume by area code that you mean Zip code? The UK and many other countries have an alphanumeric area code, e.g. "AB12 CD34", so your test will exclude those from outside of america. It will also accept as valid any string that has any non-alpha characters (e.g. '£$%&**'), as well the empty string. If you want to check that a string only contains 0-9 then use str.isdigit().

3) ditto for all the phone number tests. But also see my rant on checking phone numbers here.

4)
Code:
except Exception, e:
    print "please input your", e


What will be in the exception object e? Why do you assume it will be a string saying what is missing?

5)
Code:
        open+=1
        f = file(r"C:\Program Files\Abyss Web Server\htdocs\log.txt", "r+")
        length = len(f.read())
        f.seek(length+open)


open is intialised to 0 at the start of the script, so will always be set to 1 at this point. What is it supposed to represent?
You are also reading in the entire file just to seek to the end - I take back what I said about not needing to optimise. You can seek directly to the end of the file with f.seek(0,2). You can also open the file for appending in which case the seek to the end happens automatically.

6) It looks like you are writing to the log file that the server is using. THIS IS VERY DANGEROUS. The server may be be in the process of writing to the file, in which case the call to write() may fail, or the server may write to the file between your seek and your write statements, which will result in information getting overwritten. It sounds from your description that this may be what is happening. Create your own log file and write to that.

7)
Code:
    try:
    ...
    except Exception, e:
        print e

you have enabled cgitb to display any exceptions in a nice HTML friendly way, but then you catch all exceptions and display the same information in plain text. Remove the last try/except block and let cgitb do its work.

Finally a note on good practice: if you separate out the CGI part and put the data handling into a separate function then you can easily test the code either interactively or with unittest. e.g.

Code:
def checkAndSaveFormData(name, exp, area_code, phone_prefix,...):
   ...

if __name__ == '__main__':
  name = cgi.form['name'].value
  exp = cgi.form['exp'].value
  ...
  checkAndSaveFormData(name, exp,...)



Dave - The Developers' Coach

Reply With Quote
  #4  
Old April 20th, 2004, 08:06 AM
caroundw5h caroundw5h is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Oct 2003
Location: Canada
Posts: 181 caroundw5h User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 13 h 55 m 34 sec
Reputation Power: 0
Thank you for you reply Coach. I've sinced refactored my code and found more efficient ways to code it.
Thank you very much for you helpful suggestions and your time. you can be sure i wasn't trying to write to the log file, and i've found the pythonic way of appending to a file with the append mode . If does its job very well.
here is my code for anyone who would like to see a decent cgi script in python, add your own content accordingly
Code:
#c_parser.py
""" while 1:
        get form input
        handle form validity
        break
    process form"""
    
#import appropiate modules

import cgi, sys,time
import cgitb; cgitb.enable()

form = cgi.FieldStorage()
print "Content-type: text/html"
print

def Alert():
    print  """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/transitional">

<html>
<head>
<link rel="stylesheet" type="text/css" href="styles.css" />
</head>
<title>title goes here</title>
<body>


<h1>HEADLINES</h1>
<P/>
<h4>just a blurb</h4>
<table cellpadding = 4 cellspacing=0 width=100%>
<tr> 
<th><a href ="about.htm">About Us</a> 
<th><a href ="solutions.htm">Solutions</a>
<th><a href ="contact.htm">Contact</a>
<th><a href ="index.htm">Home</a>
<th><a href ="eform.htm">E-Forms</a>
</tr></table><ul/><hr/><p/>
<center/>
</body>
</html>"""
    return 


def End_page():
    print """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/transitional">

<html>
<head>
<link rel="stylesheet" type="text/css" href="styles.css" />
</head>
<title>TITLE</title>
<body>


<h1>HEADLINES HERE</h1>
<p/>
<h4>other blurbs</h4>
<table cellpadding = 4 cellspacing=0 width=100%>

<tr> 
<th><a href ="about.htm">About Us</a> 
<th><a href ="solutions.htm">Solutions</a>
<th><a href ="contact.htm">Contact</a>
<th><a href ="index.htm">Home</a>
</tr></table><ul/><hr/><p/>
<center/>Your information has been processed.</p>
<input type = "button" value ="RETURN TO HOME"  onClick = "window.location = ' index.htm' ">
</body>
</html>
</h1>
""" 
    return


def ProcessInfo():
    """processes client info however possible to just maybe  refactor and use the csv module,or picke, or shelve"""
    try:
        f=open(r"C:\Program Files\Abyss Web Server\htdocs\clients.txt", "a")
        f.write(time.asctime())
        f.write("\n")
        f.write(info)
        f.write("\n\n")
    finally:
         f.close()
    return 


#get form information
while 1:
    """form.getvalue("key") much less forgiving since it will not raise an exception and return none if nothing in field"""
    name=form.getvalue("name","name_none")
    l_name=form.getvalue("l_name","lname_none")
    exp=form.getvalue("Experience","exp_none")
    level=form.getvalue("Level","level_none")
    product=form.getvalue("Product","product_none")
    area_code = form.getvalue("area_code","area_none")
    phone_prefix = form.getvalue("p_prefix","prefix_none")
    phone_suffix = form.getvalue("p_suffix","suffix_none")
    email = form.getvalue("email","email_none")


    #TEST INPUT
    if name.lower() == "name_none" or l_name.lower() == "lname_none":
        Alert()
        print "<h2>Please Enter a valid name</h2>"
    
    elif exp=="exp_none":
        Alert()
        print "<h2>Please enter your experience level</h2>"
    elif level=="level_none":
        Alert()
        print "<h2>Please enter your level of work</h2>"
    elif product== "product_none":
        Alert()
        print "<h2>Please enter the product or service you have experience with</h2>"
    elif area_code=="area_none":
        Alert()
        print "<h2>Enter your area code</h2>"
    elif area_code.isalpha():
        Alert()
        print "<h2>Enter a valid area code</h2>"
    elif phone_prefix=="prefix_none":
        Alert()
        print "<h2>Enter your phone prefix</h2>"
    elif phone_prefix.isalpha():
        Alert()
        print "<h2>Enter a valid phone prefix</h2>"
    elif phone_suffix.isalpha():
        Alert()
        print "<h2>Enter a valid phone suffix</h2>"
    elif phone_suffix=="suffix_none":
        Alert()
        print "<h2>Enter a phone sufffix</h2>"
    elif "@" not in email:
        Alert()
        print "<h2>Enter a valid email address</h2>"
    else:
        phone = area_code + "-" + phone_prefix + "-" + phone_suffix
        info = name +"  "+ l_name + "  " + exp + "  "+level+" " +product+" "+phone+" "+email
        
        ProcessInfo()
        End_page()
    break


Also a nice plug: for those of you looking for a webserver to practice your cgi programming in python or other scripting. I highly suggest The Abyss webserver. I didn't build it so i'm not spamming, but it is amazing piece of work. Its tiny, and effiecient and is constantly being upgraded. available for windows and linux. So if you don't need an industrial size webserver like apache check it out. The more ppl using it the better it will become. I'm honestly very impressed with this piece of software. Even use it to host your own sites on your comp. Unbelievable especially when you combine the power of python. Thats my two cents, my ten cents is free.

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesPython Programming > My first CGI PROGRAM.


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump


Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 





© 2003-2008 by Developer Shed. All rights reserved. DS Cluster 5 hosted by Hostway