⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch29.htm

📁 《Perl 5 Unreleased》
💻 HTM
📖 第 1 页 / 共 4 页
字号:
<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">&nbsp;1 #!/usr/bin/perl<BR>

&nbsp;2<BR>

&nbsp;3 #<BR>

&nbsp;4 # Simple statistical functions in Perl<BR>

&nbsp;5 #<BR>

&nbsp;6<BR>

&nbsp;7 use Getopt::Long;<BR>

&nbsp;8<BR>

&nbsp;9 #----------------------------------------------------------------

<BR>

10 #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Declare

any subroutines here<BR>

11 #----------------------------------------------------------------

<BR>

12 sub toPolar($$);&nbsp;&nbsp;&nbsp;# Declare as taking two scalars

<BR>

13 sub toRect($$);&nbsp;&nbsp;&nbsp;&nbsp;# Declare as taking

two scalars<BR>

14<BR>

15 *PI&nbsp;&nbsp;= \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) = &amp;toPolar($x,$y);<BR>

26<BR>

27 printf &quot;The polar coordinates for %6.3f,%6.3f are \n&quot;,

$x,$y;<BR>

28 printf &quot;&nbsp;&nbsp;&nbsp;&nbsp;r = %6.3f and theta %6.3f

or %6.3f degrees\n&quot;,<BR>

29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$r,$theta,

$theta * $TODEG;<BR>

30<BR>

31 ($x1,$y1) = toRect($r,$theta);<BR>

32<BR>

33 printf &quot;Compare x,y (%6.3f,%6.3f) with&nbsp;&nbsp;&quot;,

$x, $y, $x1, $y1;<BR>

34 printf &quot; x1,y1 (%6.3f,%6.3f) \n&quot;, $x, $y, $x1, $y1;

<BR>

35<BR>

36<BR>

37 sub toPolar {&nbsp;&nbsp;&nbsp;# ($$);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#

Declare as taking two scalars<BR>

38&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my ($x,$y) = @_;<BR>

39&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $r;<BR>

40&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $t;<BR>

41<BR>

42&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$r = sqrt( $x * $x + $y

+ $y ) ;<BR>

43&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$t = atan2($y,$x);<BR>

44<BR>

45&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return($r,$t);<BR>

46<BR>

47 }<BR>

48 sub toRect&nbsp;&nbsp;{&nbsp;&nbsp;#($$);&nbsp;&nbsp; # Declare

as taking two scalars<BR>

49&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my ($r,$t) = @_;<BR>

50&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $x;<BR>

51&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $y;<BR>

52<BR>

53&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$x = $r * cos($t);<BR>

54&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$y = $r * sin($t);<BR>

55<BR>

56&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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">&nbsp;1 #!/usr/bin/perl<BR>

&nbsp;2<BR>

&nbsp;3<BR>

&nbsp;4 #<BR>

&nbsp;5 # Simple statistical functions in Perl<BR>

&nbsp;6 #<BR>

&nbsp;7<BR>

&nbsp;8 use Getopt::Long;<BR>

&nbsp;9<BR>

10 #----------------------------------------------------------------

<BR>

11 #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Declare

any subroutines here<BR>

12 #----------------------------------------------------------------

<BR>

13 sub stats(\@);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Declare as taking

reference to array.<BR>

14<BR>

15<BR>

16 GetOptions('file=s');<BR>

17 open (DATA,&quot;$opt_file&quot;) || die &quot;Cannot open

$opt_file \n&quot;;<BR>

18<BR>

19 $i = 0;<BR>

20 while ($line = &lt;DATA&gt;)<BR>

21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>

22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chop $line;<BR>

23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;($date,$hi[$i],$lo[$i],$day[$i])

= split(' ',$line);<BR>

24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$i++;<BR>

25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>

26<BR>

27 ($ave,$max,$min,$std) = &amp;stats(\@day);<BR>

28<BR>

29 printf &quot; Average = %6.2lf \n&quot;, $ave;<BR>

30 printf &quot; Maximum = %6.2lf \n&quot;, $max;<BR>

31 printf &quot; Minimum = %6.2lf \n&quot;, $min;<BR>

32 printf &quot; Std Dev = %6.2lf \n&quot;, $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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

43&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Allow passing of array

either by reference or<BR>

44&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# by its values.<BR>

45&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

46&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $a = ref($_[0]) ? $_[0]

: \@_;<BR>

47&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $count = $#{$a} + 1;

<BR>

48<BR>

49&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

50&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Bail out in case of erroneous

data.<BR>

51&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

52&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(-1,-1,-1,-1) if ($count

&lt; 2);<BR>

53<BR>

54&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print &quot;$count items

\n&quot;;<BR>

55&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $i;<BR>

56<BR>

57&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

58&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Initialize local variables.

The assignment to 0<BR>

59&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# is unnecessary for all

scalars except $max and $min<BR>

60&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# since Perl will initialize

them to zero for you.<BR>

61&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

62&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $min = $$a[0];<BR>

63&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $max = $$a[0];<BR>

64&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $sum = 0;<BR>

65&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $sum2 = 0;<BR>

66&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $ave = 0;<BR>

67&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my $std = 0;<BR>

68<BR>

69&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

70&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Get the required statistics

<BR>

71&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

72&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for $i (@$a) {<BR>

73&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$sum

+= $i;<BR>

74&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$sum2

+= ($i * $i);<BR>

75&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$max

= $i if ($max &lt; $i);<BR>

76&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$min

= $i if ($min &gt; $i);<BR>

77&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>

78&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ave = $sum/$count;<BR>

79&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$std = (($sum2 - $sum *

$ave)/($count - 1));<BR>

80&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

81&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Return the list of values

back from function.<BR>

82&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#<BR>

83&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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>, &quot;A Brief Introduction to

Perl.&quot; 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 + -