[23545] in Perl-Users-Digest

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

Perl-Users Digest, Issue: 5753 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Wed Nov 5 09:10:38 2003

Date: Wed, 5 Nov 2003 06:10:12 -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           Wed, 5 Nov 2003     Volume: 10 Number: 5753

Today's topics:
        Splitting an array into "even" parts <tore@aursand.no>
    Re: Splitting an array into "even" parts <ak+usenet@freeshell.org>
    Re: Splitting an array into "even" parts <REMOVEsdnCAPS@comcast.net>
    Re: Splitting an array into "even" parts <tore@aursand.no>
    Re: Splitting an array into "even" parts (Anno Siegel)
        text and html email (Popovici Nicolae)
    Re: using a hash as condition selector <fJogham@yahoo.com>
    Re: using a hash as condition selector <uri@stemsystems.com>
    Re: using a hash as condition selector (Anno Siegel)
    Re: Verbose warnings (Anno Siegel)
        wolk a byte code tree <pavel@gingerall.cz>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

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

Date: Wed, 05 Nov 2003 12:28:15 +0100
From: Tore Aursand <tore@aursand.no>
Subject: Splitting an array into "even" parts
Message-Id: <pan.2003.11.05.11.27.41.406592@aursand.no>

Hi there!

I need to split an array into "even" parts, so that each resulting array
contains the same number of elements.

Think of it as splitting a list of many names into multiple columns, and
you want x numbers of names in each column so that each column gets filled
up even-wise.

The problem arise, of course, when you have 10 elements and want to split
those into 3 columns.  That should be listed like this:

  +-------+-------+-------+
  | Col 1 | Col 2 | Col 3 |
  +-------+-------+-------+
  |    1  |    5  |    9  |
  |    2  |    6  |   10  |
  |    3  |    7  |       |
  |    4  |    8  |       |
  +-------+-------+-------+

So far I've come up with this solution:

  sub split_array {
      my $array = shift; # Array reference
      my $parts = shift; # Number of columns to split into

      ## Make sure $parts is set (default = 2), and that it isn't
      ## larger than the number of elements in $array
      $parts ||= 2;
      $parts = @$array if ( $parts > @$array );

      ## Split
      my @split = (); # Will contain the splitted data
      my $slice = POSIX::ceil( @$array / $parts ); # Size of each part

      for ( 1 .. $parts ) {
          if ( $_ == $parts ) {
              push( @split, $array );
          }
          else {
              push( @split, splice(@$array, 0, $slice) );
          }
      }

      ## Return
      return \@split;
  }

This code is doubtly the most efficient (I'm always looking for
efficient, yet readable, ways to do things), and I haven't run that many
tests on it either. Any comments on it?


-- 
Tore Aursand <tore@aursand.no>


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

Date: Wed, 5 Nov 2003 11:45:45 +0000 (UTC)
From: Andreas Kahari <ak+usenet@freeshell.org>
Subject: Re: Splitting an array into "even" parts
Message-Id: <slrnbqhon4.of8.ak+usenet@mx.freeshell.org>

In article <pan.2003.11.05.11.27.41.406592@aursand.no>, Tore Aursand wrote:
> Hi there!
> 
> I need to split an array into "even" parts, so that each resulting array
> contains the same number of elements.
[cut]
> This code is doubtly the most efficient (I'm always looking for
> efficient, yet readable, ways to do things), and I haven't run that many
> tests on it either. Any comments on it?

Here's something that doesn't rely on external modules:

sub split_array
{
    my $arr = shift;
    my $bins = shift;

    my $size = int((scalar @{ $arr })/$bins);

    if (scalar @{ $arr } % $bins != 0) {
	++$size;
    }

    my @result;

    for my $i (0 .. ($bins - 1)) {
	push @result, [ @{ $arr }[$i*$size .. (($i + 1)*$size - 1)] ];
    }

    return @result;
}

-- 
Andreas Kähäri


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

