[24655] in Perl-Users-Digest
Perl-Users Digest, Issue: 6819 Volume: 10
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Tue Aug 3 14:05:58 2004
Date: Tue, 3 Aug 2004 11:05:28 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Tue, 3 Aug 2004 Volume: 10 Number: 6819
Today's topics:
Re: any pointers please? combine words script <me@example.com>
Re: any pointers please? combine words script <nobull@mail.com>
Re: any pointers please? combine words script <nobull@mail.com>
Re: any pointers please? combine words script <xx087@freenet.carleton.ca>
Re: any pointers please? combine words script <nobull@mail.com>
Re: Counting occurances of string A in string B, and ad <nobull@mail.com>
Re: creating shell scripts using #!/usr/local/env perl <uri.guttman@fmr.com>
Re: Variable interpolation on STDIN ? <lv@aol.com>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Tue, 03 Aug 2004 12:32:26 -0400
From: steve_f <me@example.com>
Subject: Re: any pointers please? combine words script
Message-Id: <iafvg0dv24e4gkvt6v5jl576fn247g7res@4ax.com>
Hey Uri...this is what I've got so far. You will notice I am trying to
write more social code ;-)
#!/usr/bin/perl -Tw
use strict;
use CGI::Carp qw(fatalsToBrowser);
use CGI qw/:standard/;
# This script is a cgi application which
# combines words using either one, two
# or three boxes. The idea was inspired
# by using AdWords, which I must admit
# I am a bit tired of marketing and all
# the consumerism on the internet. But it
# did serve as a useful learning vehicle
# Generous help provided by Uri and Brian
# see the online demo at http://www.combinewords.com/in_progress.cgi
# current as of August 8, 2004
# script is in development, so not all functions
# have been realized yet
# what I am trying to do is develop a cgi framework
# gather all the specific info in one place
# the html in another place
# have the ability to get multiple textareas
# and checkboxes
# maintain user state
# etc
# and then reuse the script for rapid development
# of other ideas ;-)
# by the way, I don't know CGI.pm so well, so
# pointers are appreciated
# OK...here we go...
print "Content-type: text/html\n\n";
# grabs the query string to see what
# mode we are in. if there is no
# query string, sets default to mode 2
my $query = $ENV{QUERY_STRING};
if ($query =~ /boxes=(\w+)/) { $query = $1 }
$query ||= 2;
my %modes = (
1 => {
textareas => [ 'kw_1'],
options => [ 'no_quotes', 'quotes', 'brackets', 'skip_space' ],
submit => 'combine one',
},
2 => {
textareas => [ 'kw_1', 'kw_2' ],
options => [ 'no_quotes', 'quotes', 'brackets', 'reverse_words', 'skip_space' ],
submit => 'combine two',
},
3 => {
textareas => [ 'kw_1', 'kw_2', 'kw_3' ],
options => [ 'no_quotes', 'quotes', 'brackets', 'reverse_words', 'skip_space' ],
submit => 'combine three',
}
);
my $html = get_html(); # get html as a string here
# and then do some substitutions on it
# depending on user choice and input
$html =~ s/%title%/$modes{$query}{submit}/;
$html =~ s/%menu%/join " | \n", get_menu($query, "1::combine.cgi?boxes=1",
"2::combine.cgi?boxes=2",
"3::combine.cgi?boxes=3")/e;
$html =~ s/%number%/$query/;
$html =~ s/%textboxes%/join '<br>', get_textareas($query)/e;
$html =~ s/%checkboxes%/join '<br>', get_checkboxes($query)/e;
$html =~ s/%submit%/$modes{$query}{submit}/e;
# more substitutions
# if user inputed keywords
# triggers script manipulations
# for output
#
# also maintaining state by
# filling in boxes and checking
# the checkboxes
if (param()) {
$html =~ s/%output%/join "<br>\n", do_work()/;
$html =~ s/%user_input%/param(kw_1)/g;
$html =~ s/%checked%//g;
} else {
$html =~ s/%output%//;
$html =~ s/%user_input%//g;
$html =~ s/%checked%//g;
}
print $html;
exit (0);
# swap values in the html below are:
# %title% %menu% %number% %textboxes%
# %checkboxes% %submit% %output%
# other swap vaules embedded in functions
# below are:
# %user_input% %checked%
sub get_html {
return '<html>
<head>
<title>
%title%
</title>
</head>
<body>
<table align="center" width="90%">
<tr align="left" valign="middle">
<td valign="top" width="35%">
<b>Combine words</b><small> - choose number of boxes: %menu%</small>
<br><br>
<form action="combine.cgi?boxes=%number%" method=post>
<small><small>
Enter one word or phrase per line
</small></small>
<br>
%textboxes%
</td>
<td valign="top" width="35%">
<br><br><br>
<small>%checkboxes%</small>
<br><br>
<input type=submit value="%submit%">
<br>
</td>
</tr>
</table>
<table align="center" width="90%">
<tr align="left" valign=middle">
<td>
<tt>
%output%
</tt>
</td>
</tr>
</table>
</html>'
}
# menu function takes calling page and menu array
# as input and returns an array of html which needs
# to be joined with a separator...calling example:
# join " | \n", get_menu($query, @menu);
sub get_menu {
my ($source, @menu) = @_;
my @return_array;
for my $item (@menu) {
my ($title, $destination) = split /::/, $item;
$title eq $source ?
push @return_array, "<b>$source</b>" :
push @return_array, qq{<a href="$destination">$title</a>}
} ;
return @return_array;
}
# textareas function takes user chosen mode as input
# returns an array of html which needs to be joined
# with a separator...calling example:
# join "<br>\n", get_textareas($query);
#
# also note returns %user_input_0% %user_input_1% etc
# which needs to be swaped out later
sub get_textareas {
my $choice = shift;
my @textareas;
for my $num (0..$#{ $modes{$choice}{textareas}}) {
$textareas[$num] = qq(<textarea name="$modes{$choice}{textareas}[$num]" rows=9 cols=33>);
$textareas[$num] .= qq(%user_input_$num%</textarea> \n);
}
return @textareas;
}
sub get_checkboxes {
my ($choice) = @_;
my @checkboxes;
for my $num (0..$#{ $modes{$choice}{options}}) {
(my $label = $modes{$choice}{options}[$num]) =~ s/_/ /g;
$checkboxes[$num] = qq(<input type="checkbox" );
$checkboxes[$num] .= qq(name="$modes{$choice}{options}[$num]" );
$checkboxes[$num] .= qq(value="$modes{$choice}{options}[$num]" );
$checkboxes[$num] .= qq(%checked%>);
$checkboxes[$num] .= qq(\u$label\n);
}
return @checkboxes;
}
sub check_checkboxes {
}
------------------------------
Date: 03 Aug 2004 17:42:05 +0100
From: Brian McCauley <nobull@mail.com>
Subject: Re: any pointers please? combine words script
Message-Id: <u93c34fa1u.fsf@wcl-l.bham.ac.uk>
steve_f <me@example.com> writes:
> On 01 Aug 2004 12:44:19 +0100, Brian McCauley <nobull@mail.com> wrote:
>
> >sub simple_merge {
> > my @merged;
> > for (@_) {
> > while (/ /g) {
> > push @merged => substr($_,0,pos()-1).substr($_,pos);
> > }
> > }
> > @merged;
> >}
> >
>
> ok...this looks neat, but I need to walk through each combination:
>
> one two three four
> onetwo three four
> one twothree four
> one two threefour
Your original simple_merge() did not include the original unaltered
input in the output. Neither does my much shorter version. Adding
one line to either version so that is does include the orginial is
trival (and left as a exercise for the reader).
> so I build an index into an array of the location of spaces, and then
> loop through the strings a few times and skip each space in turn.
Yes, I know how you addressed the problem. Tearing a string apart and
treating it as an array of characters is one of a class of
affectations known collectively as "writing C in Perl".
I showed you a more Perlish way to address this problem in Perl.
--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
------------------------------
Date: 03 Aug 2004 18:18:20 +0100
From: Brian McCauley <nobull@mail.com>
Subject: Re: any pointers please? combine words script
Message-Id: <u9smb4dtsz.fsf@wcl-l.bham.ac.uk>
Uri Guttman <uri@stemsystems.com> writes:
> >>>>> "sf" == steve f <me@example.com> writes:
>
> sf> On 2 Aug 2004 11:16:35 GMT, anno4000@lublin.zrz.tu-berlin.de (Anno
> sf> Siegel) wrote:
>
> >> 300 lines of code, and not a word of explanation, except that it is
> >> supposed to "combine words"? Not my idea of fun.
>
> sf> s/sloppy_old_code/great_new_ideas/g
>
> sf> works very well for me!
>
> but not for anyone else.
I think Steve is refering to the fact that by posting a sample of his
code here he was able to learn what people would say was wrong with
his current programming style.
Since this was, I thought, primarily a thread about Steve's
programming style the detils of the particular problem that was being
used as an example didn't seem so important.
That said, a few more comments in the code would not have gone amiss.
> that is called selfish coding. here are a
> couple of coding rules for you to learn:
>
> code is for people, not computers
> code is for OTHER people, not yourself
And those rules are, I hope, some of the great_new_ideas that Steve
will take away with him.
I should also add that often two years down the line the destinction
between yourself and other people is not so sharp :-)
> your code earned an F from me (and you thanked me for my feedback).
It wasn't great code but its failings were inficiencies of design and
implementation that in my mind indicated some degree of inexperience
in programming (both in Perl (treating strings as charater arrays) and
in general (not addressing an obviously recursive problem
recursively)). However these failings did not, for me, mark Steve out
a someone who was fundamentally not able to think as a programmer.
I do not want Steve to get the impression that we are an unfriendly
lot here. Long term watchers of this group will perhaps see this as a
bit of a role-reversal for me. But I assure you it is not. I do not
consider Steve to have been guilty to any great extent of the main
"crimes" of first time posters to this newsgroup.
(OK the subject line could have better :-))
--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
------------------------------
Date: 3 Aug 2004 17:29:49 GMT
From: Glenn Jackman <xx087@freenet.carleton.ca>
Subject: Re: any pointers please? combine words script
Message-Id: <slrncgvise.4bu.xx087@smeagol.ncf.ca>
At 2004-08-03 12:32PM, steve_f <me@example.com> wrote:
> Hey Uri...this is what I've got so far. You will notice I am trying to
> write more social code ;-)
>
> #!/usr/bin/perl -Tw
> use strict;
> use CGI::Carp qw(fatalsToBrowser);
> use CGI qw/:standard/;
[...]
> print "Content-type: text/html\n\n";
If you're going to 'use CGI' then use it:
print header;
[...]
> my $query = $ENV{QUERY_STRING};
> if ($query =~ /boxes=(\w+)/) { $query = $1 }
> $query ||= 2;
If $query can only be numeric, then specify the regex appropriately:
/boxes=(\d+)/
Or, more appropriately, use the CGI module and ignore $ENV{QUERY_STRING}
altogether:
my $query = param('boxes');
if ($query < 1 or $query > 3) {
carp "invalid value for boxes ('$query'): using the default";
$query = 2;
}
--
Glenn Jackman
NCF Sysadmin
glennj@ncf.ca
------------------------------
Date: 03 Aug 2004 18:36:46 +0100
From: Brian McCauley <nobull@mail.com>
Subject: Re: any pointers please? combine words script
Message-Id: <u9oelsdsy9.fsf@wcl-l.bham.ac.uk>
steve_f <me@example.com> writes:
> #!/usr/bin/perl -Tw
> use strict;
Note: unless backward compat is an issue 'use warnings' is better than '-w'.
> # by the way, I don't know CGI.pm so well, so
> # pointers are appreciated
For a starting point read at least the SYNOPSIS in 'perldoc GCI'.
> # OK...here we go...
>
> print "Content-type: text/html\n\n";
Better to use CGI.pm, see the SYNOPSIS in 'perldoc GCI'.
> # grabs the query string to see what
> # mode we are in. if there is no
> # query string, sets default to mode 2
>
> my $query = $ENV{QUERY_STRING};
> if ($query =~ /boxes=(\w+)/) { $query = $1 }
> $query ||= 2;
Better to use CGI.pm, see the SYNOPSIS in 'perldoc GCI'.
> my %modes = (
> 1 => {
> textareas => [ 'kw_1'],
> options => [ 'no_quotes', 'quotes', 'brackets', 'skip_space' ],
> submit => 'combine one',
> },
> 2 => {
> textareas => [ 'kw_1', 'kw_2' ],
> options => [ 'no_quotes', 'quotes', 'brackets', 'reverse_words', 'skip_space' ],
> submit => 'combine two',
> },
> 3 => {
> textareas => [ 'kw_1', 'kw_2', 'kw_3' ],
> options => [ 'no_quotes', 'quotes', 'brackets', 'reverse_words', 'skip_space' ],
> submit => 'combine three',
> }
> );
>
> my $html = get_html(); # get html as a string here
>
> # and then do some substitutions on it
> # depending on user choice and input
Hmmm... rolling your own templating system. I'll let someone else
jump on you for that.
> $html =~ s/%title%/$modes{$query}{submit}/;
> $html =~ s/%menu%/join " | \n", get_menu($query, "1::combine.cgi?boxes=1",
> "2::combine.cgi?boxes=2",
> "3::combine.cgi?boxes=3")/e;
> $html =~ s/%number%/$query/;
> $html =~ s/%textboxes%/join '<br>', get_textareas($query)/e;
> $html =~ s/%checkboxes%/join '<br>', get_checkboxes($query)/e;
> $html =~ s/%submit%/$modes{$query}{submit}/e;
The /e is redundant (but harmless).
> # also maintaining state by
> # filling in boxes and checking
> # the checkboxes
>
> if (param()) {
> $html =~ s/%output%/join "<br>\n", do_work()/;
Missing /e
> $html =~ s/%user_input%/param(kw_1)/g;
Missing /e
Missing quotes.
Forgot to HTMLescape the user's input.
> $html =~ s/%checked%//g;
> } else {
> $html =~ s/%output%//;
> $html =~ s/%user_input%//g;
> $html =~ s/%checked%//g;
> }
Why the if--else? Why not simply arrange that it "does the right
thing" for empty parameters.
> sub get_html {
> return '<html>
[ lots of text ]
> </html>'
> }
Some people would suggest a here-document or a DATA file.
> push @return_array, qq{<a href="$destination">$title</a>}
Are you sure you don't want appropriate escaping of $destination and
$title?
--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
------------------------------
Date: 03 Aug 2004 17:46:03 +0100
From: Brian McCauley <nobull@mail.com>
Subject: Re: Counting occurances of string A in string B, and adding it to string B
Message-Id: <u9y8kwdvas.fsf@wcl-l.bham.ac.uk>
Uri Guttman <uri@stemsystems.com> writes:
> >>>>> "JR" == J Romano <jl_post@hotmail.com> writes:
>
> JR> Sandman <mr@sandman.net> wrote in message news:<mr-CF69F0.12533903082004@individual.net>...
> JR> Yes! You can use the /e and /g switches with s// to make a nice
> JR> elegant substitution:
>
> JR> $_ = "A horse is a horse is a horse, on a horseman";
> JR> $n = 0;
> JR> s/\b(horse\w*)/"$1 (" . ++$n .")"/ge;
>
> since you can put as much code as you want with /e (which uses the last
> value of the code block), make it easier to read:
>
> s/\b(horse\w*)/$n++ ; "$1 ($n)"/ge;
TIMTOWDI
s/\b(horse\w*)/$1 (@{[ ++$n ]})/g;
--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
------------------------------
Date: Tue, 03 Aug 2004 13:50:00 -0400
From: Uri Guttman <uri.guttman@fmr.com>
Subject: Re: creating shell scripts using #!/usr/local/env perl
Message-Id: <lid628kt6f.fsf@fmr.com>
>>>>> "AS" == Anno Siegel <anno4000@lublin.zrz.tu-berlin.de> writes:
AS> Unix shells have a built-in command to read a file and interpret the
AS> content as commands in the currently running shell. With Bourne-like
AS> shells, this command is ".", so the process may be called the "dot
AS> method". (With csh-like shells, the command is "source".)
and perl spells it 'do $file' :)
uri
------------------------------
Date: Tue, 03 Aug 2004 11:50:30 -0500
From: l v <lv@aol.com>
Subject: Re: Variable interpolation on STDIN ?
Message-Id: <410fc253$1_5@corp.newsgroups.com>
Abhinav wrote:
> Ala Qumsieh wrote:
>
>> Abhinav wrote:
>>
>>> if (-e $fileToCheck)
>>> {
>>> print "Not Found\n";
>>> }
>>
>>
>>
>> -e returns true if the file exists. You have your logic all mixed up.
>>
>
> Another reason not to type in code..even if it is just a conceptual thing.
>
> That should have read !e ..
>
> As the other posts imply, the problem lay elsewhere.
>
> [...]
When Perl interprets *if (!-e "$fileToCheck")* $fileToCheck contains the
string * $ENV{HOME}/x.pl *. It sounds like you are expecting $ENV{HOME}
to be interpreted by Perl again.
Therefore, as Anno indirectly suggested ....
perldoc -q 'How can I expand variables in text strings?'
Len
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 100,000 Newsgroups - 19 Different Servers! =-----
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
#The Perl-Users Digest is a retransmission of the USENET newsgroup
#comp.lang.perl.misc. For subscription or unsubscription requests, send
#the single line:
#
# subscribe perl-users
#or:
# unsubscribe perl-users
#
#to almanac@ruby.oce.orst.edu.
NOTE: due to the current flood of worm email banging on ruby, the smtp
server on ruby has been shut off until further notice.
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
#To request back copies (available for a week or so), send your request
#to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
#where x is the volume number and y is the issue number.
#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V10 Issue 6819
***************************************