<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
Species:
<form id="form1" name="form1" method="post" action="">
<label>
<select name="species" id="species">
<option>ecoli</option>
<option>yeast</option>
</select>
</label>
</form>
<p>Concentration: </p>
<form id="form2" name="concentration" method="post" action="">
<label>
<input type="text" name="concentration" id="concentration" />
</label>
</form>
<p>Volume: </p>
<form id="form3" name="volume" method="post" action="">
<label>
<input type="text" name="volume" id="volume" />
</label>
</form>
<form id="form4" name="form4" method="post" action="cgi-bin/yield.pl">
<label>
<input type="submit" name="button" id="button" value="Submit" />
</label>
</form>
<p> </p>
</body>
</html>
i had my boss help me out to write a simple script that works in command prompt, it is basically what i want to translate into an html form and a cgi script:
print "\ninput your concentration in ng/ul\n\n";
$concentration = <STDIN>;
print "input your volume in ul\n";
$volume = <STDIN>;
print "your yield is\n";
print ($volume * $concentration);
i do not know how to write the cgi script for this...i've been taking shots in the dark and here is what i've tried (it doesn't work):
#!/usr/local/bin/perl
print "Content-type: text/html \n\n";
$concentration = "concentration";
$volume = "volume";
my $yield = "$concentration * $volume";
print "your yield is $yield";
<form action="yourscript.cgi">
<input type="text" name="key 1">
<input type="text" name="key 2">
<input type="text" name="key 3">
<input type="submit" value="submit">
</form>
This will submit the values of key 1, 2, and 3 to yourscript.cgi.
Note I used a .cgi extension - when you get this off the ground, your server may require .cgi extensions and not .pl. Minor point.
To expand on coopster's post, data is submitted to a script in an encoded format, generally in key/value pairs. The name attribute of the form element is the key; the data entered is the value. So for my small sample, it would give you
key 1 = value entered in key 1 field
key 2 = value entered in key 2 field
key 3 = value entered in key 3 field
This is what parsing does: un-encodes the data and stores it in an associative array called a hash. so you may wind up with a hash like so:
%data = ('key 1','value entered in key 1 field','key 2','value entered in key 2 field', 'key 3','value entered in key 3 field');
These values are accessed like so:
print "the value of key 1 is $data{'key 1'}";
I can paste a read/parse in here but someone else will probably have a good one.
Second,
here is what i've tried (it doesn't work):
Let me guess: it outputs
your yield is 0;
Right? This is because the textual values you've entered evaluate as zero when you attempt to apply math to them:
my $yield = "$concentration * $volume";
Also I don't know that it will calculate with the quotes around it. Try
print "Content-type: text/html \n\n";
$concentration = "64";
$volume = "128";
my $yield = $concentration * $volume;
print "your yield is $yield";
So an additional task for your eventual program will be to make sure the input data is numeric data.
Will be watching, others will contribute. Welcome aboard!
but most perl hackers roll their own parsing routines
I don't think that is an accurate statement. The CGI modules is the standard for parsing CGI forms with perl, writing your own parser is silly and could be dangerous unless the person is very familiar with CGI and HTTP and other protocols and security issues. The average person should stick with the CGI module, even advanced perl coders are probably best sticking with the module.
#!/usr/local/bin/perl -T
use strict;
use warnings;
use CGI;my $q = CGI->new;
my %input = $q->Vars;
my $yield = $input{concentration} * $input{volume};
print $q->header,
$q->start_html,
qq{species = $input{species}<br/>
concentration = $input{concentration}<br/>
volume = $input{volume}<br/>
yield = $yield
},
$q->end_html;
the CGI form:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head><body>
Species:
<form id="form1" name="form1" method="post" action="cgi-bin/yield.pl">
<label>
<select name="species" id="species">
<option>ecoli</option>
<option>yeast</option>
</select>
</label><p>Concentration: </p>
<label>
<input type="text" name="concentration" id="concentration" />
</label><p>Volume: </p>
<label>
<input type="text" name="volume" id="volume" />
</label><label>
<input type="submit" name="button" id="button" value="Submit" />
</label>
</form>
<p> </p>
</body>
</html>
This is untested and written quickly so look it over well. Also see the CGI modules documentation for details.
I don't think that is an accurate statement.
Indeed. I would agree. My definition of a perl hacker, at least in my own mind, is perhaps quite different than what most would call perl hacker today.
The CGI modules is the standard for parsing CGI forms with perl, writing your own parser is silly and could be dangerous unless the person is very familiar with CGI and HTTP and other protocols and security issues. The average person should stick with the CGI module, even advanced perl coders are probably best sticking with the module.
Once again, I agree.
I wrote my own routines years ago after a discussion I had with Lincoln Stein regarding CGI.pm. The very same module to which you refer here. At that time the module was becoming a tad bloated for the purposes I intended or at least needed for my own applications. So I rolled my own parser.
Anyway, I always appreciate when people agree with me, life is so much simpler that way. ;)
I feel the same way about modules as I do about WYSIWYG editors. I know this is against one of the fundamental precepts of perl - "don't reinvent the wheel" - but in the case of a beginning coder, I present the following.
Examining and understanding a read/parse routine will help a beginning coder know what's actually going on and provide a richer learning experience. Passing parameters to and extracting data from a module makes it a "black box" - and when things go wrong, they will have less understanding of how to fix it.
In the context of this project, a read/parse routine is what, 10 lines? 20? The CGI module could be considered overkill. you won't need all the methods for generating forms, reading multipart data, or all the other robust tools in the CGI module. The script is just more simple as a single file without a required module.
It can go either way, just food for thought for a beginner. I agree, the approach you've posted makes for a more simple approach, but there's a little bit more to be learned by rolling your own.
you guys are the best!
our summer intern took on the task of implementing scripts on our web page ... the scripts work from the command line locally of course, but "we" are still trying to understand how to make them interactive through a browser ... so she has been following a recipe book "Perl and CGI for the World Wide Web" by Elizabeth Castro ... unfortunately, the intern is "out sick" today and not here to appreciate the wonderful feedback ...
P_D, I am still benefitting from your correction (with Phranque's addendum) of a while loop in script I was having a problem with and that you reworked for me some time back ... have applied the same solution to a few other problems also ... hopefully the intern will survive today and be here tomorrow to benefit from your advices
thanks much
Rudy
Another thing.... learned by me over the course of the last 10 years or so of posting on forums: most people are not here to learn, they have practical problems they just want a solution to, they are not interested in learning perl anymore than is necessary, in which case learning the interface of a module and how to use it can be a big time saver as well as better and more efficient code than they would probably be able to write. Learning to write good perl code takes years plus experience with all the related issues, like CGI and HTTP in this specific case.
Having said that, I am aware of how much buggy and sometimes even crappy modules there are on CPAN. Anyone can sign up for a CPAN account and upload code, there is no requirements. Its up to the rest of the perl community to test the modules and report problems. Anyone that uses CPAN should always - ALWAYS - read the bug reports and other comments (if any) left by users of the modules.
Off my soapbox.....
Exploration of opposing views will be tolerated. Agreement with my views will be considered irrevocable evidence of high moral character and superior intellect. ;)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>Untitled Document</title></head><body>Species:<form id="form1" name="form1" method="post" action=""> <label> <select name="species" id="species"> <option>ecoli</option> <option>yeast</option> </select> </label></form><p>Concentration: </p><form id="form2" name="concentration" method="post" action=""> <label> <input type="text" name="concentration" id="concentration" /> </label></form><p>Volume: </p><form id="form3" name="volume" method="post" action=""> <label> <input type="text" name="volume" id="volume" /> </label></form><form id="form4" name="form4" method="post" action="cgi-bin/yield.pl"> <label> <input type="submit" name="button" id="button" value="Submit" /> </label></form><p> </p></body></html>
(the format here is messed up)
and:
#!/usr/local/bin/perl
print "Content-type: text/html \n\n";
$concentration = "%input{concentration}";
$volume = "$input{volume}";
my $yield = $input{concentration} * $input{volume};
print "your yield is $yield";
Also use the corrected html form code.
"..i found the perl library of modules, how do i use them? they're all text files."
-RudyS
OK, I've been watching this thread for the past week, and you've had some of the best Perl scripters here trying to help you... now I have to jump in...
It appears your equation has (3) variables:
1). Species
2). Concentration
3). Volume
It appears you want to calculate a "yield" derived from (Concentration * Volume) for each (several, or all) species. Is this correct?
Are you looking to generates a report something the one below?
==========================================
SPECIES ¦ CONCENTRATION ¦ VOLUME ¦ YIELD
==========================================
Ecoli ........ 42 ...... 100ml ... .0042
Yeast ........ 90 ...... 400ml ... .0036
Other ........ 99 ...... 100ml ... .0099
==========================================
If this is not correct, please post your "problem" as a step-by-step process, e.g.-
1. A sample is collected. Volumes may vary, (e.g. 100ml, 400ml, 2 liters).
2. Technician takes a sample and examines it under microscope and visually counts various bacteria, notes count as "concentration".
3. Technician selects SPECIES, enters VOLUME and CONCENTRATION into computer program.
4. Technician repeats steps 1 through 3 for as many samples and species as needed.
5. Technician presses "RUN REPORT" to complete analysis and print report.
.. if I am way off on what you are trying to accomplish, please explain it in a way that a 5th grader could understand the problem at hand.
I think that first he needs to learn how to run the simple code I posted.
-perl_diver
...based on the fact that he had a separate <FORM></FORM constructs for each input field and other comments re: modules, etc.. I think he needs more than "perl help".. But, I thought if he could explain the problem as a step-by-step outline, we could help him script it. Chances are it can all be in a single perl script (including the form).
RudyS.. You still here ?
#!/usr/bin/perl -w
$seq = <STDIN>;
$lcseq = lc($seq);
chomp ($lcseq);
$oligo = $lcseq;
$inputlength = length($oligo);
print "of length $inputlength\n";
############################################## tm
$tm = 0;
$charpos = 0;
until($charpos == $inputlength)
{
$pair = substr($oligo, $charpos, 2) ;
if ($pair eq "aa"){$tm += 2.116;}
if ($pair eq "ac"){$tm += 3.068;}
if ($pair eq "ag"){$tm += 2.750;}
if ($pair eq "at"){$tm += 1.862;}
if ($pair eq "ca"){$tm += 3.068;}
if ($pair eq "cc"){$tm += 3.893;}
if ($pair eq "cg"){$tm += 4.591;}
if ($pair eq "ct"){$tm += 2.708;}
if ($pair eq "ga"){$tm += 2.750;}
if ($pair eq "gc"){$tm += 4.739;}
if ($pair eq "gg"){$tm += 3.893;}
if ($pair eq "gt"){$tm += 3.047;}
if ($pair eq "ta"){$tm += 1.227;}
if ($pair eq "tc"){$tm += 2.708;}
if ($pair eq "tg"){$tm += 3.047;}
if ($pair eq "tt"){$tm += 2.116;}
$charpos = $charpos +1;
}
################################### GC and AT content;
$at = 0;
$gc = 0;
$charpos = 0;
until($charpos == $inputlength)
{
$base = substr($oligo, $charpos, 1);
if ($base eq "a") {$at += 1}
if ($base eq "c") {$gc += 1}
if ($base eq "g") {$gc += 1}
if ($base eq "t") {$at += 1}
$charpos = $charpos +1;
}
$gcpercent = ($gc / ($at + $gc));
$tm2 = $tm + (5*$gcpercent);
###################################print
print "the Tm is \n$tm2\n";
this does not work as a cgi script. i uploaded it to my cgi-bin
-RudyS
"Does not work as a CGI script" is a poor way of describing the problem you're having.
You will get better answers if you ask better questions...
For a form and a CGI script to work, you need to have a way for the form to send the data to the script and return the results as a web page...
Before trying to pass data into a script and getting it do something useful, you need to know if your webserver is setup properly and that you can execute a script via the web.
Here's Lesson #1:
In almost any programming language, novices attempt to write and run a program called "Hello World". Here's "Hello World" as a PERL script...
#!/usr/local/bin/perl
#
# =========
# HELLO.CGI
# =========
#
print "Content-type: text/html\n\n";
#
print "<HTML><BODY><H1>Hello World</H1></BODY></HTML>\n";
#
1. Cut and paste the above code into a text editor and save as hello.cgi, (or you could save it as hello.pl, either should work).
2. FTP upload the file to your /cgi-bin/ directory on your webserver. (*NOTE you must upload it as ASCII text, not as a binary file)
3. Make sure the permissions for your /cgi-bin/ directory and the script are set to 755, (this done using CHMOD). 755 means the OWNER has READ, WRITE, EXECUTE privs, the GROUP has READ, EXECUTE privs and OTHER has READ, EXECUTE privs... In common unix notation it would look like:
drwxr-xr-x cgi-bin
-rwxr-xr-x hello.cgi
3. Try to run the script from a web browser. Most likely the URL for the script will be something like:
http://www.example.com/cgi-bin/hello.cgi
If this was successful, you can move ahead to "example2.cgi".. a script that checks to see if there is user input, if not it asks for it, accepts the data, processes it and returns a result via a web browser...(install using same steps as above).
#!/usr/local/bin/perl
#
# ============
# EXAMPLE2.CGI
# ============
#
use CGI;
$query = new CGI;
#
$var1 = ($query->param("var1"));
$SCRIPT_uri = $ENV{'SCRIPT_URI'};
#
print "Content-type: text/html\n\n";
#
print "<html>";
print "<head><title>Ask Who</title></head>";
print "<body>";
#
# if no data, ask for some
#
if ($var1 eq '') {
print "<form action=\"$SCRIPT_uri\" method=\"POST\">";
print "Name: <input type=\"text\" name=\"var1\">\n";
print "<input type=\"submit\" value=\"submit\">\n";
print "</form>";
#
} else {
print "Hello $var1\n";
}
#
print "</body>";
print "</html>";
#
exit;
#
Let us know how it goes...
[edited by: lexipixel at 7:13 am (utc) on July 10, 2008]
starting with the basics:
- what is the name of the cgi script? where is it located? what are the permissions and ownership of the cgi script?
- please show a source listing of the current cgi script you are using and the form you are currently trying to submit.
- have you looked in the server error log for any clues of possible errors or warnings?
this is the html form, it is in public_html, when i type a sequence in the input box it goes to the correct link of the cgi script but i get "internal server error" and also a 404 not found. the problem lies in the cgi script. my boss said that i should try to figure out how to write function oriented scripts. yesterday i was using trial and error and copying cgi scripts that run successfully (in the web browser from the cgi-bin):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
Your Sequence:
<form id="form1" name="form1" method="post" action="">
<label>
<input type="text" name="$inputlength" id="$inputlength" />
</label>
</form>
<form id="form2" name="form2" method="post" action="cgi-bin/tmcalculator.cgi">
<label>
<input type="submit" name="button" id="button" value="Submit" />
</label>
</form>
</body>
</html>
the problem i am having is writing the cgi script (tmcalculator.cgi) so that it will process(?) the sequence (typed into the html form) and calculate the legnth, returning it once the "submit" button is pressed. sorry for the bad language and confusion this is creating...