JLott
JLott

Reputation: 1828

Perl program to calculate the sum of the numbers that the user enters

My script needs to get a series of numbers input by the user and find the average of them. I would like to use the line 'end-of-file' to show that the user is done inputting code. Any help would be appreciated. Below is what I have so far. I think I am really close, but I am missing something.

Code:

#! /usr/bin/perl
use 5.010;


print "Enter the scores and type end-of-file when done";
chomp(@scores = <STDIN>);
foreach (@scores) {
    push_average(total(@scores));
}




sub total {
    my $sum;
    foreach (@_) {
        $sum += $_;
    }
    sum;
}

sub average {
    if (@_ == 0) {return}
    my $count = @_;
    my $sum = total(@_);
    $sum/$count;
}

sub push_average {
    my $average = average(@_);
    my @list;
    push @list, $average;
    return @list;
}

Upvotes: 0

Views: 11119

Answers (2)

amon
amon

Reputation: 57590

You are quite close. Adding use strict; use warnings at the top of every Perl script will alert you of errors that might go unnoticed otherwise.

A few hints:

  • You forgot the sigil of $sum in the last statement of total. Currently, you return a string "sum" (without strict vars), or possibly call a sub called sum.

  • You don't need the foreach in the main part, rather do

    my @averages = push_average(@scores);
    

    The total is already calculated inside push_average

  • You probably want to print out the resulting average:

    my $avg = $averages[0];
    say "The average of these numbers is $avg";
    
  • The push_average is silly; you return a new array of one element. You could return that one element just as well.


Suggested script:

use strict; use warnings; use 5.010;
use List::Util qw/sum/;  # very useful module

# say is like print, but appends a newline. Available with 5.10+
say "Please enter your numbers, finish with Ctrl+D";
my @nums = <STDIN>;
chomp @nums;

# The // is the defined-or operator
# interpolating undef into a string causes a warning.
# Instead, we give an expressive message:
my $avg = average(@nums) // "undefined"; 

say "The average was $avg";

sub average { @_ ? sum(@_) / @_  : undef } # return undef value if called without args

Upvotes: 3

Erik Nedwidek
Erik Nedwidek

Reputation: 6184

reads up to the newline. You've got a few choices here. You can ask the user to input the numbers separated by spaces and then split it into your @choices array. Or you can keep asking them to enter a number or just hit enter to finish.

Answer 1)

print "Enter scores separated by a space and press enter when done";
chomp($input = <STDIN>);
@choices = split(' ', $input);

Answer 2)

@chomp = ();
do {
   print "Enter a score and then press enter. If done, just press enter.";
   chomp($temp = <STDIN>);
   if($trim ne '') {
     push(@choices, $temp);
   }
} until ($temp eq '');

Upvotes: 0

Related Questions