[28833] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 77 Volume: 11

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Fri Jan 26 03:06:42 2007

Date: Fri, 26 Jan 2007 00:05:05 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)

Perl-Users Digest           Fri, 26 Jan 2007     Volume: 11 Number: 77

Today's topics:
    Re: appending to a global filehandle <someone@example.com>
    Re: appending to a global filehandle <jgibson@mail.arc.nasa.gov>
        Bus error <pallavgupta@gmail.com>
    Re: MacPerl, OS 9, move file to Trash <jgibson@mail.arc.nasa.gov>
    Re: MacPerl, OS 9, move file to Trash <spamtrap@dot-app.org>
    Re: Net::FTPSSL problem (or how to do FTP over SSL anot <dsiomtw@gmail.com>
        new CPAN modules on Fri Jan 26 2007 (Randal Schwartz)
    Re: String Substitution question <tadmc@augustmail.com>
    Re: String Substitution question (NOSPAM)
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: Fri, 26 Jan 2007 02:28:40 GMT
From: "John W. Krahn" <someone@example.com>
Subject: Re: appending to a global filehandle
Message-Id: <sHduh.155926$rv4.43357@edtnps90>

markpark wrote:
> i have a function called writedata and, inside the function, some
> things get calculated ( details  not important )  and then a
> file gets opened and written to. but this function is called over
> and over and what i want to do is keep appending to the same file.
> but, it seems like using the >> doesn't help because the files becomes
> empty once the routine is exited ?

No, using the mode '>>' does *NOT* empty the file.  Perhaps some other code in
your program is emptying the file?


> is there some way to deal with this ? I am very much a novice in perl
> and much of the code below was cut and pasted form other people's
> programs.  i definitely don't want to give the false impression that
> i know what i am doing.
> 
> i guess that i need to make the filehandle global somehow but i'm not
> clear on how to do that ?

Filehandles are package variables so they are visible throughout the current
package (main).


> or maybe send it in as a parameter ?

perldoc -q "How do I pass filehandles between subroutines"




John
-- 
Perl isn't a toolbox, but a small machine shop where you can special-order
certain sorts of tools at low cost and in short order.       -- Larry Wall


------------------------------

Date: Thu, 25 Jan 2007 18:51:07 -0800
From: Jim Gibson <jgibson@mail.arc.nasa.gov>
Subject: Re: appending to a global filehandle
Message-Id: <250120071851074994%jgibson@mail.arc.nasa.gov>

In article <1169775580.255085.276330@a75g2000cwd.googlegroups.com>,
markpark <mark.leeds@morganstanley.com> wrote:

> i have a function called writedata and, inside the function, some
> things
> get calculated ( details  not important )

Sorry. Details are often important. If you don't show us the whole
program, there is not much point in trying to help you. We could easily
be diagnosing the wrong problem.

> and then a  file gets opened
> and written to. but this function
> is called over and over and what i want to do is keep appending to the
> same file.
> but, it seems like using the >> doesn't help because the files becomes
> empty
> once the routine is exited ?

That is not true for a correctly-written program. The devil is in the
details.

> 
> is there some way to deal with this ? I am very much a novice in perl
> and
> much of the code below was cut and pasted form other people's programs.
> i definitely don't want to
> give the false impression that i know what i am doing.
> 
> i guess that i need to make the filehandle global somehow but i'm not
> clear on how to do that ?
> or maybe send it in as a parameter ? thank you very much for any help
> that can be provided.

Bareword file handles are global. You could also declare the file
handle as a lexical variable, but at file scope. Or you could declare
the file handle in the calling program and pass it as a variable.
However, you don't need to do any of those things if you want to append
to the file. Of course, your program will run more quickly if you keep
the file open instead of opening and closing it many times.

> 
> # MAIN PROGRAM ( not quite but this gives the idea )

You need to show us a complete, minimal program that demonstrates the
problem you are having.

> 
> foreach (my $bin=$exchMap->{$Exch}{s2}; $bin<=$exchMap->{$Exch}{e2};
> $bin++) {
>     my $cMap={};

Although 'foreach' is a synonym for 'for', most people would use 'for'
here.

> 
> writedata($date,$cnt,$Exch,$bin,$cMap,$bMap,$prevMap,$ewmaMap,$cnddir);
>     $cnt++;
>   }
> 
> # END OF MAIN PROGRAM
> 
> 
> sub writedata {
>   my $date = shift;
>   my $cnt = shift;
>   my $exch = shift;
>   my $bin  = shift;
>   my $cMap = shift;
>   my $bMap = shift;
>   my $prevMap = shift;
>   my $ewmaMap = shift;
>   my $cnddir = shift;

Replace those lines with:

  my( $date, $cnt, ... , $cndir) = @_;

> 
>  my $outf = $cnddir . "/$exch" . "." . "dailyfile.txt";

  my $outf = "$cnddir/$exch.dailyfile.txt";

What is in $cnddir and $exch? This could be a problem, but we don't
know.

> 
>   open (OUTF,">> $outf") || die "could not open $outf";

  open(my $outfh, '>>', $outf ) or die "could not open $outf: $!";

> 
>   foreach my $xid (keys %{$cMap}) {
>     if (! exists($bMap->{$xid})) { next; }

  next unless exists($bMap->{$xid};

> 

[37 irrelevant lines snipped]

> 
>     print OUTF
> "$xid,$te,$code,$ca,$cb,$ccp,$hp,$lp,$totvs,$r,$deltar,$deltavs,$ewma2,$ewma5,$ewma10,$ewma20,$ewma30,$ewma40,$ewma50,$ewma60,$ewma90,$ewma120\n";

This should work. I see no problem in the code that you have posted
(except stylistics ones). The problem must lie in the code that you
have not shown us.

> 
>     $prevMap->{$xid}{ret}=$r;
>     $prevMap->{$xid}{totvs}=$totvs;
>   }
> 
>   close(OUTF);
> }
> 

The following works on my system:

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

for ( 
  my $bin = 0; 
  $bin <= 10;
  $bin++
) {
  writedata($bin);
}

sub writedata {
  my $cnt = shift;
  my $outf = "./dailyfile.txt";
  open (OUTF,">> $outf") || die "could not open $outf";
  print OUTF "$cnt\n";
  close(OUTF);
}

If this doesn't work on your system, then you have a problem with your
Perl installation or file system. Try reducing your program down to a
minimal example that still demonstrates the problem. If you can do
that, post it here and someone will surely be able to help you.

Good luck!

-- 
Jim Gibson

 Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
    ** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------        
                http://www.usenet.com


------------------------------

Date: 25 Jan 2007 18:58:31 -0800
From: "pallav" <pallavgupta@gmail.com>
Subject: Bus error
Message-Id: <1169780311.365367.150850@a75g2000cwd.googlegroups.com>

I have to MAC OS X machines running 10.4.8 (tiger) with perl version
5.8.6. I have a gradebook script that computes some statistics to
student grades etc.

When I run this script on one machine, everything runs fine. But on the
second machine,
I continually get a "Bus error" and there is no diagnostics so I don't
know what to do from here.

I looked at the versions of perl. The only difference I could find is
the following:

<     uname='darwin b01.apple.com 8.0 darwin kernel version 8.3.0: mon
oct 3 20:04:04 pdt 2005; root:xnu-792.6.22.obj~2release_ppc power
macintosh powerpc '
---
>     uname='darwin b14.apple.com 8.0 darwin kernel version 8.3.0: mon oct 3 20:04:04 pdt 2005; root:xnu-792.6.22.obj~2release_ppc power macintosh powerpc '
37d36
<       SPRINTF0 - fixes for sprintf formatting issues - CVE-2005-3962


the bad machine lacks a SPRINTF0 fix but i'm not sure if this would
result in a bus error (a hardware problem?, maybe bad/illegal memory
access?).

any ideas how i can resolve this issue? I di dn't build perl from
source. it was whatever that came with teh OS X installation disk. but
i didn't install modules using the cpan program...but i didn't this on
both machines...so i doubt that is the culprit.

any suggestions are appreciated.

-----------------------------------------------------------------------------------------------------------------

THE GOOD MACHINE
Summary of my perl5 (revision 5 version 8 subversion 6) configuration:
  Platform:
    osname=darwin, osvers=8.0, archname=darwin-thread-multi-2level
    uname='darwin b01.apple.com 8.0 darwin kernel version 8.3.0: mon
oct 3 20:04:04 pdt 2005; root:xnu-792.6.22.obj~2release_ppc power
macintosh powerpc '
    config_args='-ds -e -Dprefix=/usr -Dccflags=-g  -pipe
-Dldflags=-Dman3ext=3pm -Duseithreads -Duseshrplib'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=define use5005threads=undef useithreads=define
usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-g -pipe -fno-common -DPERL_DARWIN
-no-cpp-precomp -fno-strict-aliasing -I/usr/local/include',
    optimize='-O3',
    cppflags='-no-cpp-precomp -g -pipe -fno-common -DPERL_DARWIN
-no-cpp-precomp -fno-strict-aliasing -I/usr/local/include'
    ccversion='', gccversion='4.0.1 (Apple Computer, Inc. build 5363)',
gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='env MACOSX_DEPLOYMENT_TARGET=10.3 cc', ldflags
='-L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib
    libs=-ldbm -ldl -lm -lc
    perllibs=-ldl -lm -lc
    libc=/usr/lib/libc.dylib, so=dylib, useshrplib=true,
libperl=libperl.dylib
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-bundle -undefined dynamic_lookup
-L/usr/local/lib'


Characteristics of this binary (from libperl):
  Compile-time options: MULTIPLICITY USE_ITHREADS USE_LARGE_FILES
PERL_IMPLICIT_CONTEXT
  Locally applied patches:
        23953 - fix for File::Path::rmtree CAN-2004-0452 security issue
        33990 - fix for setuid perl security issues
        SPRINTF0 - fixes for sprintf formatting issues - CVE-2005-3962
  Built under darwin
  Compiled at Oct 16 2006 22:54:34
  %ENV:
    PERL5LIB="/sw/lib/perl5:/sw/lib/perl5/darwin"
  @INC:
    /sw/lib/perl5
    /sw/lib/perl5/darwin
    /System/Library/Perl/5.8.6/darwin-thread-multi-2level
    /System/Library/Perl/5.8.6
    /Library/Perl/5.8.6/darwin-thread-multi-2level
    /Library/Perl/5.8.6
    /Library/Perl
    /Network/Library/Perl/5.8.6/darwin-thread-multi-2level
    /Network/Library/Perl/5.8.6
    /Network/Library/Perl
    /System/Library/Perl/Extras/5.8.6/darwin-thread-multi-2level
    /System/Library/Perl/Extras/5.8.6
    /Library/Perl/5.8.1
    .

------------------------------------------------------------------------------------------
THE BAD MACHINE (i.e. the one that reports BUS ERROR)
Summary of my perl5 (revision 5 version 8 subversion 6) configuration:
  Platform:
    osname=darwin, osvers=8.0, archname=darwin-thread-multi-2level
    uname='darwin b14.apple.com 8.0 darwin kernel version 8.3.0: mon
oct 3 20:04:04 pdt 2005; root:xnu-792.6.22.obj~2release_ppc power
macintosh powerpc '
    config_args='-ds -e -Dprefix=/usr -Dccflags=-g  -pipe
-Dldflags=-Dman3ext=3pm -Duseithreads -Duseshrplib'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=define use5005threads=undef useithreads=define
usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-g -pipe -fno-common -DPERL_DARWIN
-no-cpp-precomp -fno-strict-aliasing -I/usr/local/include',
    optimize='-O3',
    cppflags='-no-cpp-precomp -g -pipe -fno-common -DPERL_DARWIN
-no-cpp-precomp -fno-strict-aliasing -I/usr/local/include'
    ccversion='', gccversion='4.0.1 (Apple Computer, Inc. build 5363)',
gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='env MACOSX_DEPLOYMENT_TARGET=10.3 cc', ldflags
='-L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib
    libs=-ldbm -ldl -lm -lc
    perllibs=-ldl -lm -lc
    libc=/usr/lib/libc.dylib, so=dylib, useshrplib=true,
libperl=libperl.dylib
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-bundle -undefined dynamic_lookup
-L/usr/local/lib'


Characteristics of this binary (from libperl):
  Compile-time options: MULTIPLICITY USE_ITHREADS USE_LARGE_FILES
PERL_IMPLICIT_CONTEXT
  Locally applied patches:
        23953 - fix for File::Path::rmtree CAN-2004-0452 security issue
        33990 - fix for setuid perl security issues
  Built under darwin
  Compiled at Jul  1 2006 19:24:18
  %ENV:
    PERL5LIB="/sw/lib/perl5:/sw/lib/perl5/darwin"
  @INC:
    /sw/lib/perl5
    /sw/lib/perl5/darwin
    /System/Library/Perl/5.8.6/darwin-thread-multi-2level
    /System/Library/Perl/5.8.6
    /Library/Perl/5.8.6/darwin-thread-multi-2level
    /Library/Perl/5.8.6
    /Library/Perl
    /Network/Library/Perl/5.8.6/darwin-thread-multi-2level
    /Network/Library/Perl/5.8.6
    /Network/Library/Perl
    /System/Library/Perl/Extras/5.8.6/darwin-thread-multi-2level
    /System/Library/Perl/Extras/5.8.6
    /Library/Perl/5.8.1
    .

--------------------------------------------------------------------------------------------------------------
!/usr/bin/perl -w

# $Id:$

use strict;
use Getopt::Long;
use POSIX;
use Carp;
use English '-no_match_vars';
use IO::All;
use IO::File;
use Statistics::Descriptive;
use GD::Graph::points;
use List::Util qw[min max];
use HTML::Tabulate qw(render);

require "myXML.pm";

# Global data
my $data;
my $emailscript = "sendemail.pl";

# Additional record headers
my $defaulttotalpoints = "Total Points";
my $defaultpercent = "%";

# Default files where to dump result
my $defaultstatfile = "statistics.txt";
my $defaulthwchartfile = "hwchart.png";
my $defaultexchartfile = "examchartfile.png";
my $defaulthtmlfile = "grades.html";

# Seed of the number generator. Each student will have an 8-digit ID
my $defaultseed = 0x8295bda3;
my $defaultmin = 10000000;
my $defaultrange = 50000000;

# Match HW# or EXAM#
my $hwstring = "HW(\\d)+|hw(\\d)+";
my $exstring = "EXAM(\\d)+|exam(\\d)+";

my $sid = "Student ID";

# Print help information
sub usage() {

  my %options = (
        "--help" => "Print this documentation.",
        "--email" => "Send email to student displaying pseudo-Student
ID.",
        "--hwchartfile=s" => "Dump homework chart to file (default is
$defaulthwchartfile).",
        "--exchartfile=s" => "Dump exam chart to file (default is
$defaultexchartfile).",
        "--statfile=s" => "Dump statistics to file (default is
$defaultstatfile).",
        "--htmlfile=s" => "Generate webpage to file (default is
$defaulthtmlfile).",
        );

  print "$PROGRAM_NAME: This script computes vaious statistics on a
