[bcn-pm] El problema del que os hable el Martes

Jordi Delgado jdelgadoalsi.upc.edu
Dij Jun 22 13:41:01 PDT 2006


Buenas,

El problema que os comente el pasado martes es el numero 3 del capitulo 4
de la llama (cuarta ed.):

Dice asi:

<--- Problema --->

Extra credit exercise: Write a subroutine, called &above_average, 
which takes a list of numbers and returns the ones which are above the 
average (mean). 
(Hint: Make another subroutine that calculates the average by dividing 
the total by the number of items.) Try your subroutine in this test program.

    my @fred = &above_average(1..10);
    print "\@fred is @fred\n";
    print "(Should be 6 7 8 9 10)\n";
    my @barney = &above_average(100, 1..10);
    print "\@barney is @barney\n";
    print "(Should be just 100)\n";

<--- Fin de problema --->

Ya veis, nada del otro jueves...

Mi solucion seria (os aviso que escribo codigo "a la Lisp", o lo que es
lo mismo "a la Python", por eso pongo las llaves de cerrar donde, de hecho,
no se ven, ya que leo codigo por indentacion)::

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

sub above_average {
    my $average = &average(@_);
    my @above;
    foreach (@_) {
	if ($_ > $average) {
	    push @above, $_ ; } }
    @above
}

Fijaos que uso la variable $_ por defecto en above_average.

La solucion de la llama dice (usa la sub 'total' de un ejercicio anterior,
pero esto no es importante):

<--- solucion llama --->

Here's one way to do it:

    sub average {
      if (@_ =  = 0) { return }
      my $count = @_;
      my $sum = &total(@_);               # from earlier exercise
      $sum/$count;
    }
    sub above_average {
      my $average = &average(@_);
      my @list;
      foreach $element (@_) {
        if ($element > $average) {
          push @list, $element;
        }
      }
      @list;
    }

In average, we return without giving an explicit return value if the 
parameter list is empty. That gives the caller undef[*] to report that 
no average comes from an empty list. If the list wasn't empty, using 
&total makes it simple to calculate the average. We didn't need to use 
temporary variables for $sum and $count, but doing so makes the code 
easier to read.

[*] Or an empty list, if &average is used in a list context.

The second sub, above_average, builds and returns a list of the desired items.
(Why is the control variable named $element instead of using Perl's favorite 
default, $_?) Note that this second sub uses a different technique for 
dealing with an empty parameter list.

<--- Fin solucion llama --->

Y ahi esta el comentario de marras!!
"Why is the control variable named $element instead of using Perl's favorite
default, $_?"

Mira que el problema es sencillo... y juraria que DA IGUAL usar una variable
$element que la variable por defecto $_ !
O no da igual???

La cosa es que estoy convencido que la respuesta es chorra, muy chorra (que
estamos en el capitulo 4!, muy sofisticada no puede ser), pero no lo
se ver.

A ver si me podeis echar una manita...

Gracias por adelantado

Salud!

Jordi

PS: Estoy seguro que me arrepentire de haber escrito este mensaje. Por favor,
los que veais que esto es trivial os rogaria recordarais las palabras de
Larry:

"Most important, you don't have to know everything there is to know about 
Perl before you can write useful programs. You can learn Perl "small end 
first". You can program in Perl Baby-Talk, and we promise not to laugh. Or 
more precisely, we promise not to laugh any more than we'd giggle at a 
child's creative way of putting things. Many of the ideas in Perl are borrowed
from natural language, and one of the best ideas is that it's okay to use a 
subset of the language as long as you get your point across. Any level of 
language proficiency is acceptable in Perl culture. 
We won't send the language police after you"






Més informació de la llista de correu Barcelona-pm