📄 ch29.htm
字号:
<HTML>
<HEAD>
<TITLE>Chapter 29 -- Practical Scripts While Using
Perl</TITLE>
<META NAME="GENERATOR" CONTENT="Mozilla/3.0b5aGold (WinNT; I) [Netscape]">
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#CE2910">
<H1><FONT COLOR=#FF0000>Chapter 29</FONT></H1>
<H1><B><FONT SIZE=5 COLOR=#FF0000>Practical Scripts While Using
Perl</FONT></B>
</H1>
<P>
<HR WIDTH="100%"></P>
<P>
<H3 ALIGN=CENTER><FONT COLOR="#000000"><FONT SIZE=+2>CONTENTS<A NAME="CONTENTS"></A>
</FONT></FONT></H3>
<UL>
<LI><A HREF="#StatisticalApplications" >Statistical Applications</A>
<LI><A HREF="#UsingPerlforSimpleStatisticalRoutin" >Using Perl for Simple Statistical Routines</A>
<UL>
<LI><A HREF="#DotandCrossProductsofVectors" >Dot and Cross Products of Vectors</A>
<LI><A HREF="#AddingorSubtractingVectors" >Adding or Subtracting Vectors</A>
</UL>
<LI><A HREF="#UsingMatrices" >Using Matrices</A>
<UL>
<LI><A HREF="#ReadingtheImage" >Reading the Image</A>
<LI><A HREF="#GettingaHistogram" >Getting a Histogram</A>
</UL>
<LI><A HREF="#TheFilter" >The Filter</A>
<LI><A HREF="#AnAddedTouch" >An Added Touch</A>
<LI><A HREF="#APartingNote" >A Parting Note</A>
<LI><A HREF="#Summary" >Summary</A>
</UL>
<HR>
<P>
Perl is a powerful language for prototyping applications. This
chapter introduces you to implementing some practical algorithms
using Perl as the base language. Once you have tested your algorithm
you can use another faster language, but during testing the Perl
interpreter will provide a quick turnaround for testing and debugging.
<H2><A NAME="StatisticalApplications"><B><FONT SIZE=5 COLOR=#FF0000>Statistical
Applications</FONT></B></A></H2>
<P>
Perl programs can call the standard math library functions to
give you greater computing power. The following functions are
available to you as standard calls. All values of these functions
are sent and returned as radians:<P>
<CENTER>
<TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%>
<TR VALIGN=TOP><TD WIDTH=118><TT><FONT FACE="Courier">Atan2($y,$x);</FONT></TT>
</TD><TD WIDTH=472>Returns the arc tangent in radians of the value of <TT><FONT FACE="Courier">$y/$x</FONT></TT>. The value returned is always between <TT><FONT FACE="Courier">PI</FONT></TT> and <TT><FONT FACE="Courier">-PI</FONT></TT>. There is no
<TT><FONT FACE="Courier">atan()</FONT></TT> function because of the floating-point error problem.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=118><TT><FONT FACE="Courier">cos($x);</FONT></TT>
</TD><TD WIDTH=472>Returns cosine of <TT><FONT FACE="Courier">$x</FONT></TT>.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=118><TT><FONT FACE="Courier">sin($x);</FONT></TT>
</TD><TD WIDTH=472>Returns sine of <TT><FONT FACE="Courier">$x</FONT></TT>.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=118><TT><FONT FACE="Courier">sqrt($x);</FONT></TT>
</TD><TD WIDTH=472>Returns the square root of <TT><FONT FACE="Courier">$x</FONT></TT>.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=118><TT><FONT FACE="Courier">log($x);</FONT></TT>
</TD><TD WIDTH=472>Returns the natural log of <TT><FONT FACE="Courier">$x</FONT></TT>.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=118><TT><FONT FACE="Courier">exp($x);</FONT></TT>
</TD><TD WIDTH=472>Returns e to the power of <TT><FONT FACE="Courier">$x</FONT></TT>.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=118><TT><FONT FACE="Courier">srand($x);</FONT></TT>
</TD><TD WIDTH=472>Seeds the random number generator.</TD></TR>
<TR VALIGN=TOP><TD WIDTH=118><TT><FONT FACE="Courier">rand($x);</FONT></TT>
</TD><TD WIDTH=472>Generates a random number based on the seed.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=118><TT><FONT FACE="Courier">time;</FONT></TT></TD>
<TD WIDTH=472>Returns the number of seconds since Jan. 1, 1970.
</TD></TR>
<TR VALIGN=TOP><TD WIDTH=118><TT><FONT FACE="Courier">int($x);</FONT></TT>
</TD><TD WIDTH=472>Returns the integer portion of <TT><FONT FACE="Courier">$x</FONT></TT>. To get the fraction portion, use <TT><FONT FACE="Courier">$x - int($x);</FONT></TT>.
</TD></TR>
</TABLE></CENTER>
<P>
<P>
For most applications, these routines will suffice. Perl is linked
with the math libraries for this function. Please check the <TT><FONT FACE="Courier">man</FONT></TT>
pages for the details of how to use these standard library functions.
<P>
Listing 29.1 presents a simple application that uses two subroutines
to convert from polar to rectangular coordinates and then back
again.
<HR>
<BLOCKQUOTE>
<B>Listing 29.1. Using the math functions in Perl.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 #!/usr/bin/perl<BR>
2<BR>
3 #<BR>
4 # Simple statistical functions in Perl<BR>
5 #<BR>
6<BR>
7 use Getopt::Long;<BR>
8<BR>
9 #----------------------------------------------------------------
<BR>
10 # Declare
any subroutines here<BR>
11 #----------------------------------------------------------------
<BR>
12 sub toPolar($$); # Declare as taking two scalars
<BR>
13 sub toRect($$); # Declare as taking
two scalars<BR>
14<BR>
15 *PI = \3.1415926;<BR>
16 *PIBY2 = $PI / 2;<BR>
17 *TODEG = \57.2958;<BR>
18 *TORAD = \0.01745;<BR>
19<BR>
20 GetOptions('x=i', 'y=i');<BR>
21<BR>
22 $x = $opt_x;<BR>
23 $y = $opt_y;<BR>
24<BR>
25 ($r,$theta) = &toPolar($x,$y);<BR>
26<BR>
27 printf "The polar coordinates for %6.3f,%6.3f are \n",
$x,$y;<BR>
28 printf " r = %6.3f and theta %6.3f
or %6.3f degrees\n",<BR>
29 $r,$theta,
$theta * $TODEG;<BR>
30<BR>
31 ($x1,$y1) = toRect($r,$theta);<BR>
32<BR>
33 printf "Compare x,y (%6.3f,%6.3f) with ",
$x, $y, $x1, $y1;<BR>
34 printf " x1,y1 (%6.3f,%6.3f) \n", $x, $y, $x1, $y1;
<BR>
35<BR>
36<BR>
37 sub toPolar { # ($$); #
Declare as taking two scalars<BR>
38 my ($x,$y) = @_;<BR>
39 my $r;<BR>
40 my $t;<BR>
41<BR>
42 $r = sqrt( $x * $x + $y
+ $y ) ;<BR>
43 $t = atan2($y,$x);<BR>
44<BR>
45 return($r,$t);<BR>
46<BR>
47 }<BR>
48 sub toRect { #($$); # Declare
as taking two scalars<BR>
49 my ($r,$t) = @_;<BR>
50 my $x;<BR>
51 my $y;<BR>
52<BR>
53 $x = $r * cos($t);<BR>
54 $y = $r * sin($t);<BR>
55<BR>
56 return($x,$y);<BR>
57 }<BR>
58</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
At line 37, the subroutine <TT><FONT FACE="Courier">toPolar</FONT></TT>
uses a prototype to specify two input parameters using the <TT><FONT FACE="Courier">($$)</FONT></TT>
construct. Similarly, the <TT><FONT FACE="Courier">toRect</FONT></TT>
function also takes two parameters with the <TT><FONT FACE="Courier">($$)</FONT></TT>
prototype. Both functions return two items each. The constants
declared in lines 17 and 18 are not used in this program but are
included only for reference or future use should you need them.
<H2><A NAME="UsingPerlforSimpleStatisticalRoutin"><B><FONT SIZE=5 COLOR=#FF0000>Using
Perl for Simple Statistical Routines</FONT></B></A></H2>
<P>
Let's add some more functionality to what you have just developed
in the code in Listing 29.1. Let's start by adding some simple
statistical routines.
<P>
Perhaps the most common function to perform on a list of numeric
values is to calculate the average and standard deviation. Listing
29.2 presents a function that returns these values given an array
of items.
<HR>
<BLOCKQUOTE>
<B>Listing 29.2. Calculating the average and standard deviation.
<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 #!/usr/bin/perl<BR>
2<BR>
3<BR>
4 #<BR>
5 # Simple statistical functions in Perl<BR>
6 #<BR>
7<BR>
8 use Getopt::Long;<BR>
9<BR>
10 #----------------------------------------------------------------
<BR>
11 # Declare
any subroutines here<BR>
12 #----------------------------------------------------------------
<BR>
13 sub stats(\@); # Declare as taking
reference to array.<BR>
14<BR>
15<BR>
16 GetOptions('file=s');<BR>
17 open (DATA,"$opt_file") || die "Cannot open
$opt_file \n";<BR>
18<BR>
19 $i = 0;<BR>
20 while ($line = <DATA>)<BR>
21 {<BR>
22 chop $line;<BR>
23 ($date,$hi[$i],$lo[$i],$day[$i])
= split(' ',$line);<BR>
24 $i++;<BR>
25 }<BR>
26<BR>
27 ($ave,$max,$min,$std) = &stats(\@day);<BR>
28<BR>
29 printf " Average = %6.2lf \n", $ave;<BR>
30 printf " Maximum = %6.2lf \n", $max;<BR>
31 printf " Minimum = %6.2lf \n", $min;<BR>
32 printf " Std Dev = %6.2lf \n", $std;<BR>
33<BR>
34 close DATA;<BR>
35<BR>
36<BR>
37 #<BR>
38 # Compute simple stats on incoming stream.<BR>
39 #<BR>
40<BR>
41 sub stats {<BR>
42 #<BR>
43 # Allow passing of array
either by reference or<BR>
44 # by its values.<BR>
45 #<BR>
46 my $a = ref($_[0]) ? $_[0]
: \@_;<BR>
47 my $count = $#{$a} + 1;
<BR>
48<BR>
49 #<BR>
50 # Bail out in case of erroneous
data.<BR>
51 #<BR>
52 return(-1,-1,-1,-1) if ($count
< 2);<BR>
53<BR>
54 print "$count items
\n";<BR>
55 my $i;<BR>
56<BR>
57 #<BR>
58 # Initialize local variables.
The assignment to 0<BR>
59 # is unnecessary for all
scalars except $max and $min<BR>
60 # since Perl will initialize
them to zero for you.<BR>
61 #<BR>
62 my $min = $$a[0];<BR>
63 my $max = $$a[0];<BR>
64 my $sum = 0;<BR>
65 my $sum2 = 0;<BR>
66 my $ave = 0;<BR>
67 my $std = 0;<BR>
68<BR>
69 #<BR>
70 # Get the required statistics
<BR>
71 #<BR>
72 for $i (@$a) {<BR>
73 $sum
+= $i;<BR>
74 $sum2
+= ($i * $i);<BR>
75 $max
= $i if ($max < $i);<BR>
76 $min
= $i if ($min > $i);<BR>
77 }<BR>
78 $ave = $sum/$count;<BR>
79 $std = (($sum2 - $sum *
$ave)/($count - 1));<BR>
80 #<BR>
81 # Return the list of values
back from function.<BR>
82 #<BR>
83 return ($ave,$max,$min,$std);
<BR>
84 }</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
Look at line 23 in Listing 29.2. The data is stripped off into
columns for you to work with. The format of the data file has
the list of data points for each item in separate columns.
<P>
Also note that we are forcing the user to type in <TT><FONT FACE="Courier">file=<I>something</I></FONT></TT>
for this program to work. If you never intend on passing any parameters
to this program via the use of options, then it's better to use
<TT><FONT FACE="Courier">ARGV[1]</FONT></TT>. However, you will
have to take care of things like missing or malformed strings
in <TT><FONT FACE="Courier">ARGV[1]</FONT></TT>.
<P>
The <TT><FONT FACE="Courier">stats</FONT></TT> subroutine is also
defined via a prototype in line 13. Prototypes are discussed in
<A HREF="ch2.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch2.htm" >Chapter 2</A>, "A Brief Introduction to
Perl." The <TT><FONT FACE="Courier">stats</FONT></TT> subroutine
is shown to take only one parameter, which is a pointer to an
array.
<P>
Note how the input parameter to the <TT><FONT FACE="Courier">stats</FONT></TT>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -