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

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

[*] 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...

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