Date: Wed, 05 Nov 2003 06:25:41 -0600
From: "Eric J. Roode" <REMOVEsdnCAPS@comcast.net>
Subject: Re: Splitting an array into "even" parts
Message-Id: <Xns942A4B9315DBFsdn.comcast@216.196.97.136>

-----BEGIN xxx SIGNED MESSAGE-----
Hash: SHA1

Tore Aursand <tore@aursand.no> wrote in
news:pan.2003.11.05.11.27.41.406592@aursand.no: 

> Hi there!
> 
> I need to split an array into "even" parts, so that each resulting
> array contains the same number of elements.
> 
> Think of it as splitting a list of many names into multiple columns,
> and you want x numbers of names in each column so that each column
> gets filled up even-wise.
> 
> The problem arise, of course, when you have 10 elements and want to
> split those into 3 columns.  That should be listed like this:
> 
>   +-------+-------+-------+
>  | Col 1 | Col 2 | Col 3 |
>   +-------+-------+-------+
>  |    1  |    5  |    9  |
>  |    2  |    6  |   10  |
>  |    3  |    7  |       |
>  |    4  |    8  |       |
>   +-------+-------+-------+
> 
> So far I've come up with this solution:
> 
>   sub split_array {
>       my $array = shift; # Array reference
>       my $parts = shift; # Number of columns to split into
> 
>       ## Make sure $parts is set (default = 2), and that it isn't
>       ## larger than the number of elements in $array
>       $parts ||= 2;
>       $parts = @$array if ( $parts > @$array );
> 
>       ## Split
>       my @split = (); # Will contain the splitted data
>       my $slice = POSIX::ceil( @$array / $parts ); # Size of each part
> 
>       for ( 1 .. $parts ) {
>           if ( $_ == $parts ) {
>               push( @split, $array );
>           }
>           else {
>               push( @split, splice(@$array, 0, $slice) );
>           }
>       }
> 
>       ## Return
>       return \@split;
>   }
> 
> This code is doubtly the most efficient (I'm always looking for
> efficient, yet readable, ways to do things), and I haven't run that
> many tests on it either. Any comments on it?

aplice() pretty much does what you want by itself -- there's no need for 
all the special-case-handling code you are surrounding it with.

    sub split_array
    {
        my $array = shift;
        my $parts = shift || 2;
        my @array = @$array;     # working copy
        my @split;               # result

        while (@array)
        {
            push @split, [splice @array, 0, $parts];
        }
        return \@split;
    }

or even:

    push @split, [splice @array, 0, $parts]  while @array;

- -- 
Eric
$_ = reverse sort $ /. r , qw p ekca lre uJ reh
ts p , map $ _. $ " , qw e p h tona e and print

-----BEGIN xxx SIGNATURE-----
Version: PGPfreeware 7.0.3 for non-commercial use <http://www.pgp.com>

iQA/AwUBP6jsRmPeouIeTNHoEQJN/gCdG6n983iPY7jp14peWtV09TyG21AAnRH1
pu+8ZH/a6uRkk+sUbRLGbfx0
=fmD3
-----END PGP SIGNATURE-----


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

Date: Wed, 05 Nov 2003 14:12:28 +0100
From: Tore Aursand <tore@aursand.no>
Subject: Re: Splitting an array into "even" parts
Message-Id: <pan.2003.11.05.13.07.37.613447@aursand.no>

On Wed, 05 Nov 2003 06:25:41 -0600, Eric J. Roode wrote:
>     sub split_array
>     {
>         my $array = shift;
>         my $parts = shift || 2;
>         my @array = @$array;     # working copy
>         my @split;               # result
> 
>         while (@array)
>         {
>             push @split, [splice @array, 0, $parts];
>         }
>         return \@split;
>     }

Fine solution, indeed, but still not satisfying me needs.  Let's take a
look at an example:

  my @array = ( 1..9 );
  my $parts = 4;

