Re: how to recursion

2017-03-29 Thread PYH

I asked this just b/c I want to do matrix calculation in perl.
I found under some conditions a recursion is more effective.

Thanks everybody.

On 2017/3/29 23:31, Chas. Owens wrote:

On Tue, Mar 28, 2017 at 9:27 PM PYH <p...@vodafonemail.de
<mailto:p...@vodafonemail.de>> wrote:

Hi,

what's the better way to write a recursion in perl's class?

sub my_recursion {
 my $self = shift;
 
 if (...) {
 $self->my_recursion;
 }
}

this one?


Define better. In general that is the right form (assuming there is some
side effect to calling my_recursion that will cause the if statement to
be false).  If your function is tail recursive and it has the potential
to be deeply nested, then you can take advantage of a quirk of goto to
make it faster and use less memory:

#!/usr/bin/perl

use strict;
use warnings;

{ package A;
sub new { bless {}, shift }

sub recur {
my ($self, $n) = @_;

return "recur done" if $n <= 0;
return $self->recur($n - 1);
}

sub tail_recur {
my ($self, $n) = @_;

return "tail_recur done" if $n <= 0;
@_ = ($self, $n - 1);
goto _recur;
}
}

my $o = A->new;

print $o->recur(1_000_000), "\n";
print $o->tail_recur(1_000_000), "\n";

NOTE: this only works if the code is tail recursive.  That is, the
recursive function does nothing but return the next call's return
value.  It works by replacing the function with itself rather than
pushing another copy of the function on the stack.



--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Fw: how to recursion

2017-03-29 Thread Shlomi Fish
Forwarding to the list.

Begin forwarded message:

Date: Wed, 29 Mar 2017 11:32:08 -0400
From: Shawn H Corey <shawnhco...@gmail.com>
To: Shlomi Fish <shlo...@shlomifish.org>
Subject: Re: how to recursion


On Wed, 29 Mar 2017 17:22:36 +0300
Shlomi Fish <shlo...@shlomifish.org> wrote:

> my_recursion accepts $self as its first argument, so you should pass
> it there. Doing «my_recursion($self);» is one option for doing that
> but : 1. It looks ugly. 2. It's less future proof. 3. It's a bad
> practice for OOP perl.
> 
> The original code was fine.  

Oops, you're right. the OOLs I've been using lately take care self (or
this) automatically. I had forgotten that Perl is an OO toolkit, not an
OOL. ☺


-- 
Don't stop where the ink does.

Shawn H Corey

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: how to recursion

2017-03-29 Thread Chas. Owens
On Tue, Mar 28, 2017 at 9:27 PM PYH <p...@vodafonemail.de> wrote:

> Hi,
>
> what's the better way to write a recursion in perl's class?
>
> sub my_recursion {
>  my $self = shift;
>  
>  if (...) {
>  $self->my_recursion;
>  }
> }
>
> this one?
>

Define better. In general that is the right form (assuming there is some
side effect to calling my_recursion that will cause the if statement to be
false).  If your function is tail recursive and it has the potential to be
deeply nested, then you can take advantage of a quirk of goto to make it
faster and use less memory:

#!/usr/bin/perl

use strict;
use warnings;

{ package A;
sub new { bless {}, shift }

sub recur {
my ($self, $n) = @_;

return "recur done" if $n <= 0;
return $self->recur($n - 1);
}

sub tail_recur {
my ($self, $n) = @_;

return "tail_recur done" if $n <= 0;
@_ = ($self, $n - 1);
goto _recur;
}
}

my $o = A->new;

print $o->recur(1_000_000), "\n";
print $o->tail_recur(1_000_000), "\n";

NOTE: this only works if the code is tail recursive.  That is, the
recursive function does nothing but return the next call's return value.
It works by replacing the function with itself rather than pushing another
copy of the function on the stack.


Re: how to recursion

2017-03-29 Thread Shlomi Fish
Hi Shawn!

On Wed, 29 Mar 2017 08:09:12 -0400
Shawn H Corey  wrote:

