From martin_jacobs at optusnet.com.au Thu Mar 1 19:44:05 2007 From: martin_jacobs at optusnet.com.au (Martin Jacobs) Date: Fri, 2 Mar 2007 13:44:05 +1000 Subject: [Brisbane-pm] Counting elements in a 2D array Message-ID: Hi folks, How do I count the number of elements in a 2D array. I have an array called @rainrecord, which has a number of elements $rainrecord[x][y]. If I do $Last_line_in_Rainfall_data_array = $#rainrecord; It returns '7'. It looks to me that this is the number of 'x' entries - 'x' goes from 0 to 7, whereas 'y' could be anything. How do I get it to return the number of 'y' entries? Again, thanks in advance. Regards, Martin Visit my website... http://web.mac.com/martin_jacobs1 PS I have the book Programming Perl, and I've looked it up in PerlDoc, but I still don't get it. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.pm.org/pipermail/brisbane-pm/attachments/20070302/f03f176a/attachment.html From djames at thehub.com.au Thu Mar 1 20:23:47 2007 From: djames at thehub.com.au (Damian James) Date: Fri, 2 Mar 2007 14:23:47 +1000 Subject: [Brisbane-pm] Counting elements in a 2D array In-Reply-To: References: Message-ID: <817C0C7C-66A9-4916-BC86-5EA3C703C343@thehub.com.au> On 02/03/2007, at 1:44 PM, Martin Jacobs wrote: > Hi folks, > > How do I count the number of elements in a 2D array. > > I have an array called @rainrecord, which has a number of elements > $rainrecord[x][y]. > You have an array @rainrecord, each element of which contains a reference to an anonymous array, so $rainrecord[x] gives a reference to the array stored at that point. You'll find it less confusing if you dereference explicitly: $rainrecord[x]->[y]; Here it's plain that x is an index of the array, while y is the index of the reference to the anonymous array in $rainrecord[x]. It might seem strange, and it may take a while to sink in why you'd want to do this. The underlying reason is that Perl doesn't really do "2D arrays". What it does provide is a mechanism that lets you create arrays containing references to other (optionally anonymous) arrays. They aren't the same thing, and behave somewhat differently. 2D arrays are a matrices, while what Perl provides are recursive directed graphs. > If I do > > $Last_line_in_Rainfall_data_array = $#rainrecord; > > It returns '7'. It looks to me that this is the number of 'x' > entries - 'x' goes from 0 to 7, whereas 'y' could be anything. > > How do I get it to return the number of 'y' entries? The question only makes sense if you always have the same number of y entries in every x. How about (untested, so please don't run it as `sudo scriptname.pl > / boot/vmlinuz-2.4.27.3.386` or anything): my @rainrecord; for ( 0..7) { $rainrecord[$_] = [ 0 .. int rand 100] }; for my $x ( 0 .. $#rainrecord ) { printf "x = %3s; last index of y = %5s; number of elements in y = %5s\n" , $x, $#{ $rainrecord[$x] }, scalar @{ $rainrecord[$x] }; } or if you just want the max y: my $max_y; for ( @rainrecord ) { $max_y = $#{ $_ } if $#{$_} > $max_y } print "$max_y\n"; Note that here the dereferencing is all explicit (even if the syntax is a bit ungainly). Cheers, Damian From martin_jacobs at optusnet.com.au Sun Mar 4 17:57:56 2007 From: martin_jacobs at optusnet.com.au (Martin Jacobs) Date: Mon, 5 Mar 2007 11:57:56 +1000 Subject: [Brisbane-pm] Counting Elements in Multi-Dimensional Arrays Message-ID: Folks, Thanks to Dean and Damian for their replies to my earlier query. I had not realized that multi-dimensional arrays in Perl were actually arrays of arrays (or lists of references to other lists?). Anyhow, your comments made sense, and I see why you have to loop through all the elements in order to count them. Actually, what I wanted to do was to find the last timestep in a series of timesteps, and I was thinking of doing it indirectly by finding the length of the array and returning the value of that last element. As my program had already looped through the data, all I needed to do was to filch the last value from that loop. Regards, Martin Visit my website... http://web.mac.com/martin_jacobs1 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.pm.org/pipermail/brisbane-pm/attachments/20070305/68e3e58b/attachment.html From djames at thehub.com.au Mon Mar 5 14:23:31 2007 From: djames at thehub.com.au (Damian James) Date: Tue, 6 Mar 2007 08:23:31 +1000 Subject: [Brisbane-pm] Randal Schwarz cleared Message-ID: Hi All, I'm sure many of you will have come across this independently, but in any case it's some cause for celebration: http://www.theregister.co.uk/2007/03/05/intel_hacker_charges_quashed/ Folks who were at the SAGE conference in 2001 will have heard Randal's story first-hand. Cheers, Damian From martin_jacobs at optusnet.com.au Thu Mar 15 23:02:43 2007 From: martin_jacobs at optusnet.com.au (Martin Jacobs) Date: Fri, 16 Mar 2007 16:02:43 +1000 Subject: [Brisbane-pm] Messing with Modules Message-ID: <59E29A16-9D17-49B0-B33E-4E309621E9AB@optusnet.com.au> Hi folks, Here I am again. This time I want to my main program (PERRMOSS) to execute a block of code in a separate folder (the reason is to give users a choice in doing a particular calculation). What I did was straight out of 'Programming Perl', and it kind-of- works, though probably not as intended. The block of code is in a file in a sub-folder as follows input/Simple_Billycan_2_Stage.pm And it is called in PERRMOSS at line 369 as follows; use input::Simple_Billycan_2_Stage; The reason that it is not at the top, after #!/usr/local/bin/perl , is that PERRMOSS will not know which module to call until line 369. Simple_Billycan_2_Stage.pm includes the following (this is not the final product, by the way); package Simple_Billycan_2_Stage; require Exporter; our @ISA = qw(Exporter); our @Export = qw(camel); our @Export_OK = qw(weight); our $version = 1.00; sub camel {print "One-hump dromedary\n"} $weight = 1024; 1; I understand that 'Exporter' should make 'camel' visible to PERRMOSS. When I include the line... Simple_Billycan_2_Stage::camel (); It works as intended by printing One-hump dromedary to screen. However, when I include the line... camel(); I get the error message Undefined subroutine &main::camel called at perrmoss.pl line 370, line 21. Should I just be able to call 'camel' by camel(); ? Maybe I need to include the full 'path', though that seems rather messy. What I am looking for is a way to reference a block of code that is outside the main program. I understand that modules are the way to go, but if there is a simpler way to do it, I would be glad to know about it. Again, thanks for your help in advance. Regards, Martin Visit my website... http://web.mac.com/martin_jacobs1 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.pm.org/pipermail/brisbane-pm/attachments/20070316/80b30515/attachment.html From jarich at perltraining.com.au Fri Mar 16 16:29:37 2007 From: jarich at perltraining.com.au (Jacinta Richardson) Date: Sat, 17 Mar 2007 10:29:37 +1100 Subject: [Brisbane-pm] Messing with Modules In-Reply-To: <59E29A16-9D17-49B0-B33E-4E309621E9AB@optusnet.com.au> References: <59E29A16-9D17-49B0-B33E-4E309621E9AB@optusnet.com.au> Message-ID: <45FB2861.8080806@perltraining.com.au> Martin Jacobs wrote: > use input::Simple_Billycan_2_Stage; > > The reason that it is not at the top, after #!/usr/local/bin/perl , is > that PERRMOSS will not know which module to call until line 369. This isn't going to make a difference. When Perl first reads your files, it handles all the "use X" lines first, no matter where they appear in your file. If you really need to load these on a conditional basis then you're going to have to use require: if( some_condition ) { eval "require 'input::Simple_Billycan_2_Stage.pm'"; if($@) { print "Oops"; } } or if you know that it'll definitely be there, and permissions will be good etc: if( some_condition ) { require "input::Simple_Billycan_2_Stage.pm"; } (above code untested, some tweaks may be necessary). This is less than an ideal process though, so if you can deal with loading all of them and then just using the ones you need, that might be a better option. > Simple_Billycan_2_Stage.pm includes the following (this is not the final > product, by the way); > > package Simple_Billycan_2_Stage; > require Exporter; > our @ISA = qw(Exporter); > our @Export = qw(camel); > our @Export_OK = qw(weight); > our $version = 1.00; > > sub camel {print "One-hump dromedary\n"} > > $weight = 1024; > > 1; Capitalisation matters in Perl. I suggest you re-read perldoc Exporter or Chapters 12 and 13 in our Programming Perl course notese, or whichever chapters it is in the Programming Perl book. Any of these sources should help you spot your error up there. I recommend that you don't export things by default and instead allow the user to ask for them. More on this below. > Simple_Billycan_2_Stage::camel (); When you are "using" this code you're writing: use input::Simple_Billycan_2_Stage; This means that you're only going to have the default things exported. "camel" is not exported by default. So you'll need to write: use input::Simple_Billycan_2_Stage qw(camel); # this now works camel(); Exporting things by default (as you're doing with weight) is a bad idea because it can result in clashes between other modules (each exporting the same named symbol). Further, it makes it very difficult for a maintainer to immediately recognise where a particular symbol comes from. Exporting on request (as we do with camel) means that when the maintainer searches for the symbol throughout the code they will eventually find it next to its exporting module name. > What I am looking for is a way to reference a block of code that is > outside the main program. I understand that modules are the way to go, > but if there is a simpler way to do it, I would be glad to know about it. Modules are definitely the way to go. :) They'll make more sense as you use them more. All the best, Jacinta From martin_jacobs at optusnet.com.au Fri Mar 16 22:14:12 2007 From: martin_jacobs at optusnet.com.au (Martin Jacobs) Date: Sat, 17 Mar 2007 15:14:12 +1000 Subject: [Brisbane-pm] Messing with Modules 2 Message-ID: <65952189-3C12-4994-B3FB-E89212C3FDD9@optusnet.com.au> Thanks Jacinta and Damien, Yup, I missed the capitals. Just to make sure, I copied and pasted from http://www.unix.org.ua/orelly/perl/prog3/ch11_02.htm (which I didn't know existed until yesterday). I also tried Jacinta's qw suggestion. Same problem, though. This call works... use input::Simple_Billycan_2_Stage qw(water_export); Simple_Billycan_2_Stage::water_export(); But this one doesn't... use input::Simple_Billycan_2_Stage qw(water_export); water_export(); Here's the error message from the second call... Undefined subroutine &main::water_export called at perrmoss.pl line 379, line 21. Here's the module... package Simple_Billycan_2_Stage; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(water_export); # Symbols to be exported by default our @EXPORT_OK = qw($weight); # Symbols to be exported on request our $VERSION = 1.00; # Version number ### Include your variables and functions here sub water_export { print "One-hump dromedary\n" } $weight = 1024; 1; I also have the following at the start of the main program... #!/usr/local/bin/perl use warnings; use strict; use Time::Local; use lib; I tried the use lib after reading Chapter 11 of 'Programming Perl', though it does not make a difference to the problem described above. I might be clutching at straws, but I wonder if this has something to do with file paths. I'm working on Mac OSX10.4. The main program, PERRMOSS is... user/martin/PERRMOSS/Perl/PERRMOSS.pl The module is... user/martin/PERRMOSS/Perl/input/Simple_Billycan_2_Stage.pm And the perl stuff is in... system/library/perl/5.8.6/ (makes me wonder how the #!/usr/local/bin/perl line works! - I guess I need it for windows systems) One more thing. Because I'm going to define my modules with one sub- routine each, should I put the name of the sub-routine in our @EXPORT_OK = qw($function_name); ? Regards, Martin Visit my website... http://web.mac.com/martin_jacobs1 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.pm.org/pipermail/brisbane-pm/attachments/20070317/cce03050/attachment.html From jarich at perltraining.com.au Fri Mar 16 23:04:08 2007 From: jarich at perltraining.com.au (Jacinta Richardson) Date: Sat, 17 Mar 2007 17:04:08 +1100 Subject: [Brisbane-pm] Messing with Modules 2 In-Reply-To: <65952189-3C12-4994-B3FB-E89212C3FDD9@optusnet.com.au> References: <65952189-3C12-4994-B3FB-E89212C3FDD9@optusnet.com.au> Message-ID: <45FB84D8.8050504@perltraining.com.au> Martin Jacobs wrote: > use input::Simple_Billycan_2_Stage qw(water_export); ... > package Simple_Billycan_2_Stage; Try changing this to be: package input::Simple_Billycan_2_Stage; Or, if you want "input" to merely be the directory name, then keep your original package name but do: use lib 'input'; use Simple_Billycan_2_Stage qw(water_export); The package name has to be consistent where you define it and where you use it. J