How do you write a perl script to determine the number of measurements, average, variance, standard deviation?
This is the script that I have so far and it is not working.

my @data = (6, 9, 7, 23, 30, 18);
my @data2 = (10, 5, 8, 11);
my @data3 = (12, 15, 13, 19, 5, 8, 10);
Data_info('Info',@data);
Data_info('Info',@data2);
Data_info('Info',@data3);

sub Data_info{
my($Data_info,@activity) = @_;
my ($num)=@Data_info +0;
my ($sum)=0;
my ($sqsum)=0;
foreach $x (@Data_info) {
$sum += $x;

$sqsum += $x * $x;

}

my ($avg)=$sum/$num;
my ($var)=$sqsum/$num-$avg*$avg;
my ($stand_dev)=sqrt ($var);

print "$Data_info:\n",
"Number of measurements = $num\n",
"Average = $avg\n",
"Variance = $var\n",
"Standard Deviation = $stand_dev\n\n";

How do you write a perl script to determine the number of measurements, average, variance, standard deviation?
This is the script that I have so far and it is not working.

my @data = (6, 9, 7, 23, 30, 18);
my @data2 = (10, 5, 8, 11);
my @data3 = (12, 15, 13, 19, 5, 8, 10);
Data_info('Info',@data);
Data_info('Info',@data2);
Data_info('Info',@data3);

sub Data_info{
my($Data_info,@activity) = @_;
my ($num)=@Data_info +0;
my ($sum)=0;
my ($sqsum)=0;
foreach $x (@Data_info) {
$sum += $x;

$sqsum += $x * $x;

}

my ($avg)=$sum/$num;
my ($var)=$sqsum/$num-$avg*$avg;
my ($stand_dev)=sqrt ($var);

print "$Data_info:\n",
"Number of measurements = $num\n",
"Average = $avg\n",
"Variance = $var\n",
"Standard Deviation = $stand_dev\n\n";

  • Please post your script between [code]

    [/code] tags.

  • Two statements to include in your script are use strict; and use warnings;
  • Why are you passing a literal 'Info' to your subroutine with your array?
  • Remember that when you pass more than one argument to a subroutine, all the arguments are combined into one array. This is one reason your script doesn't work.
  • It's better to return a value from a subroutine and assign the value to a variable in the calling statement.

You can google perl calculate average and copy a pretty good subroutine from wiki.answers.com and call it like this:

#!/usr/bin/perl
use strict;
use warnings;

my @data = (6, 9, 7, 23, 30, 18);

my $avg = average(\@data);
print "The average is $avg \n";

sub average {
@_ == 1 or die ('Sub usage: $average = average(\@array);');
my ($array_ref) = @_;
my $sum;
my $count = scalar @$array_ref;
foreach (@$array_ref) { $sum += $_; }
return $sum / $count;
}

To understand how the subroutine works, it helps to read something explaining how to turn arrays into array references, and array references back into arrays, such as http://perldoc.perl.org/perlreftut.html

David,

My link to that perl module does everything stat-wise, including standard deviation. I guess it begs the question: WHY is he writing the program? It's it for a class assignment? To show someone else he can program in perl? I don't know why, but IMO I always try to go to CPAN to set if someone else has written it, and if so, it's probably better than I can write :-)

Mike

Thanks for all of the suggestions but when I put in "use Statistics:Descriptive" it is not working. I have to do this for class and wanted to fix it. I

The issue that came up on my original script was that there was illegal division by 0. I don't think I am allowed to install a module so I am trying my best to fix the original script. I have to calculate the number of measurements, variance, average, and standard deviation of @data, @data2, and @data3. I don't know why this is giving me so much trouble but it is.

What you need to do on Windows (if you're using active state perl) is go to the command line and type "ppm". If it doesn't run, go to c:\perl\bin and type "ppm" (without the quotes of course). Then add the uwinnipeg and trouchelle repositories to Edit -> Preferences -> Repositories. It should synch the package list. Then, exit ppm and go to the command line and type

ppm install Statistics::Descriptive

. That should install the package. If this is a school computer and you can't do that, download the source and put it in the directory that you code runs (which is not ideal, but should work).

use strict;
use warnings;
use Statistics::Descriptive;

my @data = (6, 9, 7, 23, 30, 18);
my @data2 = (10, 5, 8, 11);
my @data3 = (12, 15, 13, 19, 5, 8, 10);
my @clear;


my $stat = Statistics::Descriptive::Full->new();
$stat->add_data(@data); 
my $mean = $stat->mean();
my $var  = $stat->variance();
my $sd = $stat->standard_deviation();
print "Data1: mean: $mean\nvariance $var\nStd Deviation: $sd\n";
$stat->add_data(@clear);
$stat->add_data(@data2); 
$mean = $stat->mean();
$var  = $stat->variance();
$sd = $stat->standard_deviation();
print "Data2: mean: $mean\nvariance $var\nStd Deviation: $sd\n";
$stat->add_data(@clear);
$stat->add_data(@data3); 
$mean = $stat->mean();
$var  = $stat->variance();
$sd = $stat->standard_deviation();
print "Data3: mean: $mean\nvariance $var\nStd Deviation: $sd\n";

Output:

Data1: mean: 15.5
variance 95.5
Std Deviation: 9.77241014284603
Data2: mean: 12.7
variance 68.4555555555556
Std Deviation: 8.27378725587959
Data3: mean: 12.2941176470588
variance 46.7205882352941
Std Deviation: 6.83524602595211

David,

My link to that perl module does everything stat-wise, including standard deviation. I guess it begs the question: WHY is he writing the program? It's it for a class assignment? To show someone else he can program in perl? I don't know why, but IMO I always try to go to CPAN to set if someone else has written it, and if so, it's probably better than I can write :-)

Mike

Mike,

I agree that to do a commonly-required task in perl it makes a lot of sense to look for a module on CPAN that does it instead of struggling to re-invent the wheel. If I needed to calculate standard deviation I would definitely take your advice and use Statistics::Descriptive.

My reply above assumes that the problem is a school assignment that doesn't allow using module methods to do the required calculations (although I still think the teacher should insist on use strict; and use warnings; as good progr.amming practice.) I don't intend to do the assignment myself, of course. My example tries to show the right way to pass arguments to a subroutine and return a value nicely -- instead of a subroutine that creates a bunch of global variables. Subroutines assigning results to global variables can get the job done but tend too make scripts difficult to understand and debug.

I agree that to accomplish a task at work or for some goal other than practising the writing of subroutines, the first step is to look for modules that do the task. Programmers who insist on writing their own subroutines to calculate common statistical functions are wasting their employers time.

David,

I thought this was a school project as well, but it appears to be more of a stats project than a programming one (or maybe both). I think newbies DO need to know that CPAN exists - in some ways it's probably the biggest strength of perl. And yes, his programming of global variables, etc. was not good practice.

Mike

It is correct that I am not allowed to install modules. I am new to writing Perl scripts and understanding subroutines. I got stuck and still do not understand why I am receiving the message about illegal division. I thought may be I have to create different subroutines for standard deviation, average, number of measurements, and variance but am unsure.

This article has been dead for over six months. Start a new discussion instead.