Expected result should be:

  [
    [1,2,3],
    [4,5],
    [6,7],
    [8,9]
  ]

But your function only returns 3 arrays.  A note begins to form in my back
head:  Make sure that @array is splittable in $parts parts. :-)


-- 
Tore Aursand <tore@aursand.no>


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

Date: 5 Nov 2003 13:52:42 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: Splitting an array into "even" parts
Message-Id: <boavba$b2o$1@mamenchi.zrz.TU-Berlin.DE>

Tore Aursand  <tore@aursand.no> wrote in comp.lang.perl.misc:
> On Wed, 05 Nov 2003 06:25:41 -0600, Eric J. Roode wrote:
> >     sub split_array
> >     {
> >         my $array = shift;
> >         my $parts = shift || 2;
> >         my @array = @$array;     # working copy
> >         my @split;               # result
> > 
> >         while (@array)
> >         {
> >             push @split, [splice @array, 0, $parts];
> >         }
> >         return \@split;
> >     }
> 
> Fine solution, indeed, but still not satisfying me needs.  Let's take a
> look at an example:
> 
>   my @array = ( 1..9 );
>   my $parts = 4;
> 
> Expected result should be:
> 
>   [
>     [1,2,3],
>     [4,5],
>     [6,7],
>     [8,9]
>   ]

Well, here's a variant that does that.  It returns the array of split
parts directly, not a reference to it, but that's trivial to fix.

    sub split_array {
        my $parts = shift || 2;
        my @array = @{ shift()};
        my $size = int @array/$parts;
        my $rem = @array % $parts;
        map [splice @array, 0, $size + ($rem-- > 0)], 1 .. $parts;
    }


Anno


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

Date: 5 Nov 2003 05:50:57 -0800
From: octavp_2000@yahoo.com (Popovici Nicolae)
Subject: text and html email
Message-Id: <e32ba0d5.0311050550.385e9948@posting.google.com>

Hello guys,

  Here is my dilema. I am getting my emails using a perl script and
with Mail::Pop3Client module. Now, when I am reading my emails with
BodyToFile , I get the plain/text message and also the plain/html one.
How can I get rid of the plain/html part ?

Any ideeas ?
Thanks.


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

Date: Wed, 05 Nov 2003 17:51:36 +1100
From: Fred <fJogham@yahoo.com>
Subject: Re: using a hash as condition selector
Message-Id: <3FA89DF8.4090201@yahoo.com>

Gunnar Hjalmarsson wrote:

> 
> What made you think that a hash key can be an expression? 

Book: Beginning Perl
Chapter 4:  Loops and Decisions
Page 128: More Elegant Solutions
http://learn.perl.org/library/beginning_perl/3145_Chap04.pdf

I hope I did not mis-unserstood the authoer. or maybe I could.

thanks



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

Date: Wed, 05 Nov 2003 06:59:22 GMT
From: Uri Guttman <uri@stemsystems.com>
Subject: Re: using a hash as condition selector
Message-Id: <x74qxjgv1y.fsf@mail.sysarch.com>

>>>>> "F" == Fred  <fJogham@yahoo.com> writes:

  F> Gunnar Hjalmarsson wrote:
  >> What made you think that a hash key can be an expression?

  F> Book: Beginning Perl
  F> Chapter 4:  Loops and Decisions
  F> Page 128: More Elegant Solutions
  F> http://learn.perl.org/library/beginning_perl/3145_Chap04.pdf

  F> I hope I did not mis-unserstood the authoer. or maybe I could.

where in that text did you see anything remotely like what your code was
like? and the book says the code in a hash will be shown a few chapters
later. so please read that chapter and don't just type random characters
at perl and hope it does what you wish.

uri

-- 
Uri Guttman  ------  uri@stemsystems.com  -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs  ----------------------------  http://jobs.perl.org


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

Date: 5 Nov 2003 09:48:49 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: using a hash as condition selector
Message-Id: <boah21$59$1@mamenchi.zrz.TU-Berlin.DE>

