Home > Archive > PERL Beginners > November 2006 > problem with calling subprogram in a nested for-loop
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
problem with calling subprogram in a nested for-loop
|
|
| guba@vi-anec.de 2006-10-31, 7:56 am |
| Hello,
I want to call a subprogram PMM_TILE.PLX (see below) with do '...'
multiple times in a nested for-loop from a program Batch_TILE.PLX.
The outer loop works but the inner loop runs only one time
with $p = 1 (only one image for every jpg in the $sourcefolder_path
is generated instead of $pmm_number images).
Did someone see the reason why the inner loop is aborted
after $p =1 and how can this be corrected?
Thank you very much!!
Guenter
*Batch_TILE.PLX*********************************
#Input
$pmm_number = '10';
$sourcefolder_path = 'C:/ART/IM_PlaneCovering/1_Sourceimages/';
$pmm_resultfolder_path =
'C:/ART/IM_PlaneCovering/2_Tiles/2_01_pmm-Tiles/';
#program
opendir(DIR, "$sourcefolder_path") || die "no such folder: $!";
@sourcefolder_list = grep(/\.jpg$/, readdir(DIR));
$sourcefolder_number = @sourcefolder_list;
for ($k = 0; $k <= $sourcefolder_number; $k +=1) {
$sourcefile_name = $sourcefolder_list[$k];
for ($p = 1; $p <= $pmm_number; $p +=1) {do 'PMM_TILE.PLX'};
};
*PMM_TILE.PLX*********************************
use Image::Magick;
# 0)Input
# 0.1) counting variable, folders, file
# 0.2) definition of lokal parameters
$rectangle_width_min_Faktor = 0.4;
$rectangle_width_max_Faktor = 0.6;
$rectangle_height_min_Faktor = 0.4;
$rectangle_height_max_Faktor = 0.6;
# 1) definition of PerlMagick objects
$pmm_G = new Image::Magick;
# 2) inilisation of random number generator
srand;
# 3) read source image
$sourcefile_fullname = $sourcefolder_path . $sourcefile_name;
$pmm_G->Read("$sourcefile_fullname");
# 4) local variable calculations: $rectangle_width, $rectangle_height,
$x1, $y1
$image_width = $pmm_G->Get('columns');
$image_height = $pmm_G->Get('rows');
if ($image_width < $image_height) {$image_min = $image_width} else
{$image_min = $image_height};
$rectangle_width_min = $rectangle_width_min_Faktor * $image_min;
$rectangle_width_max = $rectangle_width_max_Faktor * $image_min;
$rectangle_height_min = $rectangle_height_min_Faktor * $image_min;
$rectangle_height_max = $rectangle_height_max_Faktor * $image_min;
$rectangle_width = $rectangle_width_min +
(int(rand($rectangle_width_max - $rectangle_width_min)) + 1);
$rectangle_height = $rectangle_height_min +
(int(rand($rectangle_height_max - $rectangle_height_min)) + 1);
$x_allowed = $image_width - $rectangle_width;
$y_allowed = $image_height - $rectangle_height;
$x1 = int(rand($x_allowed))+1;
$y1 = int(rand($y_allowed))+1;
# 5) generate pmm_G by cropping the source image
$pmm_G->Crop(geometry => "$rectangle_width x
$rectangle_hight+$x1+$y1");
# 6) convert pmm_G.png -flop pmm_G_flop.png
$pmm_G_flop = $pmm_G->Clone();
$pmm_G_flop->Flop();
# 7) convert pmm_G.png pmm_G_flop.png +append pmm_tile_row.png
$q = $pmm_G->Clone();
push(@$q, $pmm_G_flop);
$pmm_tile_row = $q->Append(stack=>'false');
# 8) convert pmm_tile_row.png -flip pmm_tile_row_flip.png
$pmm_tile_row_flip = $pmm_tile_row->Clone();
$pmm_tile_row_flip->Flip();
# 9) convert pmm_tile_row.png pmm_tile_row_flip.png -append
pmm_tile.png
@$q = ();
$q = $pmm_tile_row->Clone();
push(@$q, $pmm_tile_row_flip);
$pmm_tile = $q->Append(stack=>'true');
# 10) generate name of the result image
chop $sourcefile_name;
chop $sourcefile_name;
chop $sourcefile_name;
chop $sourcefile_name;
if ($p <= 9) {$resultimage_name = "pmm_tile_" . $sourcefile_name . "-0"
.. $p . ".jpg"}
else {$resultimage_name = "pmm_tile_" . $sourcefile_name . "-"
.. $p . ".jpg"};
$resultimagepath_name = $pmm_resultfolder_path . $resultimage_name;
# 11) save result image (pmm_tile)
$pmm_tile->Write(filename=>"$resultimagepath_name",
compression=>'JPEG', quality=>'95');
| |
|
|
guba@vi-anec.de wrote:
> Hello,
>
> I want to call a subprogram PMM_TILE.PLX (see below) with do '...'
> multiple times in a nested for-loop from a program Batch_TILE.PLX.
> The outer loop works but the inner loop runs only one time
> with $p = 1 (only one image for every jpg in the $sourcefolder_path
> is generated instead of $pmm_number images).
>
> Did someone see the reason why the inner loop is aborted
> after $p =1 and how can this be corrected?
>
> Thank you very much!!
>
> Guenter
>
>
>
> *Batch_TILE.PLX*********************************
> #Input
Always start your script with the following two lines:
use strict;
use warnings;
Declare variables with 'my' when you first use them.
> $pmm_number = '10';
I haven't tried running this, but this line is a problem in that you
are assigning a string to $ppm_number, but using it as a number later.
my $ppm_number = 10;
> $sourcefolder_path = 'C:/ART/IM_PlaneCovering/1_Sourceimages/';
> $pmm_resultfolder_path =
> 'C:/ART/IM_PlaneCovering/2_Tiles/2_01_pmm-Tiles/';
>
>
> #program
> opendir(DIR, "$sourcefolder_path") || die "no such folder: $!";
> @sourcefolder_list = grep(/\.jpg$/, readdir(DIR));
> $sourcefolder_number = @sourcefolder_list;
>
> for ($k = 0; $k <= $sourcefolder_number; $k +=1) {
>
> $sourcefile_name = $sourcefolder_list[$k];
>
It looks like you've been programming in C (nothing wrong with that),
but you don't really need $sourcefolder_number and the for loop:
foreach my $sourcefile_name (@sourcefolder_list) {
> for ($p = 1; $p <= $pmm_number; $p +=1) {do 'PMM_TILE.PLX'};
>
> };
$p += 1 could be $p++
Could also use a range for the for loop:
for (1..$pmm_number){do 'PMM_TILE.PLX'};
>
>
> *PMM_TILE.PLX*********************************
> use Image::Magick;
>
>
> # 0)Input
> # 0.1) counting variable, folders, file
>
> # 0.2) definition of lokal parameters
> $rectangle_width_min_Faktor = 0.4;
> $rectangle_width_max_Faktor = 0.6;
> $rectangle_height_min_Faktor = 0.4;
> $rectangle_height_max_Faktor = 0.6;
>
>
>
>
> # 1) definition of PerlMagick objects
> $pmm_G = new Image::Magick;
>
>
> # 2) inilisation of random number generator
> srand;
>
>
> # 3) read source image
> $sourcefile_fullname = $sourcefolder_path . $sourcefile_name;
> $pmm_G->Read("$sourcefile_fullname");
>
>
>
>
> # 4) local variable calculations: $rectangle_width, $rectangle_height,
> $x1, $y1
> $image_width = $pmm_G->Get('columns');
> $image_height = $pmm_G->Get('rows');
> if ($image_width < $image_height) {$image_min = $image_width} else
> {$image_min = $image_height};
> $rectangle_width_min = $rectangle_width_min_Faktor * $image_min;
> $rectangle_width_max = $rectangle_width_max_Faktor * $image_min;
> $rectangle_height_min = $rectangle_height_min_Faktor * $image_min;
> $rectangle_height_max = $rectangle_height_max_Faktor * $image_min;
> $rectangle_width = $rectangle_width_min +
> (int(rand($rectangle_width_max - $rectangle_width_min)) + 1);
> $rectangle_height = $rectangle_height_min +
> (int(rand($rectangle_height_max - $rectangle_height_min)) + 1);
> $x_allowed = $image_width - $rectangle_width;
> $y_allowed = $image_height - $rectangle_height;
> $x1 = int(rand($x_allowed))+1;
> $y1 = int(rand($y_allowed))+1;
>
>
> # 5) generate pmm_G by cropping the source image
> $pmm_G->Crop(geometry => "$rectangle_width x
> $rectangle_hight+$x1+$y1");
>
> # 6) convert pmm_G.png -flop pmm_G_flop.png
> $pmm_G_flop = $pmm_G->Clone();
> $pmm_G_flop->Flop();
>
> # 7) convert pmm_G.png pmm_G_flop.png +append pmm_tile_row.png
> $q = $pmm_G->Clone();
> push(@$q, $pmm_G_flop);
> $pmm_tile_row = $q->Append(stack=>'false');
>
> # 8) convert pmm_tile_row.png -flip pmm_tile_row_flip.png
> $pmm_tile_row_flip = $pmm_tile_row->Clone();
> $pmm_tile_row_flip->Flip();
>
> # 9) convert pmm_tile_row.png pmm_tile_row_flip.png -append
> pmm_tile.png
> @$q = ();
> $q = $pmm_tile_row->Clone();
> push(@$q, $pmm_tile_row_flip);
> $pmm_tile = $q->Append(stack=>'true');
>
> # 10) generate name of the result image
> chop $sourcefile_name;
> chop $sourcefile_name;
> chop $sourcefile_name;
> chop $sourcefile_name;
>
> if ($p <= 9) {$resultimage_name = "pmm_tile_" . $sourcefile_name . "-0"
> . $p . ".jpg"}
> else {$resultimage_name = "pmm_tile_" . $sourcefile_name . "-"
> . $p . ".jpg"};
>
> $resultimagepath_name = $pmm_resultfolder_path . $resultimage_name;
>
>
> # 11) save result image (pmm_tile)
> $pmm_tile->Write(filename=>"$resultimagepath_name",
> compression=>'JPEG', quality=>'95');
I think the main problem is using a string as a number (as noted
above).
HTH, Ken
| |
| nobull67@gmail.com 2006-11-01, 7:58 am |
|
On Oct 31, 12:14 pm, "g...@vi-anec.de" <g...@vi-anec.de> wrote:
> Hello,
>
> I want to call a subprogram PMM_TILE.PLX (see below) with do '...'
> multiple times in a nested for-loop from a program Batch_TILE.PLX.
> The outer loop works but the inner loop runs only one time
> with $p = 1 (only one image for every jpg in the $sourcefolder_path
> is generated instead of $pmm_number images).
>
> Did someone see the reason why the inner loop is aborted
> after $p =1 and how can this be corrected?
> for ($p = 1; $p <= $pmm_number; $p +=1) {do 'PMM_TILE.PLX'};
At a random guess PMM_TILE.PLX is altering the value of global variable
$p.
You should avoid global varialbles and always declare all variables as
lexically scoped in the smallest applicable lexical scope unless you
have a positive reason to do otherwise. (Note this advice applies to
programming in general, it's not specific to Perl).
For histoic reasons Perl defaults to allowing implicit declaration of
global variables simply by using them so does not tell you when you've
forgotten to declare your variables. This feature (and two others) can
be swtiched off by putting "use strict" near the top of each Perl
source file. Note do not fall into trap of simply declaring all your
variables in a stupidly wide scope just to get rid of the errors. This
is like changing the battery in your smoke alarm then wrapping a bag
arround it because you find it's now going off all the time.
Note that doing do(FILE) in a loop is probably the wrong thing anyhow.
You should make the "subprogram" into a module.
| |
| guba@vi-anec.de 2006-11-02, 9:57 pm |
| Hello Ken,
thank you for answering. I have tried to use a number
instead of a string ($pmm_number =3D 10) but the behavior is
the same: the inner loop runs one time with $p=3D1.
If I declare all variables as local the subprogram did not
get the values of $sourcefolder_path, $sourcefile_name,
$p and $pmm_resultfolder_path. I do not know how
PMM_TILE.PLX will get this values instead.
best regards
G=FCnter
kens schrieb:
> guba@vi-anec.de wrote:
>
> Always start your script with the following two lines:
>
> use strict;
> use warnings;
>
> Declare variables with 'my' when you first use them.
>
>
> I haven't tried running this, but this line is a problem in that you
> are assigning a string to $ppm_number, but using it as a number later.
>
> my $ppm_number =3D 10;
>
>
> It looks like you've been programming in C (nothing wrong with that),
> but you don't really need $sourcefolder_number and the for loop:
>
> foreach my $sourcefile_name (@sourcefolder_list) {
>
>
> $p +=3D 1 could be $p++
>
> Could also use a range for the for loop:
>
> for (1..$pmm_number){do 'PMM_TILE.PLX'};
>
"-0"[color=darkred]
>
> I think the main problem is using a string as a number (as noted
> above).
> HTH, Ken
| |
| guba@vi-anec.de 2006-11-02, 9:57 pm |
| Hello,
As I wrote Ken: If I declare all variables as local the subprogram
did not get the values of $sourcefolder_path, $sourcefile_name,
$p and $pmm_resultfolder_path. I do not know how
PMM_TILE.PLX will get this values instead.
> You should make the "subprogram" into a module
OK, but the beginner books I am using are very vague
about moduls; no word how they are build or how parts
are called at a specific point in an other programm.
best regards
G=FCnter
nobull67@gmail.com schrieb:
> On Oct 31, 12:14 pm, "g...@vi-anec.de" <g...@vi-anec.de> wrote:
>
'};[color=darkred]
>
> At a random guess PMM_TILE.PLX is altering the value of global variable
> $p.
>
> You should avoid global varialbles and always declare all variables as
> lexically scoped in the smallest applicable lexical scope unless you
> have a positive reason to do otherwise. (Note this advice applies to
> programming in general, it's not specific to Perl).
>
> For histoic reasons Perl defaults to allowing implicit declaration of
> global variables simply by using them so does not tell you when you've
> forgotten to declare your variables. This feature (and two others) can
> be swtiched off by putting "use strict" near the top of each Perl
> source file. Note do not fall into trap of simply declaring all your
> variables in a stupidly wide scope just to get rid of the errors. This
> is like changing the battery in your smoke alarm then wrapping a bag
> arround it because you find it's now going off all the time.
>
> Note that doing do(FILE) in a loop is probably the wrong thing anyhow.
> You should make the "subprogram" into a module.
| |
| guba@vi-anec.de 2006-11-03, 7:57 am |
| Hallo ,
I have exchangel the two loops
#Input
$pmm_number =3D 3; #<100
$sourcefolder_path =3D 'C:/ART/IM_PlaneCovering/1_Sourceimages/';
$pmm_resultfolder_path =3D
'C:/ART/IM_PlaneCovering/2_Tiles/2_01_pmm-Tiles/';
#program
opendir(DIR, "$sourcefolder_path") || die "folder not found: $!";
@sourcefolder_list =3D grep(/\.jp2$/, readdir(DIR));
for ($p =3D 1; $p <=3D $pmm_number; $p++) {
for ($k =3D 0; $k <=3D @sourcefolder_list; $k++) {
$sourcefile_name =3D $sourcefolder_list[$k];
do 'PMM_TILE.PLX'};
};
and now the generation process doesn't stop: Instead of stopping after
$p=3D3 it seems that the inner loop runs forever and $p is counting.
G=FCnter
| |
| nobull67@gmail.com 2006-11-03, 6:57 pm |
|
On Nov 2, 6:54 pm, "g...@vi-anec.de" <g...@vi-anec.de> wrote upside
down:
[ Please don't write upside down, it's rude. Please place your
responses in context. ]
> nobul...@gmail.com schrieb:
>
[color=darkred]
>
>
>
[color=darkred]
> As I wrote Ken: If I declare all variables as local the subprogram
> did not get the values of $sourcefolder_path, $sourcefile_name,
> $p and $pmm_resultfolder_path.
OK, but that doesn't explain why _all_ your variables are global.
If you want $p to be shared then it's up to you to make sure that the
subprogram doesn't stomp on it.
[color=darkred]
> OK, but the beginner books I am using are very vague
> about moduls; no word how they are build or how parts
> are called at a specific point in an other programm.
I suggest you burn those books. As a general rule any Perl book in
which the example programs don't all start with "use strict; use
warnings;" is probably going to do you more harm than good.
It is said that when a human embryo develops it re-lives human
evolution. But that's because that's what happens when there's no
guiding intelegence. We are intelegent. When you want to develop into
a Perl programmer you do not need to learn how to program in Perl1 then
Perl2, Perl3, Perl4 and then Perl5. It is much more effective to learn
to program in Perl5 directly.
The use of do(STRING) as you have in your code is a throwback to
earlier Perls. In Perl5 it is rarely used directly and when it is, it's
a "low level" feature that should be used by trained operators only,
not beginners. It's probably wise to know how to operate a VCR before
you start messing with the internals.
|
|
|
|
|