> On Wed, 29 Mar 2017 09:25:06 +0800
> PYH  wrote:
> 
> > sub my_recursion {
> >  my $self = shift;
> >  
> >  if (...) {
> >  $self->my_recursion;  
> 
> # you don't need $self. subroutine lookup starts
> # in the same package. Just the sub by itself
> # is good enough.
> my_recursion();
> 

my_recursion accepts $self as its first argument, so you should pass it there.
Doing «my_recursion($self);» is one option for doing that but : 1. It looks
ugly. 2. It's less future proof. 3. It's a bad practice for OOP perl.

The original code was fine.

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: how to recursion

2017-03-29 Thread Shawn H Corey
On Wed, 29 Mar 2017 09:25:06 +0800
PYH <p...@vodafonemail.de> wrote:

> sub my_recursion {
>  my $self = shift;
>  
>  if (...) {
>  $self->my_recursion;

# you don't need $self. subroutine lookup starts
# in the same package. Just the sub by itself
# is good enough.
my_recursion();

>      }
> }

More thoughts on recursion:
https://lookatperl.blogspot.ca/2012/11/a-look-at-recursion.html


-- 
Don't stop where the ink does.

Shawn H Corey

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: how to recursion

2017-03-28 Thread Uri Guttman

On 03/28/2017 09:25 PM, PYH wrote:

Hi,

what's the better way to write a recursion in perl's class?

sub my_recursion {
my $self = shift;

if (...) {
$self->my_recursion;
}
}

this one?


i am not sure what you mean by better. your code would work if you 
finished it with a proper argument check. recursive code must always 
have a clean way to end the recursion and pop up the stack. and you 
don't need OO to do recursion either. perl supports recursion in general.


uri

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




how to recursion

2017-03-28 Thread PYH

Hi,

what's the better way to write a recursion in perl's class?

sub my_recursion {
my $self = shift;

if (...) {
$self->my_recursion;
}
}

this one?

thanks.

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




generate XML from recursion

2015-07-08 Thread Nagy Tamas (TVI-GmbH)
Hi,

Thanks for the solutions of the recent problems.

I would like to traverse a dir on the HDD at a part of the XML generation.
So I generated about 75% of an xml file with xml::writer, and it comes a
Projectstructure tag. Between these tag I simply list a dir into empty tags 
Object attr=./.
If recursion is ready, the closing Projectstructure tag closes it. And non 
recursive XML
generation continues.

$output = IO::File-new(default.xml);

$writer = XML::Writer-new(OUTPUT = $output, DATA_MODE = 1, DATA_INDENT =   
, ENCODING = utf-8, NEWLINES = 0 );

Traverse($dir, $writer);
sub Traverse
{
opendir(DIR, $dir) or die Cannot open directory $dir: $!\n;
my @files = readdir(DIR);
closedir(DIR);
foreach my $file (@files) {
# generate XML here

   print $file;
   if(-d $file and ($file !~ /^\.\.?$/) ) {
   # make dir branch
   Traverse($file);
   }
   $writer-emptyTag(Object, Name = $file);
   # make file branch
}
}


...

$writer-startTag(ProjectStructure);

Traverse(C:\\ph);

$writer-endTag(ProjectStructure);

But it gives a hideous error:

Attempt to insert empty tag after close of document element at t2tot3Project 
line 72.

How can it be? I call the subrutine in the middle of a tag. How can be the 
document closed?

Tamas



Re: generate XML from recursion

2015-07-08 Thread Andy Bach
On Wed, Jul 8, 2015 at 10:51 AM, Nagy Tamas (TVI-GmbH) 
tamas.n...@tvi-gmbh.de wrote:

 How can it be? I call the subroutine in the middle of a tag. How can be
 the document closed?


Well, I don't get that (could it be that call to
Travers($dir,$writer);

before the sub def?) but to get your code to work I had to keep the dir
involved
sub Traverse
{
my $dir = shift;
opendir(DIR, $dir) or die Cannot open directory $dir:
$!\n;
my @files = readdir(DIR);
closedir(DIR);

foreach my $file (@files) {
# generate XML here
   if(-d $dir/$file and ($file !~ /^\.\.?$/)
) {
   # make dir branch
   Traverse($dir/$file);
   }



-- 

a

Andy Bach,
afb...@gmail.com
608 658-1890 cell
608 261-5738 wk


Re: Can recursion eliminate nested foreach() loops?

2012-03-05 Thread Dr.Ruud

On 2012-02-27 03:52, Shawn H Corey wrote:


There is no simplify way of doing this.


perl -wle '
  my $s = {red,green,blue},{small,large},{light,dark};
  print for glob $s;
'

--
Ruud

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Can recursion eliminate nested foreach() loops?

2012-02-27 Thread Paul Johnson
On Sun, Feb 26, 2012 at 09:30:44PM -0500, Steve Bertrand wrote:
 I came across a question early this morning on a forum that
 intrigued me. I literally spent about five hours trying everything
 to solve it, but I couldn't.

Sometimes Perl is just a means to get at the corect tool:

my $attributes =
[
  { type = 'colors',  values = [qw/red green blue/]  },
  { type = 'sizes',   values = [qw/small large/] },
  { type = 'shades',  values = [qw/light dark/] },
];

local $ = ,;
say y/-/ /r for glob join -, map {@{$_-{values}}}, @$attributes;


red small light
red small dark
red large light
red large dark
green small light
green small dark
green large light
green large dark
blue small light
blue small dark
blue large light
blue large dark


or perhaps you like commas but dislike maintenance programmers:

my $attributes =
[
  { type = 'colors',  values = [qw/red green blue/]  },
  { type = 'sizes',   values = [qw/small large/] },
  { type = 'shades',  values = [qw/light dark/] },
];

$=,;say for(glob(qq{@{[map+qq{{@{$_-{values,@$attributes]}}))


red,small,light
red,small,dark
red,large,light
red,large,dark
green,small,light
green,small,dark
green,large,light
green,large,dark
blue,small,light
blue,small,dark
blue,large,light
blue,large,dark


The key here is using globbing.  See perldoc -f glob for the details.  Using
bsd_glob would clean up the (first) code a little.

 I know this isn't a beginner's question

None of the concepts in this code are particularly tricky, but there are
quite a few of them in a short piece of code.

Is there a way to simplify this within Perl?

I suppose the question of whether or not this is simplified comes down to
definitions.

-- 
Paul Johnson - p...@pjcj.net
http://www.pjcj.net

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Can recursion eliminate nested foreach() loops?

2012-02-26 Thread Steve Bertrand
I came across a question early this morning on a forum that intrigued 
me. I literally spent about five hours trying everything to solve it, 
but I couldn't.


Every attempt at recursion, counting, numbering, hashing etc failed. Is 
there a way to use recursion to eliminate the repeated and 
pre-calculated calls to foreach as this OP is asking?


From ... .. ... is verbatim 'dms000'

...

I need to generate a list of combinations from a data structure such as:

my $attributes =
[
  { type = 'colors',  values = [qw/red green blue/]  },
  { type = 'sizes',   values = [qw/small large/] },
  { type = 'shades',  values = [qw/light dark/] },
];

It is easy enough when the number of types are known:

my @combos = ();
foreach my $a (@{$attributes-[0]-{values}}) {
  foreach my $b (@{$attributes-[1]-{values}}) {
foreach my $c (@{$attributes-[2]-{values}}) {
  push @combos, [$a, $b, $c];
}
  }
}

Which results in a list such as:
red small light
red small dark
red large light
red large dark
green small light
...

But how to do with arbitrary number of types? Obviously will need 
recursion but I can't figure it out. The only thing I could come up with 
was generating code like code2 as a string and eval()ing it...a poor 
solution.


...

I know this isn't a beginner's question, but I know there are geniuses 
here. Is there a way to simplify this within Perl?


Steve

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Can recursion eliminate nested foreach() loops?

2012-02-26 Thread Shawn H Corey

On 12-02-26 09:30 PM, Steve Bertrand wrote:

I know this isn't a beginner's question, but I know there are geniuses
here. Is there a way to simplify this within Perl?


There is no simplify way of doing this. Separate off the first attribute 
and cross-product it with a recursive call to the rest. Like this:


#!/usr/bin/env perl

use strict;
use warnings;

my $attributes =
[
  { type = 'colors',  values = [qw/red green blue/]  },
  { type = 'sizes',   values = [qw/small large/] },
  { type = 'shades',  values = [qw/light dark/] },
];

sub combo {
  my @traits = @_;

  # nothing given, nothing returned
  return if @traits == 0;

  # return the last list
  if( @traits == 1 ){
return map { [ $_ ] } @{ $traits[0]{values} };
  }

  # get the combos for everything but the first one
  my @combos = combo( @traits[ 1 .. $#traits ] );

  # now combine them
  my @result = ();
  for my $first ( @{ $traits[0]{values} } ){
for my $rest ( @combos ){
  push @result, [ $first, @$rest ];
}
  }

  return @result;
}

my @list = combo( @$attributes );

for my $set ( @list ){
  print @$set\n;
}

__END__

--
Just my 0.0002 million dollars worth,
  Shawn

Programming is as much about organization and communication
as it is about coding.

It's Mutual Aid, not fierce competition, that's the dominate
force of evolution.  Of course, anyone who has worked in
open source already knows this.

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Can recursion eliminate nested foreach() loops?

2012-02-26 Thread Steve Bertrand

On 2012-02-26 21:52, Shawn H Corey wrote:

On 12-02-26 09:30 PM, Steve Bertrand wrote:

I know this isn't a beginner's question, but I know there are geniuses
here. Is there a way to simplify this within Perl?


There is no simplify way of doing this. Separate off the first attribute
and cross-product it with a recursive call to the rest. Like this:

#!/usr/bin/env perl

use strict;
use warnings;

my $attributes =
[
{ type = 'colors', values = [qw/red green blue/] },
{ type = 'sizes', values = [qw/small large/] },
{ type = 'shades', values = [qw/light dark/] },
];

sub combo {
my @traits = @_;

# nothing given, nothing returned
return if @traits == 0;

# return the last list
if( @traits == 1 ){
return map { [ $_ ] } @{ $traits[0]{values} };
}

# get the combos for everything but the first one
my @combos = combo( @traits[ 1 .. $#traits ] );

# now combine them
my @result = ();
for my $first ( @{ $traits[0]{values} } ){
for my $rest ( @combos ){
push @result, [ $first, @$rest ];
}
}

return @result;
}

my @list = combo( @$attributes );

for my $set ( @list ){
print @$set\n;
}


Tres Bien!!! Merci Beaucoup!!

Thank you so much :)

I will pour over this code until I completely understand it. I knew I 
came to the right place!


Steve

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Can recursion eliminate nested foreach() loops?

2012-02-26 Thread Steve Bertrand

On 2012-02-26 21:52, Shawn H Corey wrote:

On 12-02-26 09:30 PM, Steve Bertrand wrote:

I know this isn't a beginner's question, but I know there are geniuses
here. Is there a way to simplify this within Perl?


There is no simplify way of doing this. Separate off the first attribute
and cross-product it with a recursive call to the rest. Like this:


fyi: http://forums.devshed.com/perl-programming-6/recursion-help-882763.html

Steve

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Can recursion eliminate nested foreach() loops?

2012-02-26 Thread Rob Dixon

On 27/02/2012 02:30, Steve Bertrand wrote:

I came across a question early this morning on a forum that intrigued
me. I literally spent about five hours trying everything to solve it,
but I couldn't.

Every attempt at recursion, counting, numbering, hashing etc failed. Is
there a way to use recursion to eliminate the repeated and
pre-calculated calls to foreach as this OP is asking?

 From ... .. ... is verbatim 'dms000'

...

I need to generate a list of combinations from a data structure such as:

my $attributes =
[
{ type = 'colors', values = [qw/red green blue/] },
{ type = 'sizes', values = [qw/small large/] },
{ type = 'shades', values = [qw/light dark/] },
];

It is easy enough when the number of types are known:

my @combos = ();
foreach my $a (@{$attributes-[0]-{values}}) {
foreach my $b (@{$attributes-[1]-{values}}) {
foreach my $c (@{$attributes-[2]-{values}}) {
push @combos, [$a, $b, $c];
}
}
}

Which results in a list such as:
red small light
red small dark
red large light
red large dark
green small light
...

But how to do with arbitrary number of types? Obviously will need
recursion but I can't figure it out. The only thing I could come up with
was generating code like code2 as a string and eval()ing it...a poor
solution.

...

I know this isn't a beginner's question, but I know there are geniuses
here. Is there a way to simplify this within Perl?


Hi Steve

Much of the complexity comes from working with the nested data
structure. Writing a subroutine that takes just a set of the 'values'
arrays cleans things up a lot. Take a look at the program below.

HTH,

Rob


use strict;
use warnings;

my $attributes = [
  { type = 'colors',  values = [qw/red green blue/]  },
  { type = 'sizes',   values = [qw/small large/] },
  { type = 'shades',  values = [qw/light dark/] },
];

print $_\n foreach combos(map $_-{values}, @$attributes);

sub combos {

  my $first = shift;

  return @$first unless @_;

  my @combinations;

  foreach my $beg (@$first) {
foreach my $end (combos(@_)) {
  push @combinations, $beg $end;
}
  }

  return @combinations;
}

**OUTPUT**

red small light
red small dark
red large light
red large dark
green small light
green small dark
green large light
green large dark
blue small light
blue small dark
blue large light
blue large dark

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Can recursion eliminate nested foreach() loops?

2012-02-26 Thread Steve Bertrand

On 2012-02-26 23:55, Rob Dixon wrote:

On 27/02/2012 02:30, Steve Bertrand wrote:



I know this isn't a beginner's question, but I know there are geniuses
here. Is there a way to simplify this within Perl?


Hi Steve

Much of the complexity comes from working with the nested data
structure. Writing a subroutine that takes just a set of the 'values'
arrays cleans things up a lot. Take a look at the program below.


In my mind, I knew that map() had to fit in someplace, but by the time I 
thought about map, I was ready to ask for help instead of performing the 
Schwartzian Transform physically on my keyboard :)


This is another great piece of code I (and others) can study. I'm 
leaving it below. Thank you Rob!



use strict;
use warnings;

my $attributes = [
{ type = 'colors', values = [qw/red green blue/] },
{ type = 'sizes', values = [qw/small large/] },
{ type = 'shades', values = [qw/light dark/] },
];

print $_\n foreach combos(map $_-{values}, @$attributes);

sub combos {

my $first = shift;

return @$first unless @_;

my @combinations;

foreach my $beg (@$first) {
foreach my $end (combos(@_)) {
push @combinations, $beg $end;
}
}

return @combinations;
}


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: [PBML] Help needed in recursion with objects in perl !

2010-08-07 Thread Amit Saxena
On Fri, Aug 6, 2010 at 8:09 PM, Randal L. Schwartz mer...@stonehenge.comwrote:

  Amit == Amit Saxena learn.tech...@gmail.com writes:

 Amit I am working on a tree implementation (with any number of parent
 Amit and child nodes) in perl. Every node is defined as a object of a
 Amit Node class which I have created as a .pm module.

 Unless this is for a student exercise, you probably just want to look at
 Graph in the CPAN.  Lots and lots and lots of graph traversal things
 already worked out for you.

 --
 Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
 mer...@stonehenge.com URL:http://www.stonehenge.com/merlyn/
 Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.
 See http://methodsandmessages.vox.com/ for Smalltalk and Seaside
 discussion



Thanks Randal for the reply.

The purpose of this activity is to model a hierarchical representation of
dependent components, each of one will be represented as a service.

I had a look at the Graph module (
http://search.cpan.org/~jhi/Graph-0.94/lib/Graph.pod) but I am not sure how
it can be used to implement multiple parent and multiple child
implementation of a tree. In other words, I would like to have similar
methods which are available in the Tree implementations in CPAN.

Please suggest.

Thanks  Regards,
Amit Saxena


Re: [PBML] Help needed in recursion with objects in perl !

2010-08-07 Thread Chas. Owens
On Sat, Aug 7, 2010 at 09:36, Amit Saxena learn.tech...@gmail.com wrote:
snip
 The purpose of this activity is to model a hierarchical representation of
 dependent components, each of one will be represented as a service.

 I had a look at the Graph module (
 http://search.cpan.org/~jhi/Graph-0.94/lib/Graph.pod) but I am not sure how
 it can be used to implement multiple parent and multiple child
 implementation of a tree. In other words, I would like to have similar
 methods which are available in the Tree implementations in CPAN.
snip

A [tree][0] is a [Graph][1].  Often you will see trees implemented as
[Directed Acyclic Graphs][2] (or DAGs) because pointers or references
only flow one way.  Here is an example using the [Graph][3] module:

#!/usr/bin/perl

use strict;
use warnings;

use Graph;

#FIXME: naive implementation, there may be a much better way to do this
sub run_in_parallel {
my $g = shift-copy;

while (my @v = $g-vertices) {
my @run = grep { $g-is_successorless_vertex($_) } @v;
print running , join(, , @run),  in parallel\n;
for my $compenent (@run) {
$g-delete_vertex($compenent);
};
}
}

my $g = Graph-new;
my $f = Graph-new;
while (DATA) {
my ($component, @dependencies) = split;
unless ($g-has_vertex($component)) {
$g-add_vertex($component);
$f-add_vertex($component);
}
for my $dependency (@dependencies) {
unless ($g-has_vertex($dependency)) {
$g-add_vertex($dependency);
$f-add_vertex($dependency);
}
$g-add_edge($dependency, $component);
$f-add_edge($component, $dependency);
}
}

print everything will work if you run the programs in this order: ,
join(, , $g-topological_sort), \n;

run_in_parallel($f);

#component  dependency list
__DATA__
a   b c d
b   e
c   f g
d
e
f
g


 [0]: http://en.wikipedia.org/wiki/Tree_(graph_theory)
 [1]: http://en.wikipedia.org/wiki/Graph_(mathematics)
 [2]: http://en.wikipedia.org/wiki/Directed_acyclic_graph
 [3]: http://search.cpan.org/dist/Graph/lib/Graph.pod

-- 
Chas. Owens
wonkden.net
The most important skill a programmer can have is the ability to read.

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Help needed in recursion with objects in perl !

2010-08-06 Thread Amit Saxena
Hi all,

I am working on a tree implementation (with any number of parent and child
nodes) in perl. Every node is defined as a object of a Node class which I
have created as a .pm module.

I have defined a method getParentNodes which returns reference to an array
having all the (immediate) parent nodes objects as shown below.

my @immediate_parent_node_objects = $node1-getParentNodes ();
my $i;
foreach $i ( @{$node1-getParentNodes ()} )
{
print Parent node for the child node  . $node1-getNodeName() .  is 
. $i-getNodeName() \n;
}

I want to define another method named getParentNodesRecurse which will
return either all or upto a level of (ancestor) parent nodes objects instead
of immediate parent node objects. I tried to implement something similar to
what's shown below but I am unable to achieve it.


sub getParentNodesRecurse
{
my ( $self, $level ) = @_;

print \t x $level . node name = [ . $self-getNodeName() . ], level
= [$level]\n;
#print level = [$level]\n;

if ( ! defined $self-getParentNodes() )
{
print \t x $level . (No parent nodes for the node [ .
$self-getNodeName() . ])\n;

return;
}

my @concatenated_list_of_parent_nodes;
my $l;
foreach $l ( @{$self-getParentNodes()} )
{
@concatenated_list_of_parent_nodes = (
@concatenated_list_of_parent_nodes, getParentNodesRecurse( $l, $level+1 )
);
}

print \n;

print Returning the concatenation of following two lists : \n;
print  . @{$self-getParentNodes()} . \n;
print [ . @concatenated_list_of_parent_nodes . ]\n;
print \n;
return ( \( @{$self-getParentNodes()},
@concatenated_list_of_parent_nodes ) );
}


Please help and also let me know in case there is a better way to implement.
I can even rewrite my implementation using different design. I tried looking
for modules on CPAN which supports tree implementation with multiple parents
and child but couldn't find it.

Note : For some reasons, I don't want to use implementation which requires
$_.

Thanks  Regards,
Amit Saxena


Re: [PBML] Help needed in recursion with objects in perl !

2010-08-06 Thread Randal L. Schwartz
 Amit == Amit Saxena learn.tech...@gmail.com writes:

Amit I am working on a tree implementation (with any number of parent
Amit and child nodes) in perl. Every node is defined as a object of a
Amit Node class which I have created as a .pm module.

Unless this is for a student exercise, you probably just want to look at
Graph in the CPAN.  Lots and lots and lots of graph traversal things
already worked out for you.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
mer...@stonehenge.com URL:http://www.stonehenge.com/merlyn/
Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.
See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: File::Find NO RECURSION Howto

2010-03-03 Thread Shlomi Fish
On Monday 01 Mar 2010 19:31:15 Shawn H Corey wrote:
 Shlomi Fish wrote:
  Well, Matt S. Trout shared his sentiments about I cannot use CPAN here:
  
  http://www.shadowcat.co.uk/blog/matt-s-trout/but-i-cant-use-cpan/
 
 Well, Matt is wrong.  You can't always use CPAN.  Yes, you can set it up
 so you can use it in development, but that doesn't mean you can do it in
 production.  I have worked in places where the policy was no software
 that's not approved by the sysadmins and approval of a single module may
 take 6 to 18 months.  They're even very strict about downloading a copy
 and cut  paste.  A foolish policy, kinda like, our horse will never get
 sick from bad grain if we never feed it but managers _always_ know best. 
 ;)

Heh, tell me about it. Medium-to-large businesses shoot themselves in the foot 
by incorporating these god-awful policies and becoming very non-agile. Then 
they wonder why startups with much fewer resources can often easily out-
compete them. I read somewhere (Paul Graham I think, but I can no longer find 
it) that as companies grow they adopt more and more rules and regulations 
after learning from mistakes they made in the past. But these rules prevent a 
lot of legitimate actions and in turn make the company much less agile. And 
sometimes they impose these rules on start-ups that they buy.

It was later compared to 
http://en.wikipedia.org/wiki/Sarbanes%E2%80%93Oxley_Act which killed the IPOs 
in .us and was another regulation that was passed and which had unwanted side-
effects.

In any case, such antagonism towards using third-party code will make the 
person working for such companies beyond help and doomed anyway you look at 
it, so we can ignore it.

Regards,

Shlomi Fish

-- 
-
Shlomi Fish   http://www.shlomifish.org/
Understand what Open Source is - http://shlom.in/oss-fs

Deletionists delete Wikipedia articles that they consider lame.
Chuck Norris deletes deletionists whom he considers lame.

Please reply to list if it's a mailing list post - http://shlom.in/reply .

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




File::Find NO RECURSION Howto

2010-03-01 Thread raphael()
Hi,

How can I stop File::Find to go below current dir? i.e. no recursion.

Although I can use glob or * to get file names in current dir.
But I wanted to know if File::Find has a maxdepth limit like linux find.

The script I created uses a switch which decides if recursion is allowed or
not.
It uses the system find like this..

open(FIND, find -maxdepth $recursive | );

I wanted to remove this dependency on system find. Is it possible with
File::Find?

I tried this after googling

http://www.perlmonks.org/?node_id=676958

sub wanted
{
if ( -d ) { # should I write this as -d $File::Find::name
  $File::Find::prune = 1;
  return;
}
print $File::Find::name . \n;
}


Re: File::Find NO RECURSION Howto

2010-03-01 Thread Shawn H Corey
raphael() wrote:
 Hi,
 
 How can I stop File::Find to go below current dir? i.e. no recursion.
 
 Although I can use glob or * to get file names in current dir.
 But I wanted to know if File::Find has a maxdepth limit like linux find.
 
 The script I created uses a switch which decides if recursion is allowed or
 not.
 It uses the system find like this..
 
 open(FIND, find -maxdepth $recursive | );
 
 I wanted to remove this dependency on system find. Is it possible with
 File::Find?
 
 I tried this after googling
 
 http://www.perlmonks.org/?node_id=676958
 
 sub wanted
 {
 if ( -d ) { # should I write this as -d $File::Find::name

# No, this is shorthand for:
if( -d $_ ){

   $File::Find::prune = 1;
   return;
 }
 print $File::Find::name . \n;
 }
 

And didn't it work?  The if statement works on all directories.  This
means that all directories except the top-level one will not be searched.


-- 
Just my 0.0002 million dollars worth,
  Shawn

Programming is as much about organization and communication
as it is about coding.

I like Perl; it's the only language where you can bless your
thingy.

Eliminate software piracy:  use only FLOSS.

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: File::Find NO RECURSION Howto

2010-03-01 Thread Shlomi Fish
On Monday 01 Mar 2010 13:23:16 raphael() wrote:
 Hi,
 
 How can I stop File::Find to go below current dir? i.e. no recursion.
 
 Although I can use glob or * to get file names in current dir.
 But I wanted to know if File::Find has a maxdepth limit like linux find.
 

Not, by itself, but there are wrappers around it that provides you with it. 
And there are several alternative modules like File-Find-Object or File-Next 
that solve some of its inherent philosophical limitations. For a summary see:

* http://www.shlomifish.org/open-source/projects/File-Find-Object/

* http://www.perlfoundation.org/perl5/index.cgi?alternatives_to_file_find

 The script I created uses a switch which decides if recursion is allowed or
 not.
 It uses the system find like this..
 
 open(FIND, find -maxdepth $recursive | );
 
 I wanted to remove this dependency on system find. Is it possible with
 File::Find?

It is possible.

 
 I tried this after googling
 
 http://www.perlmonks.org/?node_id=676958
 
 sub wanted
 {
 if ( -d ) { # should I write this as -d $File::Find::name
   $File::Find::prune = 1;
   return;
 }
 print $File::Find::name . \n;
 }

Well, this will only be equivalent to -maxdepth 1 not to larger values. I 
can't tell you offhand whether it's -d $_ or -d $File::Find::name because 
the File::Find interface is evil-incarnate and I'm trying to forget it. If you 
want to prune after an arbitrary maxdepth, you'll need to keep track of the 
current depth and the level there. May be File::Find gives you that but you 
really should be using File::Find::Object, File::Find::Rule or 
File::Find::Object::Rule .

Regards,

Shlomi Fish

-- 
-
Shlomi Fish   http://www.shlomifish.org/
What does Zionism mean? - http://shlom.in/def-zionism

Deletionists delete Wikipedia articles that they consider lame.
Chuck Norris deletes deletionists whom he considers lame.

Please reply to list if it's a mailing list post - http://shlom.in/reply .

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: File::Find NO RECURSION Howto

2010-03-01 Thread raphael()
On Mon, Mar 1, 2010 at 6:18 PM, Shawn H Corey shawnhco...@gmail.com wrote:

 raphael() wrote:
  Hi,
 
  How can I stop File::Find to go below current dir? i.e. no recursion.
 
  Although I can use glob or * to get file names in current dir.
  But I wanted to know if File::Find has a maxdepth limit like linux
 find.
 
  The script I created uses a switch which decides if recursion is allowed
 or
  not.
  It uses the system find like this..
 
  open(FIND, find -maxdepth $recursive | );
 
  I wanted to remove this dependency on system find. Is it possible with
  File::Find?
 
  I tried this after googling
 
  http://www.perlmonks.org/?node_id=676958
 
  sub wanted
  {
  if ( -d ) { # should I write this as -d $File::Find::name

 # No, this is shorthand for:
if( -d $_ ){

$File::Find::prune = 1;
return;
  }
  print $File::Find::name . \n;
  }
 

 And didn't it work?  The if statement works on all directories.  This
 means that all directories except the top-level one will not be searched.


 --
 Just my 0.0002 million dollars worth,
  Shawn

 Programming is as much about organization and communication
 as it is about coding.

 I like Perl; it's the only language where you can bless your
 thingy.

 Eliminate software piracy:  use only FLOSS.


Nope. It ddn't work. Any ideas?
I am thinking to use File::Find::Rule. But I didn't want any module
dependency for this script.

And Shlomi your message came in while I was typing this. Going to check the
modules you mentioned.
But it would have been great if I didn't has to use a module :( The people
around me no sh*t about installing perl
modules from CPAN.

Thanks all.

PS - Shlomi, your website is GOOD!


Re: File::Find NO RECURSION Howto

2010-03-01 Thread Shlomi Fish
On Monday 01 Mar 2010 15:00:26 raphael() wrote:
 On Mon, Mar 1, 2010 at 6:18 PM, Shawn H Corey shawnhco...@gmail.com wrote:
  raphael() wrote:
   Hi,
   
   How can I stop File::Find to go below current dir? i.e. no recursion.
   
   Although I can use glob or * to get file names in current dir.
   But I wanted to know if File::Find has a maxdepth limit like linux
  
  find.
  
   The script I created uses a switch which decides if recursion is
   allowed
  
  or
  
   not.
   It uses the system find like this..
   
   open(FIND, find -maxdepth $recursive | );
   
   I wanted to remove this dependency on system find. Is it possible with
   File::Find?
   
   I tried this after googling
   
   http://www.perlmonks.org/?node_id=676958
   
   sub wanted
   {
   
   if ( -d ) { # should I write this as -d $File::Find::name
  
  # No, this is shorthand for:
 if( -d $_ ){
 
 $File::Find::prune = 1;
 return;
   
   }
   print $File::Find::name . \n;
   
   }
  
  And didn't it work?  The if statement works on all directories.  This
  means that all directories except the top-level one will not be searched.
  
  
  --
  Just my 0.0002 million dollars worth,
  
   Shawn
  
  Programming is as much about organization and communication
  as it is about coding.
  
  I like Perl; it's the only language where you can bless your
  thingy.
  
  Eliminate software piracy:  use only FLOSS.
 
 Nope. It ddn't work. Any ideas?
 I am thinking to use File::Find::Rule. But I didn't want any module
 dependency for this script.

You can look at how File::Find::Rule does it and duplicate the logic.

 
 And Shlomi your message came in while I was typing this. Going to check the
 modules you mentioned.

Thanks.

 But it would have been great if I didn't has to use a module :( The people
 around me no sh*t about installing perl
 modules from CPAN.

Well, Matt S. Trout shared his sentiments about I cannot use CPAN here:

http://www.shadowcat.co.uk/blog/matt-s-trout/but-i-cant-use-cpan/

I've placed a link to it here:

http://perl-begin.org/topics/cpan/

 
 Thanks all.
 
 PS - Shlomi, your website is GOOD!

Thanks for the compliment! If possible, please share it with your friends and 
on social-bookmarking/social-networks/etc. sites that you belong to.

BTW, you shoulnd't highlight words using all-uppercase-letters. (It's 
considered akin to shouting). Instead use *...* , /.../ or _..._ .

Regards,

Shlomi Fish

-- 
-
Shlomi Fish   http://www.shlomifish.org/
Optimising Code for Speed - http://shlom.in/optimise

Deletionists delete Wikipedia articles that they consider lame.
Chuck Norris deletes deletionists whom he considers lame.

Please reply to list if it's a mailing list post - http://shlom.in/reply .

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: File::Find NO RECURSION Howto

2010-03-01 Thread Shawn H Corey
Shlomi Fish wrote:
 Well, Matt S. Trout shared his sentiments about I cannot use CPAN here:
 
 http://www.shadowcat.co.uk/blog/matt-s-trout/but-i-cant-use-cpan/
 

Well, Matt is wrong.  You can't always use CPAN.  Yes, you can set it up
so you can use it in development, but that doesn't mean you can do it in
production.  I have worked in places where the policy was no software
that's not approved by the sysadmins and approval of a single module may
take 6 to 18 months.  They're even very strict about downloading a copy
and cut  paste.  A foolish policy, kinda like, our horse will never get
sick from bad grain if we never feed it but managers _always_ know best.  ;)


-- 
Just my 0.0002 million dollars worth,
  Shawn

Programming is as much about organization and communication
as it is about coding.

I like Perl; it's the only language where you can bless your
thingy.

Eliminate software piracy:  use only FLOSS.

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Understanding recursion

2009-07-10 Thread Dermot
Hi,

I was reading Higher Order Perl[1] last night and, dishearteningly,
got stuck on chapter one.

Mark Dominus offers the following as a  binary string conversion
example of how recursion can work.


use strict;
use warnings;

my $bstr = binary(37);
print $bstr\n;                 # prints 100101

sub binary {
 my ($n) = @_;
 return $n if $n == 0 || $n == 1;
 my $k = int($n/2);
 my $b = $n % 2;
 my $E = binary($k);
 return $E . $b;
}


The algorithm works perfectly but my understanding of it's workings is amiss.

When I look at this I see $E initialised and then concatenate with the
the modulus of
37 % 2 =1
18 % 2 = 0
9 % 2 = 1
4 % 2 = 0
2 % 2 = 0

That by my reckoning is 10100. Almost the reverse of the answer but I
am obviously wrong and I can't see how the final expressions:

my $E = binary($k);
return $E . $b;

work to give the answer.

Can someone more enlightened than me give me some guidence.
Thanx,
Dp.


PS: Has anybody heard from Rob Dixon, he hasn't been on the list for ages.

1.  http://hop.perl.plover.com/book

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Understanding recursion

2009-07-10 Thread Shawn H. Corey
On Fri, 2009-07-10 at 09:26 +0100, Dermot wrote:
 The algorithm works perfectly but my understanding of it's workings is amiss.
 
 When I look at this I see $E initialised and then concatenate with the
 the modulus of
 37 % 2 =1
 18 % 2 = 0
 9 % 2 = 1
 4 % 2 = 0
 2 % 2 = 0
 
 That by my reckoning is 10100. Almost the reverse of the answer but I
 am obviously wrong and I can't see how the final expressions:
 
 my $E = binary($k);
 return $E . $b;
 
 work to give the answer.
 
 Can someone more enlightened than me give me some guidence.

Perhaps it would be easier to understand if we look at the counterpart
to this.

#!/usr/bin/perl

my $dstr = decimal( 123456789 );
print $dstr\n;

sub decimal {
 my ($n) = @_;
 return $n if $n  10;
 my $k = int($n/10);
 my $b = $n % 10;
 my $E = decimal($k);
 return $E . $b;
}
__END__

When dealing with the number 123456789, the first time through, stopping
just before the sub is called a second time, we have:

$b = 123456789 % 10 = 9;
$k = int( 123456789 / 10 ) = 12345678;

$E will be assigned the string that represents $k.  Clearly, this must
be concatenated before $b in the returned string.  The binary version
works the same way.


-- 
Just my 0.0002 million dollars worth,
  Shawn

Programming is as much about organization and communication
as it is about coding.



-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Understanding recursion

2009-07-10 Thread Dermot
2009/7/10 Shawn H. Corey shawnhco...@gmail.com:
 On Fri, 2009-07-10 at 09:26 +0100, Dermot wrote:
 The algorithm works perfectly but my understanding of it's workings is amiss.

 When I look at this I see $E initialised and then concatenate with the
 the modulus of
 37 % 2 =1
 18 % 2 = 0
 9 % 2 = 1
 4 % 2 = 0
 2 % 2 = 0

 That by my reckoning is 10100. Almost the reverse of the answer but I
 am obviously wrong and I can't see how the final expressions:

 my $E = binary($k);
 return $E . $b;

 work to give the answer.

 Can someone more enlightened than me give me some guidence.

 Perhaps it would be easier to understand if we look at the counterpart
 to this.

I appreciate what your saying but I can't say I find the counterpart
to be more helpful  so I am going to stick to the binary if it's all
the same.

 #!/usr/bin/perl

 my $dstr = decimal( 123456789 );
 print $dstr\n;

 sub decimal {
  my ($n) = @_;
  return $n if $n  10;
  my $k = int($n/10);
  my $b = $n % 10;
  my $E = decimal($k);
  return $E . $b;
 }
 __END__

 When dealing with the number 123456789, the first time through, stopping
 just before the sub is called a second time, we have:

 $b = 123456789 % 10 = 9;
 $k = int( 123456789 / 10 ) = 12345678;

 $E will be assigned the string that represents $k.

Why is $E getting assigned the value from $k? $E is initialised and
then assigned the return value of the binary(18) during the first
invocation (0). Does the subroutine continue and concatenate $b to $E
and then return (1) ? or does it wait until binary exhausts $n?

In my own groping/nonscientific sort of way, what I see emerging is a
pattern where my result (10100) is nearly the reverse of the correct
answer (100101) minus the leading 1. If that is correct I don't know
why the string is reversed,

Clearly, this must
 be concatenated before $b in the returned string.  The binary version
 works the same way.

Lost you a bit there because I can't see $k being concatenated to $E.
Dp.

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Understanding recursion

2009-07-10 Thread Shawn H. Corey
On Fri, 2009-07-10 at 13:42 +0100, Dermot wrote:
 Why is $E getting assigned the value from $k? 

my $E = binary($k);

I said $E will be assigned the string that represents $k, not it's
value.

 $E is initialised and
 then assigned the return value of the binary(18) during the first
 invocation (0). Does the subroutine continue and concatenate $b to $E
 and then return (1) ? or does it wait until binary exhausts $n?

It waits until: $n == 0 || $n == 1;

 
 In my own groping/nonscientific sort of way, what I see emerging is a
 pattern where my result (10100) is nearly the reverse of the correct
 answer (100101) minus the leading 1. If that is correct I don't know
 why the string is reversed,

Here's a breakdown of what's happening in binary(37).  Note that I'm
mixing arithmetic and string manipulations here.

37
= int(37/2)*2 + 37%2
= (18)*2 + 1
= ( int(18/2)*2 + 18%2 )*2 + 1
= ( (9)*2 + 0 ) + 1
= ( ( int(9/2)*2 + 9%2 )*2 + 0 )*2 + 1
= ( ( (4)*2 + 1 )*2 + 0 )*2 + 1
= ( ( ( int(4/2)*2 + 4%2 )*2 + 1 )*2 + 0 )*2 + 1
= ( ( ( (2)*2 + 0 )*2 + 1 )*2 + 0 )*2 + 1
= ( ( ( ( int(2/2)*2 + 2%2 )*2 + 0 )*2 + 1 )*2 + 0 )*2 + 1
= ( ( ( ( (1)*2 + 0 )*2 + 0 )*2 + 1 )*2 + 0 )*2 + 1
= ( ( ( ( 1 . 0 ) . 0 ) . 1 ) . 0 ) . 1
= ( ( ( ( 10 ) . 0 ) . 1 ) . 0 ) . 1
= ( ( ( 100 ) . 1 ) . 0 ) . 1
= ( ( 1001 ) . 0 ) . 1
= ( 10010 ) . 1
= 100101

In the first part:
$n = int($n/2)* + $n%2
but $k = int($n/2)
and $b = $n%2
so $n = int($n/2)*2 + $n%2 = $k*2 + $b

Addition is commutative, so this could be written as: $n = $b + $k*2
but string concatenation is not.  The return string must be $E, the
string representing $k; multiplied by 2 by concatenating 0 at it's
end; and then that 0 being replaced by $b.

In decimal, to multiply a number by 10, add an zero to it's end.  (It's
true.  Ask anyone on the streets.  When asked, How do you multiply a
number by ten? they'll reply, Stick a zero at its end.)

In binary, to multiply a number by two, stick an zero on its end.  If $e
is the string representing $k, to reconstruct $n, we have to first
multiply $E by 2:

my $return_string = $E . 0;

Now we have to add $b to this by replacing the last character in the
return string with $b:

$return_string = substr( $return_string, 0, -1 ) . $b;

It's just simpler to do it all in one step:

my $return_string = $E . $b;


-- 
Just my 0.0002 million dollars worth,
  Shawn

Programming is as much about organization and communication
as it is about coding.



-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Understanding recursion

2009-07-10 Thread Telemachus
On Fri Jul 10 2009 @  9:26, Dermot wrote:
 The algorithm works perfectly but my understanding of it's workings is amiss.
 
 When I look at this I see $E initialised and then concatenate with the
 the modulus of
 37 % 2 =1
 18 % 2 = 0
 9 % 2 = 1
 4 % 2 = 0
 2 % 2 = 0
 
 That by my reckoning is 10100. Almost the reverse of the answer but I
 am obviously wrong and I can't see how the final expressions:
 
 my $E = binary($k);
 return $E . $b;
 
 work to give the answer.

It helps for me to walk through it visually, indenting once each time the
script needs to call the binary sub-routine. Notice that it keeps going down
and inward, until it bottoms out on the base case. At that point, the answers
ripple back up to fit into the calls to binary($E) that were left hanging 
(because in those cases $E wasn't 1 or 0). Maybe this will help you as well.


Does 37 == 0 || 1? No; continue...
$k = 18; $b = 1; $E = binary(18) - go do that...
Does 18 == 0 || 1? No; continue...
$k = 9; $b = 0; $E = binary(9) - go do that...
Does 9 == 0 || 1? No; continue...
$k = 4; $b = 1; $E = binary(4) - go do that...
Does 4 == 0 || 1? No; continue...
$k = 2; $b = 0; $E = binary(2) - go do that...
Does 2 == 0 || 1? No; continue...
$k = 1; $b = 0; $E = binary(1) - go do that...
Does 1 == 0 || 1? Yes; return 1
$E = 1; return 1 . 0
$E = 10; return 10 . 0
$E = 100; return 100 . 1
$E = 1001; return 1001 . 0
$E = 10010; return 10010 . 1

Hope this helps, T

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Understanding recursion

2009-07-10 Thread Dermot
2009/7/10 Telemachus telemac...@arpinum.org:
 On Fri Jul 10 2009 @  9:26, Dermot wrote:
 The algorithm works perfectly but my understanding of it's workings is amiss.

 When I look at this I see $E initialised and then concatenate with the
 the modulus of

 It helps for me to walk through it visually, indenting once each time the
 script needs to call the binary sub-routine. Notice that it keeps going down
 and inward, until it bottoms out on the base case. At that point, the 
 answers
 ripple back up to fit into the calls to binary($E) that were left hanging
 (because in those cases $E wasn't 1 or 0). Maybe this will help you as well.


 Does 37 == 0 || 1? No; continue...
 $k = 18; $b = 1; $E = binary(18) - go do that...
    Does 18 == 0 || 1? No; continue...
    $k = 9; $b = 0; $E = binary(9) - go do that...
        Does 9 == 0 || 1? No; continue...
        $k = 4; $b = 1; $E = binary(4) - go do that...
            Does 4 == 0 || 1? No; continue...
            $k = 2; $b = 0; $E = binary(2) - go do that...
                Does 2 == 0 || 1? No; continue...
                $k = 1; $b = 0; $E = binary(1) - go do that...
                    Does 1 == 0 || 1? Yes; return 1
                $E = 1; return 1 . 0
            $E = 10; return 10 . 0
        $E = 100; return 100 . 1
    $E = 1001; return 1001 . 0
 $E = 10010; return 10010 . 1


Yes this does help. It makes a lot more sense when I get to view the
whole execution visually like this. So the final return statement (as
Shawn pointed out) isn't used until $n is either 0 or 1. In effect the
whole thing loops from:

my ($n) = @_;
return  return $n if $n == 0 || $n == 1;
 my $k = int($n/2);
 my $b = $n % 2;
 my $E = binary($k);

Then un-winds itself, returning in reverse order.

I want to thank you both for the time and energy you've put in.
There's been a lot of typing there and it's much appreciated.
Dp.

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Understanding recursion

2009-07-10 Thread Ken Slater

Dermot wrote:
Hi,

I was reading Higher Order Perl[1] last night and, dishearteningly,
got stuck on chapter one.

Mark Dominus offers the following as a  binary string conversion
example of how recursion can work.


use strict;
use warnings;

my $bstr = binary(37);
print $bstr\n; # prints 100101

sub binary {
  my ($n) = @_;
  return $n if $n == 0 || $n == 1;
  my $k = int($n/2);
  my $b = $n % 2;
  my $E = binary($k);
  return $E . $b;
}


The algorithm works perfectly but my understanding of it's workings is amiss.

When I look at this I see $E initialised and then concatenate with the
the modulus of
37 % 2 =1
18 % 2 = 0
9 % 2 = 1
4 % 2 = 0
2 % 2 = 0

That by my reckoning is 10100. Almost the reverse of the answer but I
am obviously wrong and I can't see how the final expressions:

my $E = binary($k);
return $E . $b;

work to give the answer.

Can someone more enlightened than me give me some guidence.
Thanx,
Dp.

Maybe this will make it easier to understand.

On each call 'binary' $b is set as follows (but does not start returning values 
until the 6th call):

1. $b = 1  (37 % 2)
2. $b = 0  (18 % 2)
3. $b = 1 (9 % 2)
4. $b = 0 (4 % 0)
5. $b = 0 (2 % 0)
6. returns 1 immediately

Now the stack starts unwinding and appending the $b value to the return value:

5. returns '10' (1 from 6th call and 0 from b value on 5th call).
4. returns '100'
3. returns '1001'
2. returns '10010'
1. returns '100101'

Ken


 
_
Windows Live™: Keep your life in sync. 
http://windowslive.com/explore?ocid=TXT_TAGLM_WL_BR_life_in_synch_062009

Randal's columns (was Re: HOWTO: File Renaming and Directory Recursion)

2004-04-02 Thread Randal L. Schwartz
 Morbus == Morbus Iff [EMAIL PROTECTED] writes:

Morbus The script was mindlessly simple, and I felt it would be a good HOWTO
Morbus for the perl beginners crowd, if not to show some good code practices,
Morbus but also to counteract the . .. .. . controversial HOWTO that had
Morbus been posted a week or so ago. Certainly, if you find this as misguided
Morbus as his, complain onlist with better examples, or offlist with anger.

Not necessarily a better example, but it's always worth a quick
google of site:stonehenge.com $YOUR_PERL_KEYWORDS HERE.  In this
case, using File::Find and rename, the first hit is:

 http://www.stonehenge.com/merlyn/LinuxMag/col45.html

which I wrote fairly recently and covers nearly identical ground.

Seriously, after 192 magazine articles, there's not *much* that isn't
illustrated in that archive of

http://www.stonehenge.com/merlyn/UnixReview/
http://www.stonehenge.com/merlyn/WebTechniques/
http://www.stonehenge.com/merlyn/LinuxMag/
http://www.stonehenge.com/merlyn/PerlJournal/

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
[EMAIL PROTECTED] URL:http://www.stonehenge.com/merlyn/
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




HOWTO: File Renaming and Directory Recursion

2004-04-01 Thread Morbus Iff

Earlier this morning, a friend of mine asked me for a script that would
given a list of files, replace underscores with spaces, to take this:

  Artist_Name-Track_Name.mp3

and rename it to this:

  Artist Name-Track Name.mp3

The script was mindlessly simple, and I felt it would be a good HOWTO
for the perl beginners crowd, if not to show some good code practices,
but also to counteract the . .. .. . controversial HOWTO that had
been posted a week or so ago. Certainly, if you find this as misguided
as his, complain onlist with better examples, or offlist with anger.

The first bit of code I wrote him was below. Save for
the additional explanatory comments, it's nearly exact.

 #!/usr/bin/perl

 # start all your scripts with these two lines.
 # they are the best teacher you will ever find for
 # writing perl code. they make you smarter, and
 # you'll last longer in bed; no drugs necessary.
 #
 use warnings;
 use strict;

 # he needed the script to read every file in a directory
 # and rename them based on whether they had underscores
 # in the name. to make the script as 'immediately runnable'
 # as possible, I assumed he would be placing the script
 # in the directory full of files, and running it there.
 # as such, we'll be opening the current working directory.
 # if anything goes wrong, we stop processing with the error.
 # ALWAYS CHECK FOR SUCCESS BEFORE CONTINUING.
 #
 opendir(DIR, .) or die $!;

 # next, we load all the files in that directory into
 # an array. at this point, we could also have used the
 # grep() function to filter out entries that weren't
 # relevant, but for readability I chose a more configurable
 # approach (see below).
 #
 my @files = readdir(DIR);
 close(DIR); # implicit.

 # now, we need to loop through all the directory files,
 # stored in @array. we're going to use $_ here, which
 # can be remembered as the thing we want to work with.
 # we could just as easily used an explicit variable name,
 # and in larger scripts, you usually want to.
 #
 while (@files) {

# so, the filename is now stored in $_, and since $_ is
# assumed for a number of Perl's functions, we don't
# have to explicitly mention it in the following filters.
# these filter serve one purpose: make sure we're working
# ONLY with files we should be. these are sanity checks:
# we're ensuring that we're not operating on anything we
# wouldn't. this is good practice: ALWAYS CHECK YOUR SANITY.
# rule out everything you don't want, and focus on everything
# you do. first, we skip directories with the -d check.
# the syntax I'm using below is far more readable than a bunch
# of if/else statements: we're not increasing our indents, and
# we don't have to worry about a zillion open/closing brackets.
# it also reads more like English.
#
next if -d;

# if we're still here, we've got a file. we'll automatically
# skip files that begin with a . as they're usually considered
# special, and renaming them can be a bad thing.
#
next if /^\./;

# and finally, if the file doesn't have any underscores in
# it, we can skip it immediately. again, this is for safety:
# the rest of our code could operate on the file and rename
# it with the same filename, but why waste that processing
# power? it's just dirty. it's how bad things happen.
#
next unless /_/;

# at this point, we're assuming that this is a file
# we're supposed to be working on. so, we copy the file
# name, do our underscore for space conversion, and
# issue a rename() from the original name to the new.
# again, if something goes wrong with the rename, we
# die immediately. this is probably overly cautious.
#
my $new_name = $_;
$new_name=~ s/_/ /g;
rename($_, $new_name) or die $!;
 }

And that's the script. For readability, no comments:

 #!/usr/bin/perl
 use warnings;
 use strict;

 opendir(DIR, .) or die $!;
 my @files = readdir(DIR);
 close(DIR);

 while (@files) {
next if -d;
next if /^\./;
next unless /_/;

my $new_name = $_;
$new_name=~ s/_/ /g;
rename($_, $new_name) or die $!;
 }

It worked fine for him, and we moved on. A few hours later, he
asked for a recursive version, and whether that would be hard
to do. While I wasn't around to help him out, the weak solution
was easy: just move the script into each new directory and run
it again. But, there are two other solutions to this new request:
the bad one, and the good one.

The bad one is to assume the first script is perfect: it's not.
It works if you're in the current directory, and the assumptions
are that no recursion is necessary. A bad approach to the recursive
problem is to start modifying the above script to manually support
it: people think hey, I got this working, recursion must be
simple as pie, right?!. Usually, they'll end up with something
like (pseudo non-working code follows):

 my DIRECTORIES = start_directory

Re: HOWTO: File Renaming and Directory Recursion

2004-04-01 Thread Paul Johnson
On Thu, Apr 01, 2004 at 07:05:51PM -0500, Morbus Iff wrote:

 Earlier this morning, a friend of mine asked me for a script that would
 given a list of files, replace underscores with spaces, to take this:
 
   Artist_Name-Track_Name.mp3
 
 and rename it to this:
 
   Artist Name-Track Name.mp3
 
 The script was mindlessly simple, and I felt it would be a good HOWTO
 for the perl beginners crowd, if not to show some good code practices,
 but also to counteract the . .. .. . controversial HOWTO that had
 been posted a week or so ago. Certainly, if you find this as misguided
 as his, complain onlist with better examples, or offlist with anger.
 
 The first bit of code I wrote him was below. Save for
 the additional explanatory comments, it's nearly exact.

[ snip ]

 And that's the script. For readability, no comments:
 
  #!/usr/bin/perl
  use warnings;
  use strict;
 
  opendir(DIR, .) or die $!;
  my @files = readdir(DIR);
  close(DIR);
 
  while (@files) {

Are you sure that's not:

   for (@files) {

?

 next if -d;
 next if /^\./;
 next unless /_/;
 
 my $new_name = $_;
 $new_name=~ s/_/ /g;
 rename($_, $new_name) or die $!;
  }
 
 It worked fine for him, and we moved on. A few hours later, he
 asked for a recursive version, and whether that would be hard
 to do. While I wasn't around to help him out, the weak solution
 was easy: just move the script into each new directory and run
 it again. But, there are two other solutions to this new request:
 the bad one, and the good one.

Here's a third:

  $ rename 'y/_/ /' **/*(.)

That's zsh globbing and rename that used to come with perl.  rename is
now part of debian, and google tells me it can be found at:

  http://www.hurontel.on.ca/~barryp/menu-mysql/music_rename-1.12c/rename

Though I'll admit that that solution doesn't provide so many
opportunities for learning Perl.

-- 
Paul Johnson - [EMAIL PROTECTED]
http://www.pjcj.net

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: HOWTO: File Renaming and Directory Recursion

2004-04-01 Thread Randy W. Sims
On 4/1/2004 7:05 PM, Morbus Iff wrote:

 # and here is that subroutine. it's nearly exactly
 # the same as our previous code, only this time, we
 # move into the directory that contains a file to
 # be renamed. this is actually a quick hack because
 # I knew this wouldn't be production-code: a more proper
 # solution would be to stay where we are in the directory
 # structure, and give full paths to our rename(). this
 # would require the help of another module, File::Spec.
 # find out more with perldoc File::Spec. it's handy.
 #
 sub underscores {
next if -d $_;
next if /^\./;
next unless /_/;
my $new_name = $_;
$new_name=~ s/_/ /g;
chdir($File::Find::dir);
rename($_, $new_name) or die $!;
 }
Nice work. Just two quick comments. 1) Above, the chdir is not neccesary 
because File::Find moves through the directory structure unless you 
specify no_chdir(?). 2) It might be instructive to follow up with one 
that handles the directory as a parameter; I agree it would have been 
distracting here, but as a follow-up it would be a good how-to for a 
common task (incl usage  pod also).

Again, this is a great example of a good How-To.

Regards,
Randy.


--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response



Re: HOWTO: File Renaming and Directory Recursion

2004-04-01 Thread Morbus Iff
  while (@files) {

Are you sure that's not:

   for (@files) {

Yup, for is right. An error in my memory recall.

-- 
Morbus Iff ( evil is my sour flavor )
Technical: http://www.oreillynet.com/pub/au/779
Culture: http://www.disobey.com/ and http://www.gamegrene.com/
icq: 2927491 / aim: akaMorbus / yahoo: morbus_iff / jabber.org: morbus

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Size of dir (with recursion)

2003-12-29 Thread Jesper Noehr
Hey list.

I'm having a problem reading the size of a directory with recursive 
directories.
The problem is that du -s shows a different bytecount than my program does.

Here's my code:

#!/usr/gnu/bin/perl -w
use File::Find;
@ARGV = ('.') unless @ARGV;
my $sum = 0;
find sub { $sum += -s }, @ARGV;
print @ARGV contains $sum bytes\n;
'du' shows a size of ~120 megabytes, while the program shows a size of 
something that's waaay larger.

Any idea why?

Jesper Nøhr - decius [EMAIL PROTECTED]
Holstebro, Denmark -- http://printf.dk
UNIX Administrator, Software Engineer, Geek.
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response



Re: Size of dir (with recursion)

2003-12-29 Thread John W. Krahn
Jesper Noehr wrote:
 
 Hey list.

Hello,

 I'm having a problem reading the size of a directory with recursive
 directories.
 The problem is that du -s shows a different bytecount than my program does.

$ man du

NAME
   du - estimate file space usage

SYNOPSIS
   du [OPTION]... [FILE]...

DESCRIPTION
   Summarize  disk usage of each FILE, recursively for direc­
   tories.


 Here's my code:
 
 #!/usr/gnu/bin/perl -w
 use File::Find;
 @ARGV = ('.') unless @ARGV;
 my $sum = 0;
 find sub { $sum += -s }, @ARGV;
 print @ARGV contains $sum bytes\n;
 
 'du' shows a size of ~120 megabytes, while the program shows a size of
 something that's waaay larger.
 
 Any idea why?

du looks at disk space usage while your program looks at file sizes.  If
your disk has a block size of 1024 and you have a file that is 10 bytes
in size, du will report the amount of space based on the blocks required
to store the file, not on the actual size of the file.

$ ls -l test.txt
-rw-r--r--1 john users 187 Jul  9 11:54 test.txt
$ perl -le'print +(lstat shift)[11]' test.txt
4096
$ du -b test.txt
4096test.txt
$ du test.txt
4   test.txt



John
-- 
use Perl;
program
fulfillment

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Size of dir (with recursion)

2003-12-29 Thread Jesper Noehr
On Mon, 29 Dec 2003 13:19:29 -0800, John W. Krahn [EMAIL PROTECTED] wrote:

Jesper Noehr wrote:
Hey list.
Hello,

I'm having a problem reading the size of a directory with recursive
directories.
The problem is that du -s shows a different bytecount than my program 
does.
$ man du

NAME
   du - estimate file space usage
SYNOPSIS
   du [OPTION]... [FILE]...
DESCRIPTION
   Summarize  disk usage of each FILE, recursively for direc­
   tories.

Here's my code:

#!/usr/gnu/bin/perl -w
use File::Find;
@ARGV = ('.') unless @ARGV;
my $sum = 0;
find sub { $sum += -s }, @ARGV;
print @ARGV contains $sum bytes\n;
'du' shows a size of ~120 megabytes, while the program shows a size of
something that's waaay larger.
Any idea why?
du looks at disk space usage while your program looks at file sizes.  If
your disk has a block size of 1024 and you have a file that is 10 bytes
in size, du will report the amount of space based on the blocks required
to store the file, not on the actual size of the file.
Hmm, I see.
$ ls -l test.txt
-rw-r--r--1 john users 187 Jul  9 11:54 test.txt
$ perl -le'print +(lstat shift)[11]' test.txt
4096
$ du -b test.txt
4096test.txt
$ du test.txt
4   test.txt
Great example, thanks. You have any idea how I can rehack my program to 
return what du does? That is, diskspaceusage.


John


--
Jesper Nøhr - decius [EMAIL PROTECTED]
Holstebro, Denmark -- http://printf.dk
UNIX Administrator, Software Engineer, Geek.
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response



Re: Size of dir (with recursion)

2003-12-29 Thread John W. Krahn
Jesper Noehr wrote:
 
 On Mon, 29 Dec 2003 13:19:29 -0800, John W. Krahn [EMAIL PROTECTED] wrote:
 
  $ ls -l test.txt
  -rw-r--r--1 john users 187 Jul  9 11:54 test.txt
  $ perl -le'print +(lstat shift)[11]' test.txt
  4096
  $ du -b test.txt
  4096test.txt
  $ du test.txt
  4   test.txt
 Great example, thanks. You have any idea how I can rehack my program to
 return what du does? That is, diskspaceusage.

As you can see from the perl script above, the twelfth field of stat and
lstat is the block size.

$ ls -l file.txt
-rw-r--r--1 john users   22982 Nov 13 23:28 file.txt
$ du -b file.txt
24576   file.txt
$ perl -le'$x = shift;
   $b = (lstat $x)[11];
   $s = -s _;
   print $s  , $s + ( $b - ( $s % $b ) );
   ' file.txt 
22982  24576



John
-- 
use Perl;
program
fulfillment

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Size of dir (with recursion)

2003-12-29 Thread Shawn
While you're at it, write a parallel version of du.pl... Modern hard
drives do scatter gather, and reading lots (say 10 or so) of dirs'
contents' block sizes at a time would be interesting...

It would be cool if a parent kept 20 children pre-forked, and only told
10 children at a time to do their work load. The children upon fork
would wait for some IPC from the parent, then do their work, then
communicate the answer back to the parent, and die. I don't know if
pre-forking is necessary to keep 10 children active, but it's something
to make the task harder, and make you learn more!

If you wanna learn perl, aim at over-engineered spaghetti. Give yourself
a task fit for a mentally insane perl monk, and then you can say you've
been to hell and back. Then repeat...

On Mon, 2003-12-29 at 15:51, John W. Krahn wrote:
 Jesper Noehr wrote:
  
  On Mon, 29 Dec 2003 13:19:29 -0800, John W. Krahn [EMAIL PROTECTED] wrote:
  
   $ ls -l test.txt
   -rw-r--r--1 john users 187 Jul  9 11:54 test.txt
   $ perl -le'print +(lstat shift)[11]' test.txt
   4096
   $ du -b test.txt
   4096test.txt
   $ du test.txt
   4   test.txt
  Great example, thanks. You have any idea how I can rehack my program to
  return what du does? That is, diskspaceusage.
 
 As you can see from the perl script above, the twelfth field of stat and
 lstat is the block size.
 
 $ ls -l file.txt
 -rw-r--r--1 john users   22982 Nov 13 23:28 file.txt
 $ du -b file.txt
 24576   file.txt
 $ perl -le'$x = shift;
$b = (lstat $x)[11];
$s = -s _;
print $s  , $s + ( $b - ( $s % $b ) );
' file.txt 
 22982  24576
 
 
 
 John
 -- 
 use Perl;
 program
 fulfillment

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Recursion

2003-11-03 Thread Rob Dixon
James Edward Gray II wrote:

 On Sunday, November 2, 2003, at 06:19 AM, Rob Dixon wrote:

  Jeff Westman
  wrotenews:[EMAIL PROTECTED]
  Hi,
 
  I've never liked recursion but of course there are times where it is
  needed.

 I'm not sure I would say recursion is needed, but it sure makes some
 things simpler.  I've never met a recursive function I couldn't rewrite
 iteratively though, often with some pain, of course.

Recursion can always be eliminated by hard-coding the stacking of
context variables that the compiler provides and using a loop
instead of a recursive call. In fact this is exactly what File::Find
itself does. But recursive code will almost always allow a better
expression of an algorithm than the hammer and nails technique.

Cheers,

Rob



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Recursion

2003-11-03 Thread Rob Dixon
Steve Grazzini wrote:

 On Sun, Nov 02, 2003 at 05:32:35PM -0600, James Edward Gray II wrote:
  On Sunday, November 2, 2003, at 06:19 AM, Rob Dixon wrote:
sub printdir {
  
  my $dir = shift;
  
  opendir DIR, $dir or die $!;
  my @dirs = grep /[^.]/, readdir DIR;
 
  I'm not sure this grep() is what you meant it to be.  It selects any
  file containing a non-dot character, as written.

 Right.  The files to skip are . (this directory) and .. (the
 parent directory).  Rob's solution also skips ..., though, so it's
 not perfect.

  I probably would have preferred grep /^[^.]/, ..., which get all
  files starting with a non-dot character.  I believe that's a little
  more typical UNIX behavior.

 That's fine if you *want* to skip the dotfiles.  But you *always*
 skip . and ...  More robust code will also check for cycles, but
 since File::Find does all this already, it's usually better just to
 use the module.

Hi Steve.

Cycles are eliminated by discarding links and printing only directories
and regular files.

/R



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Recursion

2003-11-03 Thread Rob Dixon
R. Joseph Newton wrote:

 Rob Dixon wrote:

  Jeff Westman wrotenews:[EMAIL PROTECTED]
  
   I've never liked recursion but of course there are times where it is
   needed.
  
   I have a simple task that I am trying to do.  Basically, I just want to list
   out my directories on disk, and then chdir to each one, print it out, and so
   on.  Pretty basic, but I have a total mental block using recursion.
  
   Any quick help or tips would be appreciated.
 
  File::Find would do it for you, but the recursion is very
  simple really:

 HI Rob,

 This is great, but could use just a bit of textual explanation:

 
 
use strict;
use warnings;
 
printdir('/usr');
 
sub printdir {
 
  my $dir = shift;
 
  opendir DIR, $dir or die $!;
  my @dirs = grep /[^.]/, readdir DIR;
  closedir DIR;
 
  foreach (map $dir/$_, @dirs) {
if (-d) {   #  recursive case
  printdir($_);
}
elsif (-f _) {
  print $_, \n; #stopping case
}
  }
}
 
  HTH,
 
  Rob

 Doesn't take much.  Recursion is, as you say, fairly simple in its essence.  I
 just thought that it would be good to explicitly point out the need for a stopping
 case to prevent infinite recursion.

I'm not sure the idea of a 'stopping case' is relevant here. That is more
useful when recursion is used to evaluate one function in terms of another
simpler one, as in the classic

  sub factorial {
my $x = shift;
$x  1 ? $x * factorial($x - 1) : 1;
  }

when there must be a case where the function is no longer reduceable
and has a value defined non-recursively. Scanning directory
recursively works because the data structure is recursive, and cannot
fail to terminate as long as there are no loops in the data (which is
true here since the code ignores symbolic links).

Cheers,

Rob



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Recursion

2003-11-03 Thread James Edward Gray II
On Monday, November 3, 2003, at 03:43 AM, Rob Dixon wrote:

Recursion can always be eliminated by hard-coding the stacking of
context variables that the compiler provides and using a loop
instead of a recursive call. In fact this is exactly what File::Find
itself does. But recursive code will almost always allow a better
expression of an algorithm than the hammer and nails technique.
For some definition of better meaning easier to understand, but 
certainly not faster, right?  ;)

I agree with Rob that recursion is usually prettier.  It has very real 
limits though, that iteration can often extend greatly.  Also, if 
you're ever looking for more speed, start with unrolling recursions, 
trust me.

James

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Re: Recursion

2003-11-03 Thread Steve Grazzini
On Mon, Nov 03, 2003 at 09:48:55AM -, Rob Dixon wrote:
 Steve Grazzini wrote:
  That's fine if you *want* to skip the dotfiles.  But you *always*
  skip . and ...  More robust code will also check for cycles, but
  since File::Find does all this already, it's usually better just to
  use the module.
 
 Cycles are eliminated by discarding links and printing only directories
 and regular files.

The problem is that -d $path will return true if $path is a symlink
to a directory.

-- 
Steve

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Recursion

2003-11-03 Thread Rob Dixon
Steve Grazzini wrote:

 On Mon, Nov 03, 2003 at 09:48:55AM -, Rob Dixon wrote:
  Steve Grazzini wrote:
   That's fine if you *want* to skip the dotfiles.  But you *always*
   skip . and ...  More robust code will also check for cycles, but
   since File::Find does all this already, it's usually better just to
   use the module.
 
  Cycles are eliminated by discarding links and printing only directories
  and regular files.

 The problem is that -d $path will return true if $path is a symlink
 to a directory.

Thanks Steve, but are you certain? I can't test it here. As far
as I know this behaviour isn't documented anywhere.

Anybody?

Rob



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Recursion

2003-11-03 Thread Paul Johnson
On Mon, Nov 03, 2003 at 11:16:02PM -, Rob Dixon wrote:
 Steve Grazzini wrote:
 
  On Mon, Nov 03, 2003 at 09:48:55AM -, Rob Dixon wrote:
   Steve Grazzini wrote:
That's fine if you *want* to skip the dotfiles.  But you *always*
skip . and ...  More robust code will also check for cycles, but
since File::Find does all this already, it's usually better just to
use the module.
  
   Cycles are eliminated by discarding links and printing only directories
   and regular files.
 
  The problem is that -d $path will return true if $path is a symlink
  to a directory.
 
 Thanks Steve, but are you certain? I can't test it here. As far
 as I know this behaviour isn't documented anywhere.
 
 Anybody?

Steve is right (just for a change).  I don't know that this is
documented anywhere specifically.  Possibly the closest is in perldoc -f
stat (at the end on recent perls) and man 2 stat (on systems that have
that).

-- 
Paul Johnson - [EMAIL PROTECTED]
http://www.pjcj.net

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Recursion

2003-11-03 Thread Steve Grazzini
On Tue, Nov 04, 2003 at 12:45:58AM +0100, Paul Johnson wrote:
 On Mon, Nov 03, 2003 at 11:16:02PM -, Rob Dixon wrote:
 Steve Grazzini wrote:
 The problem is that -d $path will return true if $path is a symlink
 to a directory.
 
 Thanks Steve, but are you certain? I can't test it here. As far
 as I know this behaviour isn't documented anywhere.

 Steve is right (just for a change).

Yeah, I try to mix a few good answers in with the nonsense...

 I don't know that this is documented anywhere specifically.  Possibly
 the closest is in perldoc -f stat (at the end on recent perls) and man
 2 stat (on systems that have that).

It's one of those things that you can't find until you already know
about it.  The idea is that (given a UNIX-centric view of the world) 
absolutely everything follows symlinks, and only exceptions to this
rule need to be documented.

  % perldoc -f -X
 ... (This doesn't work with -t, and you need to remember
  that lstat() and -l will leave values in the stat structure for 
  the symbolic link, not the real file.)

  % perldoc -f lstat

   lstat FILEHANDLE
   lstat EXPR
   lstat   Does the same thing as the stat function
   (including setting the special _ filehandle) but
   stats a symbolic link instead of the file the
   symbolic link points to.

There's also some good stuff in the description of the follow options
for (cough!) File::Find.

-- 
Steve

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Recursion

2003-11-02 Thread Rob Dixon
Jeff Westman wrotenews:[EMAIL PROTECTED]
 Hi,

 I've never liked recursion but of course there are times where it is
 needed.

 I have a simple task that I am trying to do.  Basically, I just want to list
 out my directories on disk, and then chdir to each one, print it out, and so
 on.  Pretty basic, but I have a total mental block using recursion.

 Any quick help or tips would be appreciated.

Hi Jeff.

File::Find would do it for you, but the revursion is very
simple really:

  use strict;
  use warnings;

  printdir('/usr');

  sub printdir {

my $dir = shift;

opendir DIR, $dir or die $!;
my @dirs = grep /[^.]/, readdir DIR;
closedir DIR;

foreach (map $dir/$_, @dirs) {
  if (-d) {
printdir($_);
  }
  elsif (-f _) {
print $_, \n;
  }
}
  }

HTH,

Rob




-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Recursion

2003-11-02 Thread R. Joseph Newton
Rob Dixon wrote:

 Jeff Westman wrotenews:[EMAIL PROTECTED]
  Hi,
 
  I've never liked recursion but of course there are times where it is
  needed.
 
  I have a simple task that I am trying to do.  Basically, I just want to list
  out my directories on disk, and then chdir to each one, print it out, and so
  on.  Pretty basic, but I have a total mental block using recursion.
 
  Any quick help or tips would be appreciated.

 Hi Jeff.

 File::Find would do it for you, but the revursion is very
 simple really:

HI Rob,

This is great, but could use just a bit of textual explanation:



   use strict;
   use warnings;

   printdir('/usr');

   sub printdir {

 my $dir = shift;

 opendir DIR, $dir or die $!;
 my @dirs = grep /[^.]/, readdir DIR;
 closedir DIR;

 foreach (map $dir/$_, @dirs) {
   if (-d) {   #  recursive case
 printdir($_);
   }
   elsif (-f _) {
 print $_, \n; #stopping case
   }
 }
   }

 HTH,

 Rob

Doesn't take much.  Recursion is, as you say, fairly simple in its essence.  I
just thought that it would be good to explicitly point out the need for a stopping
case to prevent infinite recursion.

Joseph


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Recursion

2003-11-02 Thread James Edward Gray II
On Sunday, November 2, 2003, at 06:19 AM, Rob Dixon wrote:

File::Find would do it for you, but the revursion is very
simple really:
  use strict;
  use warnings;
  printdir('/usr');

  sub printdir {

my $dir = shift;

opendir DIR, $dir or die $!;
my @dirs = grep /[^.]/, readdir DIR;
I'm not sure this grep() is what you meant it to be.  It selects any 
file containing a non-dot character, as written.

I probably would have preferred grep /^[^.]/, ..., which get all files 
starting with a non-dot character.  I believe that's a little more 
typical UNIX behavior.

James

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Re: Recursion

2003-11-02 Thread James Edward Gray II
On Sunday, November 2, 2003, at 06:19 AM, Rob Dixon wrote:

Jeff Westman 
wrotenews:[EMAIL PROTECTED]
Hi,

I've never liked recursion but of course there are times where it is
needed.
I'm not sure I would say recursion is needed, but it sure makes some 
things simpler.  I've never met a recursive function I couldn't rewrite 
iteratively though, often with some pain, of course.

Hi Jeff.

File::Find would do it for you, but the revursion is very
simple really:
  use strict;
  use warnings;
  printdir('/usr');

  sub printdir {

my $dir = shift;

opendir DIR, $dir or die $!;
my @dirs = grep /[^.]/, readdir DIR;
closedir DIR;
foreach (map $dir/$_, @dirs) {
  if (-d) {
printdir($_);
  }
  elsif (-f _) {
print $_, \n;
  }
}
  }
# or iteratively...

sub printdir {
my @dirs = (shift);

while (@dirs) {
my $dir = shift @dirs;
opendir DIR, $dir or die Directory error:  $!;
my @new_dirs = grep /^[^.]/, readdir DIR;
closedir DIR;

foreach (map $dir/$_,@new_dirs) {
if (-d) { push @dirs, $_; }
elsif (-f _) { print $_\n; }
}
}
}
James

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Re: Recursion

2003-11-02 Thread Steve Grazzini
On Sun, Nov 02, 2003 at 05:32:35PM -0600, James Edward Gray II wrote:
 On Sunday, November 2, 2003, at 06:19 AM, Rob Dixon wrote:
   sub printdir {
 
 my $dir = shift;
 
 opendir DIR, $dir or die $!;
 my @dirs = grep /[^.]/, readdir DIR;
 
 I'm not sure this grep() is what you meant it to be.  It selects any 
 file containing a non-dot character, as written.

Right.  The files to skip are . (this directory) and .. (the
parent directory).  Rob's solution also skips ..., though, so it's
not perfect.

 I probably would have preferred grep /^[^.]/, ..., which get all
 files starting with a non-dot character.  I believe that's a little
 more typical UNIX behavior.

That's fine if you *want* to skip the dotfiles.  But you *always* 
skip . and ...  More robust code will also check for cycles, but
since File::Find does all this already, it's usually better just to
use the module.

-- 
Steve

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Recursion

2003-11-01 Thread Jeff Westman
Hi,

I've never liked recursion but of course there are times where it is
needed.

I have a simple task that I am trying to do.  Basically, I just want to list
out my directories on disk, and then chdir to each one, print it out, and so
on.  Pretty basic, but I have a total mental block using recursion.

Any quick help or tips would be appreciated.

Thanks in advance,

Jeff


__
Do you Yahoo!?
Exclusive Video Premiere - Britney Spears
http://launch.yahoo.com/promos/britneyspears/

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Recursion

2003-11-01 Thread Steve Grazzini
On Sat, Nov 01, 2003 at 05:20:39PM -0800, Jeff Westman wrote:
 I have a simple task that I am trying to do.  Basically, I just want 
 to list out my directories on disk, and then chdir to each one, print
 it out, and so on.

use File::Find;
find sub { print $File::Find::name\n if -d }, '/';

-- 
Steve

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Recursion

2003-11-01 Thread Kevin Old
On Sat, 2003-11-01 at 20:20, Jeff Westman wrote:
 Hi,
 
 I've never liked recursion but of course there are times where it is
 needed.
 
 I have a simple task that I am trying to do.  Basically, I just want to list
 out my directories on disk, and then chdir to each one, print it out, and so
 on.  Pretty basic, but I have a total mental block using recursion.
 
 Any quick help or tips would be appreciated.
 
 Thanks in advance,
 
 Jeff
 
 
 __
 Do you Yahoo!?
 Exclusive Video Premiere - Britney Spears
 http://launch.yahoo.com/promos/britneyspears/

I'm rusty on recursion too, but here are some resources that explain it

on Perlmonks.com
http://www.perlmonks.com/index.pl?node_id=101801
http://www.perlmonks.com/index.pl?node_id=41634

Also, if you're parsing directories and files, Randal has two awesome
columns on this very subject
http://www.stonehenge.com/merlyn/LinuxMag/col45.html
http://www.stonehenge.com/merlyn/LinuxMag/col46.html

Hope this helps,
Kevin
-- 
Kevin Old [EMAIL PROTECTED]


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



recursion and memory use... a lot of memory use.

2001-06-01 Thread Peter Cornelius

I have this program that recurses through a directory structure building
Default.htm files.  The idea here was to quickly generate a bunch of these
things to replace the default index listing you normally see.  The part
that's giving me trouble is the navbar that should have a nested structure
like...

Food
   Fruit
 Apples
 Oranges
 Kiwi
   Vegetables
   Coffee
Critters
Cars
Rocks

So that if you are in /DocRoot/Food/Fruit you would see the above on the
left all properly linked yada yada.  The code I've pasted in does this just
fine (I've removed a bunch of stuff to focus on the real problem) but only
on small directory structures.  When I run it on something with 10 directory
levels, 3 or 4 subdirectories in each one, 20-30 files in each one, it zips
along for a few seconds then grinds to a halt, consumes all my physical
memory and begins swapping like mad.  

I changed things around to not use the joinLists() function and to have
buildIndices() call itself rather than have getLinks call it and it works
fine.  But I don't know why, hence the posting.  Anyone feel like tackling
this?

Thanks!

Peter C.

--
#! perl

use strict;
use warnings;
use File::Copy;
use vars ('$rootDir');

#===

# Main
#===

my $baseURL = engweb;
$rootDir = d:/inetpub/wwwroot/$baseURL;

buildIndices($rootDir, /$baseURL) or
die (failed trying to build $rootDir\n);

exit 0;

#===

# Functions
#===


#---

# buildIndices($dir, $parentLinks)
#
# This function takes a document directory and builds the
# Default.htm file for it.
#
sub buildIndices {
my ($dir, $url, $parentLinks) = @_; #$parentLinks is an array ref.
my $cwd = (split /\\|\//, $dir)[-1];

print currently working on $dir\n;

local $ = \n;  #Set the list seperator to a new line.

#All we want is 2 things, a directory and an html file.
#Is that too much to ask for?
copy ($rootDir\\Default.htm, $dir\\Default.htm)
unless -T $dir\\Default.htm;

unless (-d $dir and -T $dir\\Default.htm) {
print $dir is not a directory\n unless -d $dir;
print We couldn't put the Default.htm file in $dir\n
unless -T $dir\\Default.htm;
return 0;
}

my @curLinks = getLinks($dir, $url, $parentLinks);
#links should have a bunch of 'a href...' strings

#if we were given a parentLinks array splice these two together.
# if there were no subdirectories or files splice in an anonymous
# array that Just says EMPTY
my @links = ($parentLinks and $cwd) ?
joinLists (@curLinks ? \@curLinks :
[DIV STYLE=\margin:10\,
Empty, /DIV],
$parentLinks, $cwd) :
@curLinks;

#there's just an inplace edit here...
#
#...

return 1; #one is good
}

#---

# getLinks($dir)
#
# loop through the directory entries and build a bunch of 'a href...'
# strings and stuff them in an array.  If the entry is a directory call
# buildIndices($ent) on it.
#
sub getLinks {
my ($dir, $url, $parentLinks) = @_;
my @subDirs;
my @links = ();
my $link;
my $ent; #a thing for iterating over directory entries
my $cwd = (split /\\|\//, $dir)[-1];

opendir (DH, $dir) or
logItAndDie(Can't open the directory $rootDir,
status=$!\n);


while (defined ($ent = readdir(DH))) {
next if $ent =~ /^\./;  #skip things with leading '.'

if (-d $dir/$ent) {
#Add some spaces.
push @links, a
href=\$url/$ent/Default.htm\$ent/abr;
push @subDirs, $dir/$ent; #to be used in calls to
buildIndices
} elsif ($ent  =~ /\.(htm|html|jsp|doc)$/) {
if (!($ent =~ /Default/)) { # Skip the
Default files
push @links, a
href=\$url/$ent\$ent/abr;
}
}
}
closedir(DH);

if (@links) {
unshift @links, DIV STYLE=\margin:10\;
push @links, /DIV;
}

my @completeLinks = ($cwd and $parentLinks) ?
joinLists (\@links, $parentLinks, $cwd) :
@links;

for (@subDirs) {
buildIndices($_, $url/ . (split /\\|\//)[-1],