Fred  <news@group.com> wrote in comp.lang.perl.misc:
> 
> Hello
> I have
> my %hcond =(
> 	   condition => "1",
> 	   condition => "2"
> 	   );
> 
> where condition is ($a > $b and $s * $k < $f - 3)
> I have many conditions in this hash.

No, you don't, not in the hash keys.  A perl scalar can hold a
"condition" in the form of a coderef, but hash keys are strings,
not general scalars.


> in a code where I need the value out of the hash based on the condition.
> the values of all the variables are known at the time the hash value is 
> needed but do I have to
> 
> ...code
> ...
> $value = $hcond{$long_condition_written_here}
> ...
> or there is a better way?

You may want to put your conditions in an array (not a hash), where
the array index is the number of the condition to return:

    my ( $a, $b, $s, $k, $f);

    my @cond;
    BEGIN {
        @cond = (
            sub { 0 },                # always false
            sub { $a > $b },          # cond. 1
            sub { $s * $k < $f - 3 }, # cond. 2
            sub { 1 },                # catch-all
        );
    }

    sub get_cond {
        $cond[ $_]->() and return $_ for 0 .. $#cond;
    }

Don't forget to assign values to $a...$f before you call get_cond.

Anno


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

Date: 5 Nov 2003 11:54:29 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: Verbose warnings
Message-Id: <boaodl$6dg$1@mamenchi.zrz.TU-Berlin.DE>

Richard Voss  <erutiurf@web.de> wrote in comp.lang.perl.misc:
> Greg Bacon wrote:
> > In article <3fa6ba78$0$1100$3c090ad1@news.plethora.net>,
> >     Seebs <seebs@plethora.net> wrote:
> > 
> > : Is there any way to find out WHICH variable is uninitialized, short of
> > : breaking a line up into bunches of single lines?
> > : [...]
> > 
> > Here's a start:
> 
> that will only work with package variables, not with lexicals.
> 
> I recommend the debugger.

I have occasionally used something along these lines, which works for
lexicals and package variables, and, in fact, for arbitrary Perl
expressions:

    sub report_undef {
        my $vars = join ', ', map "'$_'", @_;
        my $expr = qq|join( ', ', grep not( defined( eval( \$_))), $vars)|;
        qq|print 'undef: ', $expr, "\\n"|;
    }

If the code is, for example,

    my ( $a, $b, $s, $k, $f);
    $b = 123;
    $k = 'aaa';

add the line

    eval report_undef( qw( $a $b $s $k $f));

to see that $a, $s, and $f are undefined.  You still have to type
"eval" literally, and name the variables you want to check.  This
is necessary (along with the weirdness of the code in report_undef()),
so that the variables you want to check don't have to be in the
scope where report_undef() is compiled.

Anno


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

Date: Wed, 05 Nov 2003 13:22:42 +0100
From: Pavel Hlavnicka <pavel@gingerall.cz>
Subject: wolk a byte code tree
Message-Id: <boaq40$29pf$1@ns.felk.cvut.cz>

Hi all,

this is a bit advanced question. I'm developing and application which is 
a finite state automaton, where actions to be take on particular state 
are described in an external configuration files as a Perl expressions.

To keep the code as safe as possible, I want to allow only particular 
function names and variable names might be used in such external 
expressions and run a Perl interpreter in a taint mode.

What I need is to pre-check the expression to be evaluated. Regular 
expression could become quite complex for this stuff, while walking the 
byte code tree seems to be a simple recursive algorithm.

Problem is, that I have no clue where to start and I'm to lazy :) and 
under such a time pressure that I need your help. {Please give me some 
tips, where to start and how to walk a instruction tree. All I need is 
to quit if non-desired tree item is met. I think 'B' module family is 
the solution.

Thank you VERY much in advance.

Pavel

-- 
Pavel Hlavnicka
Ginger Alliance
www.gingerall.com



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

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.  

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 V10 Issue 5753
***************************************


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