list of student grades.\n\n";
  print "Usage: $PROGRAM_NAME [--hwchartfile=s] [--exchartfile==s]
[--statfile=s] [--htmlfile=s] [--help] <data$

  foreach my $key (sort keys %options) {
        printf "%5s %-15s %-70s\n", "", $key, $options{$key};
  }
  print "\n";
  exit 1;
}

# Initailze
sub initialize() {

  my $help;
  my $email;

  &GetOptions(
        "help", => \$help,
        "email", => \$email,
        "exchartfile", => \$defaultexchartfile,
        "hwchartfile", => \$defaulthwchartfile,
        "statfile=s", => \$defaultstatfile,
        "htmlfile=s", => \$defaulthtmlfile,
        ) || croak "Unable to parse options. Type $PROGRAM_NAME --help
for usage";

  if ($help) { &usage(); }
  if (@ARGV == 0) { croak "Must specify a file containing student
grades"; }

# Parse grades file, check the records, compute statistics
  my ($records, $fields, $points) = &parseGradeFile($ARGV[0]);
  &checkRecords($records, $fields, $points);
  my $stats = &computeStatistics($records, $fields);
  $records = &computeStudentTotalPointsandPercentage($records, $fields,
$points);

  # Print statistics to file
  my $fh = new IO::File("$defaultstatfile", "w") || croak "Unable to
open file '$defaultstatfile' for writing";
  &printStatistics($stats, \*$fh);
  $fh->close();

  # Generate charts
  print "Generating hw and exam charts ...\n";
  &genChart($records, $fields, $defaulthwchartfile, $hwstring,
"Homework score distribution", "", "Points");
  &genChart($records, $fields, $defaultexchartfile, $exstring, "Exam
score distribution", "", "Points");

  # Generate HTML
  $fh = new IO::File("$defaulthtmlfile", "w") || croak "Unable to open
file '$defaulthtmlfile' for writing";
  &genHTMLTable($records, $stats, $fields, \*$fh);
  $fh->close();

  # Send emails to students
  if ($email) {
    &genEmails($records, $fields);
  }
# List the generated files
  print "Generated files: $defaultexchartfile $defaulthwchartfile
$defaultstatfile $defaulthtmlfile\n";
  return 0;
}

# Send emails to the students telling them their pseudo-Student ID
sub genEmails() {

  my ($records, $fields) = @_;
  my $sid; my $name; my $email; my $totalmsg;

  my $msg = "Dear ";
  my $msg1 = "You are receiving this email because you are enrolled in
my class. Access your homework/exam grad$
  $msg1 .= "Click on the 'Courses' link and proceed
accordingly.\n\nYour pseudo-Student ID is: ";
  my $msg2 = "Do NOT share your ID. If you feel there are errors in the
grades, discuss this with me.\n";
  $msg2 .= "If you believe you are receiving this email in error, reply
to this email and report the problem.\n$
  $msg2 .= "Email generated automatically by $PROGRAM_NAME\n";
  my $subject = "\"Your course grades.\"";
   my $tmpfile = tmpnam();

  print "Sending emails ...\n";

  # For each record, get the name, email, and pseudo-student ID. Form
the message, write to temp file, and send$
  foreach my $rec (@{$records}) {
    $sid = $rec->{$fields->[0]};
    $name = $rec->{$fields->[1]};
    $email = $rec->{$fields->[2]};
    $totalmsg = $msg.$name.",\n\n".$msg1.$sid.".\n\n".$msg2;
    open(OUT, ">$tmpfile") || croak "Unable to open file '$tmpfile' for
writing";
    print OUT "totalmsg";
   close(OUT);
    print "Sending email to $name at $email.\n";
    system("$emailscript --to=$email --txtfile=$tmpfile
--subject=$subject");
  }
  `rm -f $tmpfile`;
}

# Generate the HTML file displaying the grades data
sub genHTMLTable() {

  my ($records, $stats, $fields, $fh) = @_;

  # Setup the global definition of the tables
  my $tabledefn = {
    table => { border => 1, cellpadding => 3, cellspacing => 1, align
=> 'center' },
    null => '&nbsp;',
    labels => 1,
    stripe => '#cccccc',
    thead => 'true',
    tbody => 'true',
    field_attr => {
      -defaults => { align => 'center', valign => 'top'},
      $defaultpercent => { format => '%.3f' },
    },
  };

  # Setup the defintions of the grades table
  # NOTE: Do not display student grades and ID.
my $tabledefn2 = {
    fields => [@{$fields}, $defaulttotalpoints, $defaultpercent],
    fields_omit => [ qw(Name Contact) ],
    title => {
      value => 'Raw Homework and Exam Scores',
      format => '<h3 align="center">%s</h3>',
    },
    caption => {
      type => 'caption_caption',
      value => 'Note: Use the pseudo-Student ID that was emailed to you
as your record locator.',
    },
  };

  # Setup the definitions for the statistics table
  my $tabledefn3 = {
    fields => [qw(Type Min Max Mean Median), "Standard Deviation",
qw(Variance)],
    field_attr => {
      Mean => { format => '%.3f' },
      "Standard Deviation" => { format => '%.3f' },
      Variance => { format => '%.3f'},
    },
    title => {
      value => 'Various Statistics',
      format => '<h3 align="center">%s</h3>',
    },
  };
 # Get date stamp
  my $datestamp = strftime("%m-%d-%Y", localtime);

  # Generate HTML tags
  print $fh "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01
Transitional//EN\" \"http://www.w3.org/TR/html4/loos$
  print $fh "<html>\n<head>\n<title>Course Grade</title>\n";
  print $fh "<meta http-equiv=\"Content-Type\" content=\"text/html;
charset=iso-8859-1\">\n";
  print $fh "</head>\n\n<body>\n";

  # Print the grades and statistics table
  my $table =  HTML::Tabulate->new($tabledefn);
  print $fh $table->render($records, $tabledefn2);
  print $fh "<br/>\n";
  print $fh $table->render($stats, $tabledefn3);

  # Add the links to the chart showing grade distribution
  print $fh "<br /><h3 align=\"center\">Score Distribution</h3>\n";
  print $fh "<table width=\"100%\"><tr>\n";
  print $fh "<td align=\"center\">";
  print $fh "<img src=\"$defaultexchartfile\" alt=\"\" /></td>\n";
  print $fh "<td align=\"center\">";
  print $fh "<img src=\"$defaulthwchartfile\" alt=\"\" /></td>\n";
  print $fh "</tr></table>\n";
  print $fh "<br/><hr>\n";
  print $fh "<i>This page was generated by $PROGRAM_NAME on
$datestamp.</i><br/>";
  print $fh "</body></html>\n";
}
# Generate charts which show the homework/exam grade distribution
sub genChart() {

  my ($records, $fields, $filename, $str, $title, $xlabel, $ylabel) =
@_;
  my @data;

  # Exclude the string specified in $str from the fields during display
  my @temp = grep(/$str/, @{$fields}[2..scalar($#$fields)]);

  # Get the points for each homework/exam (delimited by /)
  my @points = map(m/\/(\d+)$/, @temp);

  # Just push an integer for each student in the array
  my @temp2;
  for (my $i = 0; $i < @{$records}; $i++) { push @temp2, $i; }
  push @data, [@temp2];

  # For each homework/exam, add the grade of each student as the y
values
  for (my $i = 0; $i < @temp; $i++) {
    my @scores;
    foreach my $rec (@{$records}) {
      push @scores, $rec->{$temp[$i]};
    }
    push @data, [@scores];
  }

  # Draw the chart
  &drawChart(\@data, \@temp, $filename, max(@points), $title, $xlabel,
$ylabel);
}

 Draw the chart
sub drawChart() {

  my ($data, $legend, $filename, $max, $title, $xlabel, $ylabel) = @_;

  # Set the dimensions of the graph and set the global variables
  my $graph = GD::Graph::points->new(600,450);
  $graph->set(
    x_label           => $xlabel,
    y_label           => $ylabel,
    title             => $title,
    y_min_value       => 0,
    y_max_value       => $max,
    y_tick_number     => 10,
    y_label_skip      => 1,
    x_label_position  => 1/2,
    y_label_position  => 1/2,
  ) or croak $graph->error;

  # Set the legend keys
  $graph->set_legend(@{$legend});

  # Plot the graph and dump result to file
  my $gd = $graph->plot($data) || croak $graph->error;
  open(IMG, ">$filename") or croak $!;
  binmode IMG;
  print IMG $gd->png;
  close(IMG);
}
 Read the grades data and return as array of hashes, field lists, and
the point value for each grade field
sub parseGradeFile() {

  my $infile = shift;

  print "Reading data file '$infile' ... \n";
  if (!-e $infile) { croak "Grade file '$infile' does not exist"; }

  # Seed the number generator (Note: I should change this each semester
for new numbers)
  srand($defaultseed);

  # Read in the data
  my @lines = IO::All->new($infile)->chomp->slurp;

  # Get the data fields
  my @fields;
  unshift(@fields, $sid);
  push(@fields, split('\s+', $lines[0]));
  my $records = [];
  my @points;

  # Get the point value for each grade field
  foreach my $i (@fields) { if ($i =~ m/.*\/(\d+)/) { push @points, $1;
} }

# Parse each line, split the data, create a hash, and add to array
  for (my $i = 1; $i < @lines; $i++) {
    my @rec = split('\s+', $lines[$i]);
    if ((@rec+1) != @fields) { croak "Row ", $i+1, " in file '$infile'
contains too many/few data fields"; }
    my %tmp;
    for (my $j = 1; $j < @fields; $j++) {
      $tmp{$fields[$j]} = $rec[$j-1];
    }
    $tmp{$sid} = $defaultmin + int(rand($defaultrange));
    push(@{$records}, \%tmp);
  }

  return ($records, \@fields, \@points);
}

# Print the array of hashes
sub printRecords() {

  my $records = shift;
  foreach my $rec (@{$records}) {
    foreach my $key (sort keys %{$rec}) {
      print "$key $rec->{$key} ";
    }
    print "\n";
  }
}
# Perform sanity check on the data
sub checkRecords() {

  my ($records, $fields, $points) = @_;

  print "Performing sanity check on data ...\n";

  # For each records, check that all the grades don't exceed the total
point value
  foreach my $rec (@{$records}) {
    for (my $i = 3; $i < @{$fields}; $i++) {
      if ($rec->{$fields->[$i]} > $points->[$i-3]) {
        croak "Record '$rec->{$fields->[1]}': Points for
'$fields->[$i]' is '$rec->{$fields->[$i]}' and exceeds$
      }
      if ($rec->{$fields->[$i]} < 0) {
        croak "Record '$rec->{$fields->[1]}': Points
'$rec->{$fields->[$i]}' is negative";
      }
    }
  }
}

# Print the statistics
sub printStatistics() {
  my ($st, $fh) = @_;
  foreach my $rec (@{$st}) {
    &printStatisticsHelper($rec, \*$fh);
  }
}
# Helper function
sub printStatisticsHelper() {
  my ($rec, $fh) = @_;
  print $fh "Statistics for ", $rec->{"Type"}, ":\n";
  foreach my $key (sort keys %{$rec}) {
    if ($key eq "Type") { next; }
    printf  $fh "$key = %.2f\n", $rec->{$key};
  }
  print $fh "\n";
}

# Computes various statistics on the grades
sub computeStatistics() {

  my ($records, $fields) = @_;
  my $st = [];

  print "Computing statistics ...\n";

  # For each homework/exam type, compute various statistics and add to
hash
  for (my $i = 3; $i < @{$fields}; $i++) {
    my $stats = new Statistics::Descriptive::Full->new();
    foreach my $rec (@{$records}) {
      $stats->add_data($rec->{$fields->[$i]});
    }
     my %tmp;
     $tmp{"Type"} = $fields->[$i];
     $tmp{"Min"} = $stats->min();
     $tmp{"Max"} = $stats->max();
 $tmp{"Mean"} = $stats->mean();
     $tmp{"Standard Deviation"} = $stats->standard_deviation();
     $tmp{"Variance"} = $stats->variance();
     $tmp{"Median"} = $stats->median();
     push (@{$st}, \%tmp);
  }

  # Return the result
  return($st);
}
# Compute total points and percentage for the homeworks/exams
sub computeStudentTotalPointsandPercentage() {

  my ($records, $fields, $points) = @_;
  my %tpp;

  print "Computing total points and percentage ...\n";

  # Sum up all the points
  my $tp = 0;
  ($tp += $_) for @{$points};

  # For each record, compute total and percentage, and add that to the
same record as fields
  my $total;
  foreach my $rec (@{$records}) {
    $total = 0;
    for (my $i = 3; $i < @{$fields}; $i++) { $total +=
$rec->{$fields->[$i]}; }
    my @data = ($total, $total/$tp);

    $rec->{$defaulttotalpoints} = $total;
    $rec->{$defaultpercent} = ($total*100)/$tp;
    $tpp{$rec->{$fields->[0]}} = [@data];
  }

  # Return the records with the additional information
  return ($records);
}

# Read XML data
$data = &parseXMLData();

# Initialize and process
my $status = &initialize();
exit $status;



------------------------------

Date: Thu, 25 Jan 2007 18:25:37 -0800
From: Jim Gibson <jgibson@mail.arc.nasa.gov>
Subject: Re: MacPerl, OS 9, move file to Trash
Message-Id: <250120071825373199%jgibson@mail.arc.nasa.gov>

In article <please-E3D4B0.17122925012007@free.teranews.com>, Xiong
Changnian <please@nospam.net> wrote:

> In article <m2veiuu4o7.fsf@Sherm-Pendleys-Computer.local>,
>  Sherm Pendley <spamtrap@dot-app.org> wrote:
> 
> > Just renaming them should work.
> 
> It might. I'd really rather *move* files to Trash, rather that jigger 
> the system. Mac plays nice if you play nice with Mac. 

You are not 'jiggering' the system. Renaming and moving a file are
equivalent in a Unix-based system provided the file remains within the
same file system. That way, the file itself is untouched. Only the
directory entries that point to the file are modified. The equivalent
Unix command is 'mv', but that is what you use to rename the file if
you want it to remain in the same directory.

Only if you want to move the file to a different file system
(partition, drive, etc.) is it necessary for the file to be copied and
the original unlinked.

> 
> >     <http://bumppo.net/lists/macperl/1997/04/msg00079.html>
> 
> Yes, I read that post and its reply, too. It's about renaming to 
> faux-move. I've also read 2 or 3 discussions in other places reporting 
> problems with this approach. 

What are the problems reported with this approach? As far as I know, it
is only what I mentioned above? Some Unix mv utilities will take care
of this for you. On my system (Mac OS X.4.8), mv works across file
system boundaries but perl rename does not. See 'perldoc -f rename'. 

> 
> I'd really prefer to get AppleScript calls working. Who knows, I may be 
> able to do something else with them. 

Go for it. I always had problems getting AppleScript to work for me
under Mac OS 9. I would record a set of actions in an Applescript
program, but found the resulting program would not always work and
would fail silently. I found Perl much more reliable. I haven't tried
Applescript under Mac OS X -- there is no reason since Perl does
everything I want it to do.

> 
> > lists.perl.org
> 
> It's lists.cpan.org now. I've been subscribed to the original MacPerl 
> mailing list since 2004; it's dead, nobody ever posts, not even spam. 

That is probably because anybody writing programs on the Mac has
upgraded to Mac OS X and uses the standard Perl distribution, not
MacPerl.

> 
> Almost all forum discussion -- no matter where it's held -- revolves 
> around MacPerl for OS X. This is a whole different animal, of course, 
> since OS X is just a wrapper around a unix-ish box. 
> 
> I suppose I should subcribe to a half-dozen MacPerl OS X forums and 
> troll for solutions there. I'm still hoping somebody in this group has 
> some experience with OS 9.

Some of us do. However, my experience with MacPerl and OS 9 is about 5
years old.

-- 
Jim Gibson

 Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
    ** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------        
                http://www.usenet.com


------------------------------

Date: Thu, 25 Jan 2007 21:54:13 -0500
From: Sherm Pendley <spamtrap@dot-app.org>
Subject: Re: MacPerl, OS 9, move file to Trash
Message-Id: <m28xfqts4q.fsf@Sherm-Pendleys-Computer.local>

Jim Gibson <jgibson@mail.arc.nasa.gov> writes:

> On my system (Mac OS X.4.8), mv works across file
> system boundaries but perl rename does not.

Quite right, but keep in mind that the OP wants to move a file to the trash.
Doing so will be definition never move a file across file system boundaries,
because each HFS+ file system has its own Trash folder.

sherm--

-- 
Web Hosting by West Virginians, for West Virginians: http://wv-www.net
Cocoa programming in Perl: http://camelbones.sourceforge.net


------------------------------

Date: 25 Jan 2007 21:27:06 -0800
From: "DSIOMTW" <dsiomtw@gmail.com>
Subject: Re: Net::FTPSSL problem (or how to do FTP over SSL another way?)
Message-Id: <1169789225.933814.297610@m58g2000cwm.googlegroups.com>

Hey Rob,

Thanks a lot for your response. I was able to find the necessary patch
and now it works like a champ!



------------------------------

Date: Fri, 26 Jan 2007 05:42:08 GMT
From: merlyn@stonehenge.com (Randal Schwartz)
Subject: new CPAN modules on Fri Jan 26 2007
Message-Id: <JCGnu8.1zs8@zorch.sf-bay.org>

The following modules have recently been added to or updated in the
Comprehensive Perl Archive Network (CPAN).  You can install them using the
instructions in the 'perlmodinstall' page included with your Perl
distribution.

Apache-UploadMeter-0.9912
http://search.cpan.org/~isaac/Apache-UploadMeter-0.9912/
Apache module which implements an upload meter for form-based uploads
----
Audio-MPD-0.12.4
http://search.cpan.org/~jquelin/Audio-MPD-0.12.4/
Class for talking to MPD (Music Player Daemon) servers
----
CFPlus-0.97
http://search.cpan.org/~mlehmann/CFPlus-0.97/
undocumented utility garbage for our crossfire client
----
CSS-Tiny-Style-v0.0.3
http://search.cpan.org/~scesano/CSS-Tiny-Style-v0.0.3/
Object oriented interface to CSS stylesheets
----
Catalyst-Plugin-Authentication-Basic-Remote-0.03
http://search.cpan.org/~typester/Catalyst-Plugin-Authentication-Basic-Remote-0.03/
(DEPRECATED) Basic authentication via remote host.
----
Catalyst-Plugin-Authentication-CDBI-Basic-0.02
http://search.cpan.org/~typester/Catalyst-Plugin-Authentication-CDBI-Basic-0.02/
(DEPRECATED) Basic Authorization with Catalyst
----
Catalyst-Plugin-Firebug-0.01
http://search.cpan.org/~typester/Catalyst-Plugin-Firebug-0.01/
Catalyst plugin for Firebug Lite
----
Catalyst-Plugin-Setenv-0.02
http://search.cpan.org/~jrockway/Catalyst-Plugin-Setenv-0.02/
Allows you to set up the environment from Catalyst's config file.
----
Config-IniHash-2.8.2
http://search.cpan.org/~jenda/Config-IniHash-2.8.2/
Perl extension for reading and writing INI files
----
Config-Model-Xorg-0.5
http://search.cpan.org/~ddumont/Config-Model-Xorg-0.5/
----
Crossfire-0.96
http://search.cpan.org/~mlehmann/Crossfire-0.96/
Crossfire maphandling
----
Crypt-Rijndael-1.02
http://search.cpan.org/~bdfoy/Crypt-Rijndael-1.02/
Crypt::CBC compliant Rijndael encryption module
----
DBIx-Class-0.07999_02
http://search.cpan.org/~jrobinson/DBIx-Class-0.07999_02/
Extensible and flexible object <-> relational mapper.
----
Data-Constraint-1.11
http://search.cpan.org/~bdfoy/Data-Constraint-1.11/
prototypical value checking
----
Data-Float-0.005
http://search.cpan.org/~zefram/Data-Float-0.005/
details of the floating point data type
----
Date-Calc-5.5
http://search.cpan.org/~tchatzi/Date-Calc-5.5/
Gregorian calendar date calculations
----
Digest-Whirlpool-1.0.4
http://search.cpan.org/~avar/Digest-Whirlpool-1.0.4/
A 512-bit, collision-resistant, one-way hash function
----
Directory-Scratch-0.12
http://search.cpan.org/~jrockway/Directory-Scratch-0.12/
Easy-to-use self-cleaning scratch space.
----
Finance-Bank-HSBC-1.06
http://search.cpan.org/~mwilson/Finance-Bank-HSBC-1.06/
Extract HSBC online banking data.
----
GPS-Babel-v0.0.3
http://search.cpan.org/~andya/GPS-Babel-v0.0.3/
Perl interface to gpsbabel
----
JE-0.001
http://search.cpan.org/~sprout/JE-0.001/
Pure-Perl ECMAScript (JavaScript) Engine
----
JavaScript-Engine-0.01
http://search.cpan.org/~sprout/JavaScript-Engine-0.01/
Pure-Perl ECMAScript (JavaScript) engine
----
MARC-Record-2.0.0
http://search.cpan.org/~mikery/MARC-Record-2.0.0/
Perl extension for handling MARC records
----
Mac-iTerm-LaunchPad-1.006
http://search.cpan.org/~bdfoy/Mac-iTerm-LaunchPad-1.006/
----
Module-Load-Conditional-0.16
http://search.cpan.org/~kane/Module-Load-Conditional-0.16/
Looking up module information / loading at runtime
----
Module-ThirdParty-0.19
http://search.cpan.org/~saper/Module-ThirdParty-0.19/
Provide information for 3rd party modules (outside CPAN)
----
Muck-0.02
http://search.cpan.org/~mike/Muck-0.02/
a toolkit for managing a cloud on Amazon EC2 and S3
----
Opt
http://search.cpan.org/~balajiram/Opt/
Get command line options and their values
----
Opt-0.1.1
http://search.cpan.org/~balajiram/Opt-0.1.1/
Get command line options and their values
----
PDF-FromHTML-0.22
http://search.cpan.org/~audreyt/PDF-FromHTML-0.22/
Convert HTML documents to PDF
----
PHP-Session-DBI-0.20
http://search.cpan.org/~burak/PHP-Session-DBI-0.20/
Interface to PHP DataBase Sessions
----
Palm-Magellan-NavCompanion-0.52
http://search.cpan.org/~bdfoy/Palm-Magellan-NavCompanion-0.52/
access the Magellan GPS Companion waypoints file
----
Params-Classify-0.002
http://search.cpan.org/~zefram/Params-Classify-0.002/
argument type classification
----
Parse-Eyapp-1.06503
http://search.cpan.org/~casiano/Parse-Eyapp-1.06503/
----
Perl-Critic-1.01
http://search.cpan.org/~thaljef/Perl-Critic-1.01/
Critique Perl source code for best-practices
----
Pod-POM-View-HTML-Filter-0.08
http://search.cpan.org/~book/Pod-POM-View-HTML-Filter-0.08/
Use filters on sections of your pod documents
----
Pod-Perldoc-ToToc-1.07
http://search.cpan.org/~bdfoy/Pod-Perldoc-ToToc-1.07/
Translate Pod to a Table of Contents
----
Socialtext-Resting-0.12
http://search.cpan.org/~lukec/Socialtext-Resting-0.12/
module for accessing Socialtext REST APIs
----
Socialtext-Resting-Utils-0.07
http://search.cpan.org/~lukec/Socialtext-Resting-Utils-0.07/
Utilities for Socialtext REST APIs
----
Test-Mock-LWP-0.03
http://search.cpan.org/~lukec/Test-Mock-LWP-0.03/
Easy mocking of LWP packages
----
Test-Mock-LWP-0.04
http://search.cpan.org/~lukec/Test-Mock-LWP-0.04/
Easy mocking of LWP packages
----
Test-Perl-Critic-1.01
http://search.cpan.org/~thaljef/Test-Perl-Critic-1.01/
Use Perl::Critic in test programs
----
Time-Local-1.17
http://search.cpan.org/~drolsky/Time-Local-1.17/
efficiently compute time from local and GMT time
----
Win32-GUI-XMLBuilder-0.38
http://search.cpan.org/~bsdz/Win32-GUI-XMLBuilder-0.38/
Build Win32::GUIs using XML.
----
Win32-GUI-XMLBuilder-0.39
http://search.cpan.org/~bsdz/Win32-GUI-XMLBuilder-0.39/
Build Win32::GUIs using XML.
----
XML-SAX-Expat-0.38
http://search.cpan.org/~bjoern/XML-SAX-Expat-0.38/
SAX2 Driver for Expat (XML::Parser)
----
YAML-Syck-0.80
http://search.cpan.org/~audreyt/YAML-Syck-0.80/
Fast, lightweight YAML loader and dumper
----
YAML-Syck-0.81
http://search.cpan.org/~audreyt/YAML-Syck-0.81/
Fast, lightweight YAML loader and dumper
----
YAML-Syck-0.82
http://search.cpan.org/~audreyt/YAML-Syck-0.82/
Fast, lightweight YAML loader and dumper
----
criticism-1.01
http://search.cpan.org/~thaljef/criticism-1.01/
Perl pragma to enforce coding standards and best-practices
----
later-0.04
http://search.cpan.org/~erwan/later-0.04/
A pragma to postpone using a module
----
threads-1.58
http://search.cpan.org/~jdhedden/threads-1.58/
Perl interpreter-based threads


If you're an author of one of these modules, please submit a detailed
announcement to comp.lang.perl.announce, and we'll pass it along.

This message was generated by a Perl program described in my Linux
Magazine column, which can be found on-line (along with more than
200 other freely available past column articles) at
  http://www.stonehenge.com/merlyn/LinuxMag/col82.html

print "Just another Perl hacker," # the original

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!


------------------------------

Date: Thu, 25 Jan 2007 20:39:44 -0600
From: Tad McClellan <tadmc@augustmail.com>
Subject: Re: String Substitution question
Message-Id: <slrneriqfg.vd3.tadmc@tadmc30.august.net>

Lawrence Statton XE2/N1GAK <yankeeinexile@gmail.com> wrote:
> "LtCommander" <LtCommander@gmail.com> writes:
>> 
>> 		$m =~ s/\(/\\(/sig;
>> 		$m =~ s/\)/\\)/sig;
>> 		$m =~ s/\[/\\[/sig;
>> 		$m =~ s/\]/\\]/sig;
>> 		$m =~ s/\?/\\?/sig;
>> 		$m =~ s/\*/\\*/sig;
>> 		$m =~ s/\./\\./sig;
>> 		$m =~ s/\$/\\\$/sig;
>> 		$m =~ s/\+/\\+/sig;
>> 		$m =~ s/\_/\\_/sig;
>> 		$m =~ s/\-/\\-/sig;
>
> OH!  I see it, it's a pony!


Bzzzt! It's a camel.

With two humps.


-- 
    Tad McClellan                          SGML consulting
    tadmc@augustmail.com                   Perl programming
    Fort Worth, Texas


------------------------------

Date: Thu, 25 Jan 2007 21:51:35 -0600
From: "Mumia W. (NOSPAM)" <paduille.4060.mumia.w+nospam@earthlink.net>
Subject: Re: String Substitution question
Message-Id: <epbu5j$62k$1@aioe.org>

On 01/25/2007 05:51 PM, LtCommander wrote:
> This could be a stupid question but I am really stuck!
> 
> I am doing
> $content=~ s/$m//sig;
> 
> The problem is that $m may have all sorts of escape sequence
> characters, brackets and so on. So, sometimes, $content doesn't have
> $match removed. So, I do this:
> 
> 		$m =~ s/\(/\\(/sig;
> 		$m =~ s/\)/\\)/sig;
> 		$m =~ s/\[/\\[/sig;
> 		$m =~ s/\]/\\]/sig;
> 		$m =~ s/\?/\\?/sig;
> 		$m =~ s/\*/\\*/sig;
> 		$m =~ s/\./\\./sig;
> 		$m =~ s/\$/\\\$/sig;
> 		$m =~ s/\+/\\+/sig;
> 		$m =~ s/\_/\\_/sig;
> 		$m =~ s/\-/\\-/sig;
> and then
> $content=~ s/$m//sig;
> 
> Is there a better way of doing this?
> 
> Thanks a lot for any help.
> 
> VInce
> 

Yes:

$content =~ s/\Q$m\E//ig;

Read the docs:
perldoc perlre
perldoc -f quotemeta


-- 
Windows Vista and your freedom in conflict:
http://www.badvista.org/


------------------------------

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 V11 Issue 77
*************************************


home help back first fref pref prev next nref lref last post