Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Assignments for Subroutines

by perlguru22 (Acolyte)
on Sep 27, 2012 at 07:24 UTC ( #995936=perlquestion: print w/ replies, xml ) Need Help??
perlguru22 has asked for the wisdom of the Perl Monks concerning the following question:

I had to do this 3 assignments I finished them I Just wanted to show it to you guys to see if there was anything I Could do to make it better or to shorten some of them Thanks =).

1. Write a subroutine (&evens) that recieves an array of numbers and returns an array containing only even numbers Give an example of calling the subroutine.

#!/usr/bin/perl use strict; use warnings; my@num = (1..10); sub even { foreach my$number(@num) { if ($number%2==0) { my @evens = $number; print "@evens"; } } } &even

2. Write a subroutine(&squares) that recieves an array of numbers and squares each number in the array. Note: nothing is returned.

#! /usr/bin/perl use strict; use warnings; my @nums = (1..10); sub square { foreach my$number (@nums) { my$number = ($number * $number); print "$number\n"; } }

3. Write a subroutine(&huge) that returns true if the number sent is greater than 1,000,000 or false(look up what is true and false). Show an example of calling the function.

#!/usr/bin/perl use strict; use warnings; sub huge { my $num = <>; if ($num > 1000000) { print "1"; } else{ print "0"; } } &huge

Comment on Assignments for Subroutines
Select or Download Code
Re: Assignments for Subroutines
by Anonymous Monk on Sep 27, 2012 at 07:30 UTC
Re: Assignments for Subroutines
by Athanasius (Monsignor) on Sep 27, 2012 at 07:46 UTC

    (Looking at script 1 only:)

    As Anonymous Monk says, the subroutine doesn’t receive an array. It also doesn’t return an array. And the output has no spaces between numbers, so how is the user (your professor?) supposed to know that 246810 represents 5 numbers? (Hint: use join.)

    Another point: Don’t call a subroutine using the & sigil, unless you have good reason to (and you don’t). Call it as even() — or rather, as even(@num).

    Two more hints: Declare an array @evens inside sub even before the loop; and populate it using the push function.

    Hope that helps,

    Athanasius <°(((><contra mundum

Re: Assignments for Subroutines
by tobyink (Abbot) on Sep 27, 2012 at 07:52 UTC

    As the other answer said, none of these functions receive any arguments, nor do they return anything meaningful.

    In Perl, to pass arguments to a function, you put them in parentheses after the function name, a la:

    my @nums = 1 .. 10; my @results = evens(@nums);

    And within the functions, to receive arguments, you pull them out of the @_ array.

    sub evens { my (@nums) = @_; ...; }

    To return something, you either use the return keyword, or make sure that the thing you want to return is the last statement executed in the sub.

    sub this_sub_returns_1 { return 1; 2; } sub this_sub_returns_2 { 1; 2; }

    Here are even and square rewritten to actually take arguments and return values. There's also even_better and square_better which do the same thing but more concisely. (Whether they are "better" is a judgement call. I prefer them though.)

    use strict; use warnings; # Write a subroutine (&evens) that recieves an array of numbers and re +turns # an array containing only even numbers Give an example of calling the + # subroutine. sub even { my (@nums) = @_; my @evens; foreach my $number (@nums) { if ($number % 2 == 0) { push @evens, $number; } } return @evens; } print "Results for even(1..10)\n"; print "$_\n" for even( 1 .. 10 ); sub even_better { grep { $_ % 2 == 0 } @_; } print "Results for even_better(1..10)\n"; print "$_\n" for even_better( 1 .. 10 ); # Write a subroutine(&squares) that recieves an array of numbers and # squares each number in the array. Note: nothing is returned. sub square { foreach my $number (@_) { $number *= $number; } return; } print "Results for square(1..10)\n"; my @nums = 1 .. 10; square(@nums); print "$_\n" for @nums; sub square_better { $_ *= $_ for @_; } print "Results for square_better(1..10)\n"; my @nums_better = 1 .. 10; square_better(@nums_better); print "$_\n" for @nums_better;
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Assignments for Subroutines
by protist (Monk) on Sep 27, 2012 at 10:00 UTC
    The following is my version of part 1. You may find use diagnostics useful if you are new.
    #!/usr/bin/perl use strict; use warnings; use diagnostics; #more verbose feedback #useful for debugging my@num = (1..10); sub printeven{ my @given=@_; #pull in list given later: printeven(@list) my @evens; for (@given){ unless($_%2){ #unless odd push(@evens,$_); #add number to @evens } } $,=", "; #change list delimiter for fancy printing print @evens; print "\n"; #newline $,=""; #change list delimiter back before it is a problem } printeven(@num); #call sub with list of numbers 1-10
      $,=", "; #change list delimiter for fancy printing print @evens; print "\n"; #newline $,=""; #change list delimiter back before it is a problem
      That could be written as
      { local $,=", "; print @evens; print "\n"; #newline }
      No need to change it back, less possibility of an error. My 2 cents.


      I'm too lazy to be proud of being impatient.
        That is better. You have my +1

        Indeed. Especially because this...

        $,=""; #change list delimiter back before it is a problem

        ... changes the list delimited "back" to the empty string, when we never checked that it started off as the empty string to begin with!

        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Assignments for Subroutines
by aaron_baugher (Deacon) on Sep 27, 2012 at 13:56 UTC

    If you turned these in as-is, I'd be curious to know what grade you got on the assignment. Here would be my answers:

    1. Write a subroutine (&evens) that recieves an array of numbers and returns an array containing only even numbers. Give an example of calling the subroutine.
    #!/usr/bin/env perl use Modern::Perl; sub evens { return grep { ! ($_ % 2) } @_; } say for evens(1..10);
    2. Write a subroutine(&squares) that recieves an array of numbers and squares each number in the array. Note: nothing is returned.

    Since the subroutine is supposed to take an array but return nothing, I assume it is to change the array in place. So I'll pass the array as a reference:

    #!/usr/bin/env perl use Modern::Perl; sub squares { my $n = shift; $_ *= $_ for @$n; } my @nums = (1..10); squares(\@nums); say for @nums;
    3. Write a subroutine(&huge) that returns true if the number sent is greater than 1,000,000 or false(look up what is true and false). Show an example of calling the function.
    #!/usr/bin/env perl use Modern::Perl; sub huge { my $n = shift; return 1 if $n and $n > 1_000_000; return ! $n; # reverse the t/f for all other cases } for (-1,0,1,100,1_000_000, 1_000_001){ my $t = huge($_) ? 'true' : 'false'; say "$_ $t"; }

    Aaron B.
    Available for small or large Perl jobs; see my home node.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://995936]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (12)
As of 2014-10-20 14:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (77 votes), past polls