Re: Filehandle within foreach loop
Yes, and I think that gives us *two* reasons to always explicitly close filehandles. :-) David On Sun, Jul 16, 2017 at 8:00 AM, Shawn H Coreywrote: > On Sun, 16 Jul 2017 07:36:39 -0400 > David Mertens wrote: > > > Also note that lexical filehandles close when they go out of scope > > True but you should always explicitly close your files. This gives you > a chance to report any errors it had, have rather than silently > ignoring them. > > > -- > 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/ > > > -- "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." -- Brian Kernighan
Re: Filehandle within foreach loop
On Sun, 16 Jul 2017 07:36:39 -0400 David Mertenswrote: > Also note that lexical filehandles close when they go out of scope True but you should always explicitly close your files. This gives you a chance to report any errors it had, have rather than silently ignoring them. -- 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: Filehandle within foreach loop
Even more readable: FILE: foreach my $file ( @files ) } ... last FILE if (some_condition); ... } Also note that lexical filehandles close when they go out of scope, except for the most recently "stat"ed file. Perl holds a reference to "the most recently stat-ed filehandle" in "the solitary underscore" as discussed in the documentation about -X <https://perldoc.perl.org/functions/-X.html>. The upshot is that a filehandle used in an expression like "-M $fh" will live until the next such expression, and the filehandle used in the last such expression won't close until the end of the program. David On Wed, Jul 12, 2017 at 5:28 PM, Jim Gibson <jimsgib...@gmail.com> wrote: > If you wish to terminate execution of a foreach loop without iterating > over all of the elements (@files, in this case) use the “last” statement: > > foreach my $file ( @files ) { > # process file > open( my $fh, ‘<‘, $file ) or die(…); > while( my $line = <$fh> ) { ># process line > } > close ($fh) or die( … ); > > last if (some_condition); > } > > If you wish to terminate the foreach loop from inside the while loop, you > can give the foreach loop a label and use the label in the “last” > statement. Without an explicit label, “last” will terminate the innermost > loop (the while loop here): > > ALL: foreach my $file ( @files ) { > # process file > open( my $fh, ‘<‘, $file ) or die(…); > while( my $line = <$fh> ) { ># process line >last ALL if (some_condition); > } > close ($fh) or die( … ); > } > > However, in that case you have skipped the close statement, and the close > will happen automatically when the file handle $fh goes out of scope, but > you cannot do any explicit error checking on the close. > > > > On Jul 12, 2017, at 12:20 PM, perl kamal <kamal.p...@gmail.com> wrote: > > > > Hello All, > > > > I would like to read multiple files and process them.But we could read > the first file alone and the rest are skipped from the while loop. Please > correct me where am i missing the logic.Thanks. > > > > use strict; > > use warnings; > > my @files=qw(Alpha.txt Beta.txt Gama.txt); > > > > foreach my $file (@files) > > { > > open (my $FH, $file) or die "could not open file\n"; > > > > while( my $line = <$FH> ){ > > #[process the lines & hash construction.] > > } > > close $FH; > > } > > > > Regards, > > Kamal. > > > > Jim Gibson > > -- > To unsubscribe, e-mail: beginners-unsubscr...@perl.org > For additional commands, e-mail: beginners-h...@perl.org > http://learn.perl.org/ > > > -- "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." -- Brian Kernighan
Re: Filehandle within foreach loop
On Thu, 13 Jul 2017 00:50:42 +0530 perl kamalwrote: > open (my $FH, $file) or die "could not open file\n"; A quick note: output the file name and error message to have a better idea of what went wrong. open (my $FH, $file) or die "could not open file $file: $!\n"; -- 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: Filehandle within foreach loop
If you wish to terminate execution of a foreach loop without iterating over all of the elements (@files, in this case) use the “last” statement: foreach my $file ( @files ) { # process file open( my $fh, ‘<‘, $file ) or die(…); while( my $line = <$fh> ) { # process line } close ($fh) or die( … ); last if (some_condition); } If you wish to terminate the foreach loop from inside the while loop, you can give the foreach loop a label and use the label in the “last” statement. Without an explicit label, “last” will terminate the innermost loop (the while loop here): ALL: foreach my $file ( @files ) { # process file open( my $fh, ‘<‘, $file ) or die(…); while( my $line = <$fh> ) { # process line last ALL if (some_condition); } close ($fh) or die( … ); } However, in that case you have skipped the close statement, and the close will happen automatically when the file handle $fh goes out of scope, but you cannot do any explicit error checking on the close. > On Jul 12, 2017, at 12:20 PM, perl kamal <kamal.p...@gmail.com> wrote: > > Hello All, > > I would like to read multiple files and process them.But we could read the > first file alone and the rest are skipped from the while loop. Please correct > me where am i missing the logic.Thanks. > > use strict; > use warnings; > my @files=qw(Alpha.txt Beta.txt Gama.txt); > > foreach my $file (@files) > { > open (my $FH, $file) or die "could not open file\n"; > > while( my $line = <$FH> ){ > #[process the lines & hash construction.] > } > close $FH; > } > > Regards, > Kamal. Jim Gibson -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Filehandle within foreach loop
That code will read each line from each file. The problem is likely in the part that says: #[process the lines & hash construction.] What are you doing there? On Wed, Jul 12, 2017 at 3:23 PM perl kamal <kamal.p...@gmail.com> wrote: > Hello All, > > I would like to read multiple files and process them.But we could read the > first file alone and the rest are skipped from the while loop. Please > correct me where am i missing the logic.Thanks. > > use strict; > use warnings; > my @files=qw(Alpha.txt Beta.txt Gama.txt); > > foreach my $file (@files) > { > open (my $FH, $file) or die "could not open file\n"; > > while( my $line = <$FH> ){ > #[process the lines & hash construction.] > } > close $FH; > } > > Regards, > Kamal. >
Filehandle within foreach loop
Hello All, I would like to read multiple files and process them.But we could read the first file alone and the rest are skipped from the while loop. Please correct me where am i missing the logic.Thanks. use strict; use warnings; my @files=qw(Alpha.txt Beta.txt Gama.txt); foreach my $file (@files) { open (my $FH, $file) or die "could not open file\n"; while( my $line = <$FH> ){ #[process the lines & hash construction.] } close $FH; } Regards, Kamal.
Re: map vs foreach
On Tue, Sep 30, 2014 at 6:19 PM, David Precious dav...@preshweb.co.uk wrote: Like most things, TIMTOWTDI, but I believe Perl Best Practices [PBP] advises against using map in void context. As PBP[1] is encoded in Perl::Critic map and grep are intended to be pure functions, not mutators. If you want to iterate with side-effects, then you should use a proper for or foreach loop. Somewhere there's a quote (possibly apocryphal but wait! [2]) from Larry Wall on a map vs foreach thread: That being said, I'd never grep someone in a void context myself. He actually wasn't condemning the use of map/grep in a void context per se, just noting his personal preference. a [1] Perl Best Practices Standards and Styles for Developing Maintainable Code By Damian Conway http://shop.oreilly.com/product/9780596001735.do#tab_04_2 http://shop.oreilly.com/product/9780596001735.do [2] quoted here: http://www.perlmonks.org/?node_id=809543 Andy Bach, afb...@gmail.com 608 658-1890 cell 608 261-5738 wk
map vs foreach
Is the output of these two lines equivalent? map { $hash-{$_} = shift @record } @{$self-{'FIELDNAMES'}}; $hash-{$_} = shift @record foreach @{$self-{'FIELDNAMES'}}; They appear to be in my testing, but I'd like to make sure. Is one more appropriate than the other in a situation like this, or is it simply a styling difference? Thanks, Frank SurfShop shopping cart is now open source... Follow us on GitHub! https://github.com/surfshopcart/surfshop -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: map vs foreach
Is asking a preference-based question appropriate for a beginners list appropriate? Question for you: Have you updated your software to have a more modern look and feel or does it still resemble 1995? I ask because, in your own words, you said or is it simply a styling difference?. Feedback for you: The look and feel of your software quickly helps any potential shopper to return to Amazon. Yes, I am top-posting. Why? Because top-posting annoys me as well as most on this list, but so does seeing your signature in each of your trivial questions, SEO initiatives and marketing schemes And, [ drum roll ] you're welcome. On Tue, Sep 30, 2014 at 5:08 PM, SSC_perl p...@surfshopcart.com wrote: Is the output of these two lines equivalent? map { $hash-{$_} = shift @record } @{$self-{'FIELDNAMES'}}; $hash-{$_} = shift @record foreach @{$self-{'FIELDNAMES'}}; They appear to be in my testing, but I'd like to make sure. Is one more appropriate than the other in a situation like this, or is it simply a styling difference? Thanks, Frank SurfShop shopping cart is now open source... Follow us on GitHub! https://github.com/surfshopcart/surfshop -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/ -- http://seatingspace.com
Re: map vs foreach
On Tue, 30 Sep 2014 14:08:14 -0700 SSC_perl p...@surfshopcart.com wrote: Is the output of these two lines equivalent? map { $hash-{$_} = shift @record } @{$self-{'FIELDNAMES'}}; $hash-{$_} = shift @record foreach @{$self-{'FIELDNAMES'}}; They appear to be in my testing, but I'd like to make sure. Is one more appropriate than the other in a situation like this, or is it simply a styling difference? Fancy tricks are fine...if you understand them. But do yourself a favour: code like you will have to read it after an all-night party (some day, you will). foreach my $field_name ( @{ $self-{FIELDNAMES} } ){ $hash-{ $field_name } = shift @record; } In other words, keep is simple. -- Don't stop where the ink does. Shawn -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: map vs foreach
On Tue, 30 Sep 2014 14:08:14 -0700 SSC_perl p...@surfshopcart.com wrote: Is the output of these two lines equivalent? map { $hash-{$_} = shift @record } @{$self-{'FIELDNAMES'}}; $hash-{$_} = shift @record foreach @{$self-{'FIELDNAMES'}}; [...] Is one more appropriate than the other in a situation like this, or is it simply a styling difference? map is more suitable when using it to transform a list; it doesn't make sense to use it as a flow-control statement where a for loop would be more sane. In other words, if you're not assigning or using the result of the map call, you're using it wrong, and a for loop would be more readable (and, in older perls at least, likely more efficient). So, e.g.: my %fields = map { $_ = shift @record } @{$self-{'FIELDNAMES'}}; ... would make sense, because you're using map to produce the data you want, rather than using it instead of a for loop. Like most things, TIMTOWTDI, but I believe Perl Best Practices advises against using map in void context. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: map vs foreach
On Sep 30, 2014, at 4:08 PM, Shawn H Corey wrote: code like you will have to read it after an all-night party (some day, you will). Those days are over, but point taken! ;) Thanks, Frank SurfShopCART https://github.com/surfshopcart/surfshop -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: map vs foreach
On Sep 30, 2014, at 4:19 PM, David Precious wrote: So, e.g.: my %fields = map { $_ = shift @record } @{$self-{'FIELDNAMES'}}; ... would make sense, because you're using map to produce the data you want, rather than using it instead of a for loop. Thanks, David. That was an excellent explanation! As usual, I stumbled across an old thread on PerlMonks after I posted my question. :\ It was a good read, however, and it's helped to clear up my understanding of map. If anyone else is interested, it's here: http://www.perlmonks.org/?node_id=296742 However, David's response was pretty much everything that was in the thread, but in a nutshell. Frank SurfShopCART https://github.com/surfshopcart/surfshop -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: map vs foreach
On 09/30/2014 05:08 PM, SSC_perl wrote: Is the output of these two lines equivalent? map { $hash-{$_} = shift @record } @{$self-{'FIELDNAMES'}}; $hash-{$_} = shift @record foreach @{$self-{'FIELDNAMES'}}; They appear to be in my testing, but I'd like to make sure. Is one more appropriate than the other in a situation like this, or is it simply a styling difference? both do the exact same thing. the general rule is to use map only when you are generating a new list which is the output of map. your code is called using map in a void context. perl used to generate the list and then throw it out which is a waste. even with that inefficiency fixed, it is still considered by most a poor coding style. you are telling the reader that you are building a list but don't use it. the foreach is better style yet some might not like the shift trick (i have used that one). but you just are assigning a list of values to a list of tokens in a hash. a slice is the best and fastest way to do that. my %hash ; @hash{ @{$self-{'FIELDNAMES'} } = @record ; done! if you are using DBI, you can get the row back as a hash reference and not need that code. uri -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: map vs foreach
On Tue, 30 Sep 2014 16:38:24 -0700 SSC_perl p...@surfshopcart.com wrote: On Sep 30, 2014, at 4:08 PM, Shawn H Corey wrote: code like you will have to read it after an all-night party (some day, you will). Those days are over, but point taken! ;) They're never over but they do get farther apart. ;) -- Don't stop where the ink does. Shawn -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach and next
My code my %attr = ( PrintError = 0, RaiseError = 0 ); my $dbh = DBI-connect($dsn, $user, $pass, \%attr); unless ($dbh) { next; } my $query = SHOW DATABASES; I use unless ($dbh) { next; } and this work fine. Thanks 09.04.2012 01:22, Jim Gibson написал: At 12:50 AM + 4/9/12, Vyacheslav wrote: I enabled RaiserError, then script die. ... my %attr = ( PrintError = 0, RaiseError = 1 ); Use: RaiseError = 0 instead so that your script will not raise an exception and die. Then check $dbh-err. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach and next
On 09/04/2012 14:24, Vyacheslav wrote: My code my %attr = ( PrintError = 0, RaiseError = 0 ); my $dbh = DBI-connect($dsn, $user, $pass, \%attr); unless ($dbh) { next; } my $query = SHOW DATABASES; I use unless ($dbh) { next; } and this work fine. Thanks 09.04.2012 01:22, Jim Gibson написал: At 12:50 AM + 4/9/12, Vyacheslav wrote: I enabled RaiserError, then script die. ... my %attr = ( PrintError = 0, RaiseError = 1 ); Use: RaiseError = 0 instead so that your script will not raise an exception and die. Then check $dbh-err. Hi Vyacheslav I suggest you use this instead my $dbh = DBI-connect($dsn, $user, $pass) or do { warn Can't connect to database $db: $DBI::errstr\n; next; }; so that your program shows which database connections have failed and been skipped. This is pretty much the same as your original code except that a failure to connect causes a warning instead of a fatal 'die', and execution skips to the next database source. Also the warning string shows the name of the database instead of saying just Can't connect to the DB. HTH, Rob -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach and next
Enclose DBI operation inside eval - #!/usr/bin/perl use strict; use warnings; use DBI; use DBD::mysql; foreach $db (hostdb($project)) { eval { my $server = $db; my $dbname = information_schema; my $port = 3306; my $dsn = dbi:mysql:$dbname:$server:$port; my $user = user; my $pass = pass; my $dbh = DBI-connect($dsn, $user, $pass) or die Can't connect to the DB: $DBI::errstr\n; my $query = SHOW DATABASES; my $sth = $dbh-prepare($query); $sth-execute; my @dbs; while ( my $data = $sth-fetchrow_arrayref ) { push @dbs, $data-[0]; } $dbh-disconnect; }; if ($@) { print host $db - not ok; } else { print host $db - ok; } img src=http://www.gnome.org/friends/banners/associate.png; alt=Become a Friend of GNOME border=0 / From: Vyacheslav agapov.sl...@gmail.com To: beginners@perl.org Sent: Sunday, April 8, 2012 11:42 AM Subject: foreach and next Hello all. My english bad and i have a problem. I am connected to databases in a cycle foreach and the script die, if one of database is not available. #!/usr/bin/perl use strict; use warnings; use DBI; use DBD::mysql; foreach $db (hostdb($project)) { my $server = $db; my $dbname = information_schema; my $port = 3306; my $dsn = dbi:mysql:$dbname:$server:$port; my $user = user; my $pass = pass; my $dbh = DBI-connect($dsn, $user, $pass) or die Can't connect to the DB: $DBI::errstr\n; my $query = SHOW DATABASES; my $sth = $dbh-prepare($query); $sth-execute; my @dbs; while ( my $data = $sth-fetchrow_arrayref ) { push @dbs, $data-[0]; } print host $db - ok; $dbh-disconnect; My result host db1 - ok host db2 - ok host db3 - ok DBI connect('information_schema:db4:3306','user',...) failed: Can't connect to MySQL server on 'db4' (111) at ./dbcheck.pl line 53 and script die How I can pass an error that the cycle has continued execute? I need host db1 - ok host db2 - ok host db3 - ok ... host db10 - ok Can I use next operator in this situation? -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach and next
Hi Vyacheslav, On Sun, 08 Apr 2012 06:12:53 + Vyacheslav agapov.sl...@gmail.com wrote: Hello all. My english bad and i have a problem. I am connected to databases in a cycle foreach and the script die, if one of database is not available. #!/usr/bin/perl use strict; use warnings; use DBI; use DBD::mysql; foreach $db (hostdb($project)) { my $server = $db; my $dbname = information_schema; my $port = 3306; my $dsn = dbi:mysql:$dbname:$server:$port; my $user = user; my $pass = pass; my $dbh = DBI-connect($dsn, $user, $pass) or die Can't connect to the DB: $DBI::errstr\n; Your problem is that you are invoking die ... which throws an exception. See: https://www.socialtext.net/perl5/exception_handling Since this exception is not caught (using eval { ... }) it terminates the entire program. So what you should do instead is handle it gracefully (say using next): my $dbh = DBI-connect($dsn, $user, $pass); if (!$dbh) { next DB_HOSTS_LOOP; # And label the loop appropriately. } Regards, Shlomi Fish -- - Shlomi Fish http://www.shlomifish.org/ Humanity - Parody of Modern Life - http://shlom.in/humanity Chuck Norris refactors 10 million lines of Perl code before lunch. 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: foreach and next
Thanks all. using eval helped me. 08.04.2012 09:43, Shlomi Fish пишет: Hi Vyacheslav, On Sun, 08 Apr 2012 06:12:53 + Vyacheslavagapov.sl...@gmail.com wrote: Hello all. My english bad and i have a problem. I am connected to databases in a cycle foreach and the script die, if one of database is not available. #!/usr/bin/perl use strict; use warnings; use DBI; use DBD::mysql; foreach $db (hostdb($project)) { my $server = $db; my $dbname = information_schema; my $port = 3306; my $dsn = dbi:mysql:$dbname:$server:$port; my $user = user; my $pass = pass; my $dbh = DBI-connect($dsn, $user, $pass) or die Can't connect to the DB: $DBI::errstr\n; Your problem is that you are invoking die ... which throws an exception. See: https://www.socialtext.net/perl5/exception_handling Since this exception is not caught (using eval { ... }) it terminates the entire program. So what you should do instead is handle it gracefully (say using next): my $dbh = DBI-connect($dsn, $user, $pass); if (!$dbh) { next DB_HOSTS_LOOP; # And label the loop appropriately. } Regards, Shlomi Fish -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach and next
Hi Vyacheslav, On Sun, 08 Apr 2012 15:10:06 + Vyacheslav agapov.sl...@gmail.com wrote: Thanks all. using eval helped me. The problem with eval in Perl 5 is that it catches any and all thrown exceptions . I.e: by default, it doesn't do Object-Oriented exceptions like Java, Ruby, Python and other languages do, though this can be done to a large extent using some CPAN modules. As a result, by using eval, you risk easily trapping other more meaningful exceptions, which *should* cause your program to terminate. In your case, you're throwing an exception explicitly upon failure, so if you're not interested in an exception getting thrown, you should just handle the failure differently. ( I also recall seeing something about excessive exceptions throwing and trapping being costly in CPU time, but this shouldn't make a difference in this case. ) Regards, Shlomi Fish -- - Shlomi Fish http://www.shlomifish.org/ Why I Love Perl - http://shlom.in/joy-of-perl “Interesting” has a negative correlation with “successful”. — Anno on Freenode's #perl 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: foreach and next
On 2012-04-08 17:10, Vyacheslav wrote: using eval helped me. You should not use exceptions for normal code flow. Read the DBI docs (perldoc DBI). If a failed connection must be an exception, set RaiseError to true. But if it isn't an exception, leave it false, and test $dbh-err (or the global $DBI::err). -- Ruud -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach and next
I enabled RaiserError, then script die. ... my %attr = ( PrintError = 0, RaiseError = 1 ); my $dbh = DBI-connect($dsn, $user, $pass, \%attr); # or die Can't connect to the DB: $DBI::errstr\n; my $query = SHOW DATABASES; my $sth = $dbh-prepare($query) or die Can't prepare SQL statement: $DBI::errstr\n;; $sth-execute; my @dbs; while ( my $data = $sth-fetchrow_arrayref ) { push @dbs, $data-[0]; } ... DBI connect('information_schema:db1:3306','test',...) failed: Can't connect to MySQL server on 'db1' (111) at ./dbcheck.pl line 72 I test with $dbh-err, but the script all the same die. 08.04.2012 18:40, Dr.Ruud пишет: On 2012-04-08 17:10, Vyacheslav wrote: using eval helped me. You should not use exceptions for normal code flow. Read the DBI docs (perldoc DBI). If a failed connection must be an exception, set RaiseError to true. But if it isn't an exception, leave it false, and test $dbh-err (or the global $DBI::err). -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach and next
At 12:50 AM + 4/9/12, Vyacheslav wrote: I enabled RaiserError, then script die. ... my %attr = ( PrintError = 0, RaiseError = 1 ); Use: RaiseError = 0 instead so that your script will not raise an exception and die. Then check $dbh-err. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
foreach and next
Hello all. My english bad and i have a problem. I am connected to databases in a cycle foreach and the script die, if one of database is not available. #!/usr/bin/perl use strict; use warnings; use DBI; use DBD::mysql; foreach $db (hostdb($project)) { my $server = $db; my $dbname = information_schema; my $port = 3306; my $dsn = dbi:mysql:$dbname:$server:$port; my $user = user; my $pass = pass; my $dbh = DBI-connect($dsn, $user, $pass) or die Can't connect to the DB: $DBI::errstr\n; my $query = SHOW DATABASES; my $sth = $dbh-prepare($query); $sth-execute; my @dbs; while ( my $data = $sth-fetchrow_arrayref ) { push @dbs, $data-[0]; } print host $db - ok; $dbh-disconnect; My result host db1 - ok host db2 - ok host db3 - ok DBI connect('information_schema:db4:3306','user',...) failed: Can't connect to MySQL server on 'db4' (111) at ./dbcheck.pl line 53 and script die How I can pass an error that the cycle has continued execute? I need host db1 - ok host db2 - ok host db3 - ok ... host db10 - ok Can I use next operator in this situation? -- 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?
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?
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?
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?
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?
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?
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?
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?
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: Foreach loop and hash of arrays
On 07/02/2012 01:39, sono...@fannullone.us wrote: On Feb 6, 2012, at 1:42 PM, Steve Bertrand wrote: This may be easier. It uses the hash elements directly as an array, then uses grep to see if the zip code is within the specific state. It returns true if the state owns that zip code, and false if it doesn't. if ( grep( /^$customers_zip$/, @{ $states{ $customers_state } } ) ) { $match = yes; } Thanks, Steve. Elegantly simple! It is odd to use a regex here when the intention is a simple string comparison grep( $_ eq $customers_zip, @{ $states{ $customers_state } } ) in fact, if the objective is to reduce the code to something as brief as possible then this will do the trick my $match = (grep $_ eq $customers_zip, @{$states{$customers_state}}) ? 'yes' : 'no'; Rob -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Foreach loop and hash of arrays
On 12-02-07 06:26 AM, Rob Dixon wrote: in fact, if the objective is to reduce the code to something as brief as possible then this will do the trick my $match = (grep $_ eq $customers_zip, @{$states{$customers_state}}) ? 'yes' : 'no'; You can use first from List::Util for more efficient code: use List::Util qw( first ); my $match = (first { $_ eq $customers_zip } @{$states{$customers_state}}) ? 'yes' : 'no'; -- 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/
Foreach loop and hash of arrays
I have a web form where people enter their address info and I want to make sure that the first three digits of their Zip Code correspond to their State. So I'm creating a hash of arrays that contains a list of Zip Codes for the United States. I've also written a foreach loop to access this hash but I'd like to see if it could be written better. For example, do I really need three foreach loops? Also, the first line that's printed contains 499 and I can't figure out where that's coming from. I'd appreciate some help. Thanks, Marc #!/Users/perl5/perlbrew/perls/perl-5.14.1/bin/perl use strict; use warnings; my %states = ( AL = [ '350','351', ], AK = [ '995','996', ], AZ = [ '850','851', ], AR = [ '716','717', ], ); my $customers_state = 'AZ'; my $customers_zip = '850'; my $match = 'no' ; STATE: foreach my $state (keys %states) { # print $state \n; if ($state eq $customers_state) { foreach (@{$states{$customers_state}}) { my @zips = $_; ZIP:foreach my $zip (@zips) { next ZIP if $zip ne $customers_zip; $match = 'yes'; # print \nZip matches the State \n; } } last STATE; } } print $match; SAMPLE OUTPUT: 499 yes -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Foreach loop and hash of arrays
On 2012.02.06 16:14, sono...@fannullone.us wrote: I have a web form where people enter their address info and I want to make sure that the first three digits of their Zip Code correspond to their State. So I'm creating a hash of arrays that contains a list of Zip Codes for the United States. I've also written a foreach loop to access this hash but I'd like to see if it could be written better. For example, do I really need three foreach loops? Also, the first line that's printed contains 499 and I can't figure out where that's coming from. I'd appreciate some help. Thanks, Marc #!/Users/perl5/perlbrew/perls/perl-5.14.1/bin/perl use strict; use warnings; my %states = ( AL = [ '350','351', ], AK = [ '995','996', ], AZ = [ '850','851', ], AR = [ '716','717', ], ); my $customers_state = 'AZ'; my $customers_zip = '850'; my $match = 'no' ; STATE: foreach my $state (keys %states) { # print $state \n; if ($state eq $customers_state) { foreach (@{$states{$customers_state}}) { my @zips = $_; ZIP:foreach my $zip (@zips) { next ZIP if $zip ne $customers_zip; $match = 'yes'; # print \nZip matches the State \n; } } last STATE; } } print $match; SAMPLE OUTPUT: 499 yes This may be easier. It uses the hash elements directly as an array, then uses grep to see if the zip code is within the specific state. It returns true if the state owns that zip code, and false if it doesn't. Therefore, if it is true, $match will be set to yes. #!/usr/bin/perl use strict; use warnings; my %states = ( AL = [ '350','351', ], AK = [ '995','996', ], AZ = [ '850','851', ], AR = [ '716','717', ], ); my $customers_state = 'AR'; my $customers_zip = '716'; my $match = 'no' ; if ( grep( /^$customers_zip$/, @{ $states{ $customers_state } } ) ) { $match = yes; } print $match\n; Steve -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Foreach loop and hash of arrays
On Mon, Feb 6, 2012 at 1:14 PM, sono...@fannullone.us wrote: For example, do I really need three foreach loops? You can get rid of third ForLoop for sure. use strict; use warnings; my %states = ( AL = [ '350','351', ], AK = [ '995','996', ], AZ = [ '850','851', ], AR = [ '716','717', ], ); my $customers_state = 'AZ'; my $customers_zip = '850'; my $match = 'no' ; STATE: foreach my $state (keys %states) { if ($state eq $customers_state) { foreach (@{$states{$customers_state}}) { my @zips = $_; $match = 'yes' if grep /$customers_zip/, @zips ; last STATE; } } } print $match;
Re: Foreach loop and hash of arrays
On 06/02/2012 21:14, sono...@fannullone.us wrote: use strict; use warnings; my %states = ( AL = [ '350','351', ], AK = [ '995','996', ], AZ = [ '850','851', ], AR = [ '716','717', ], ); my $customers_state = 'AZ'; my $customers_zip = '850'; my $match = 'no' ; STATE: foreach my $state (keys %states) { # print $state \n; if ($state eq $customers_state) { foreach (@{$states{$customers_state}}) { my @zips = $_; ZIP:foreach my $zip (@zips) { next ZIP if $zip ne $customers_zip; $match = 'yes'; # print \nZip matches the State \n; } } last STATE; } } print $match; You are missing the point of hashes: that they can be indexed directly by a key value, and there is no need to loop through all elements of the has. You can reduce you code to just one loop: foreach my $zip (@{$states{$customers_state}}) { if ($zip eq $customers_zip) { $match = 'yes'; last; } } HTH, Rob -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Foreach loop and hash of arrays
On 02/06/2012 04:58 PM, Parag Kalra wrote: On Mon, Feb 6, 2012 at 1:14 PM,sono...@fannullone.us wrote: For example, do I really need three foreach loops? You can get rid of third ForLoop for sure. you don't actually lose the third loop. grep is an implied loop. STATE: foreach my $state (keys %states) { if ($state eq $customers_state) { foreach (@{$states{$customers_state}}) { use a named variable there. my @zips = $_; that assigns an array ref to @zips and not the list of zips. you need to dereference it. and you don't need a temp var as you can do that in the grep itself. $match = 'yes' if grep /$customers_zip/, @zips ; last STATE; why the last call there? it means the double loop only executes one time. uri } } } print $match; -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Foreach loop and hash of arrays
On Mon, Feb 6, 2012 at 3:14 PM, sono...@fannullone.us wrote: So I'm creating a hash of arrays that contains a list of Zip Codes for the United States. I've also written a foreach loop to access this hash but I'd like to see if it could be written better. For example, do I really need three foreach loops? snip #!/Users/perl5/perlbrew/perls/perl-5.14.1/bin/perl use strict; use warnings; my %states = ( AL = [ '350','351', ], AK = [ '995','996', ], AZ = [ '850','851', ], AR = [ '716','717', ], ); my $customers_state = 'AZ'; my $customers_zip = '850'; my $match = 'no' ; STATE: foreach my $state (keys %states) { # print $state \n; if ($state eq $customers_state) { foreach (@{$states{$customers_state}}) { my @zips = $_; ZIP:foreach my $zip (@zips) { next ZIP if $zip ne $customers_zip; $match = 'yes'; # print \nZip matches the State \n; } } last STATE; } } print $match; You can also key the hash with the first three digits and skip the loops altogether. my %zips = ( 350 = 'AL', 351 = 'AL', 995 = 'AK', 996 = 'AK', 850 = 'AZ', 851 = 'AZ', 716 = 'AR', 717 = 'AR', ); my $customers_state = 'AZ'; my $customers_zip = '850'; if ( exists( $zips{$customers_zip} ) and $zips{$customers_zip} eq $customers_state ) { print 'yes'; } else { print 'no'; } -- Robert Wohlfarth
Re: Foreach loop and hash of arrays
On Feb 6, 2012, at 1:42 PM, Steve Bertrand wrote: This may be easier. It uses the hash elements directly as an array, then uses grep to see if the zip code is within the specific state. It returns true if the state owns that zip code, and false if it doesn't. if ( grep( /^$customers_zip$/, @{ $states{ $customers_state } } ) ) { $match = yes; } Thanks, Steve. Elegantly simple! Marc -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Question/Problem with foreach loop
Gents, Sorry for my delayed response. Thank you for your suggestions. Based on your feedback, I made the following changes, and the hook is now working as expected. Thanks a million! my $taskstate = $taskEntity-GetFieldValue(state)-GetValue(); $session-OutputDebugString (Task's state is $taskstate\n); next if $taskstate eq Completed; -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Using $variable outside a foreach loop
Maybe it's too early in the morning here, but I can't seem to remember how to use a lexical $variable that is defined inside a foreach loop, outside of that loop.=:\ Here's the loop: foreach my $name (split (/, */, $names)) { next unless ($name =~ /\w/); my $sortstr = substr(00$totalcells, -2); $html =~ s|/tdtd|/td\ntd|g; $cell{$sortstr$name} = !--//CELL $name//--; $cell{$sortstr$name} =~ s/\[NAME\]/$name/sig; $totalcells++; } I want to use $name in another loop just after this one, but when I do, I get Global symbol $name requires explicit package. Could someone please point me in the right direction? Thanks, Marc -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Using $variable outside a foreach loop
Hello, foreach my $name (split (/, */, $names)) { Here, the scope of $name is limited to the foreach loop and not outside it. So, you will have to declare the variable again for use outside the loop. Regards, Alan Haggai Alavi. -- The difference makes the difference. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Using $variable outside a foreach loop
On Jun 3, 2011, at 8:45 AM, Alan Haggai Alavi wrote: Here, the scope of $name is limited to the foreach loop and not outside it. So, you will have to declare the variable again for use outside the loop. But wouldn't that make the second $name a different variable? I'm not at my computer to try it. Marc -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Using $variable outside a foreach loop
At 8:37 AM -0700 6/3/11, sono...@fannullone.us wrote: Maybe it's too early in the morning here, but I can't seem to remember how to use a lexical $variable that is defined inside a foreach loop, outside of that loop.=:\ Here's the loop: foreach my $name (split (/, */, $names)) { next unless ($name =~ /\w/); my $sortstr = substr(00$totalcells, -2); $html =~ s|/tdtd|/td\ntd|g; $cell{$sortstr$name} = !--//CELL $name//--; $cell{$sortstr$name} =~ s/\[NAME\]/$name/sig; $totalcells++; } I want to use $name in another loop just after this one, but when I do, I get Global symbol $name requires explicit package. Declare the variable just before the loop, and remove the 'my' from the foreach statement: my $name; foreach $name ( ... ) { ... } -- Jim Gibson j...@gibson.org -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Using $variable outside a foreach loop
On Jun 3, 8:37 am, sono...@fannullone.us wrote: ... I want to use $name in another loop just after this one, but when I do, I get Global symbol $name requires explicit package. One option is an outer enclosing block that'll extend the scope of $name to that entire block: { # enclosing block my $name; for $name ( split //... ) { } # first loop for $name ( ... ) { } # next loop } -- Charles DeRykus -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Using $variable outside a foreach loop
C.DeRykus wrote: One option is an outer enclosing block that'll extend the scope of $name to that entire block: Jim Gibson wrote: Declare the variable just before the loop, and remove the 'my' from the foreach statement: Thanks for the responses. I was able to get it to work. Marc -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Using $variable outside a foreach loop
On 11-06-03 11:37 AM, sono...@fannullone.us wrote: I want to use $name in another loop just after this one, but when I do, I get Global symbol $name requires explicit package. Could someone please point me in the right direction? Certainly. The variable used in a foreach loop is independent of anything outside the loop. Even if it's declared before the loop, it's value is unavailable inside the loop: #!/usr/bin/env perl use strict; use warnings; my $name = 'forgotten'; for $name ( qw( fred barney wilma )){ print \$name is $name\n; } print \$name is $name\n; __END__ Outside the loop, it becomes just another variable. -- Just my 0.0002 million dollars worth, Shawn Confusion is the first step of understanding. Programming is as much about organization and communication as it is about coding. The secret to great software: Fail early often. 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: Using $variable outside a foreach loop
s == sono-io sono...@fannullone.us writes: sMaybe it's too early in the morning here, but I can't seem to remember how to use a lexical $variable that is defined inside a foreach loop, outside of that loop.=:\ sHere's the loop: sforeach my $name (split (/, */, $names)) { snext unless ($name =~ /\w/); smy $sortstr = substr(00$totalcells, -2); that looks like you are forcing leading 0's. the common idiom for that is sprintf %02d, $totalcells. your way works but is harder to read. s$html =~ s|/tdtd|/td\ntd|g; why are you doing that insert of a newline each time in that loop? you don't use or modify $html anywhere else in this loop. s$cell{$sortstr$name} = !--//CELL $name//--; s$cell{$sortstr$name} =~ s/\[NAME\]/$name/sig; you just assigned that value the line before. unless $name has [NAME] inside it, how could that s/// op ever do anything? s$totalcells++; s} sI want to use $name in another loop just after this one, but when I do, I get Global symbol $name requires explicit package. did you want to use $name as the loop variable again? that is perfectly fine as this $name is scoped only to that loop. if you just want to use $name for any other reason you need to just declare it with my. uri -- Uri Guttman -- u...@stemsystems.com http://www.sysarch.com -- - Perl Code Review , Architecture, Development, Training, Support -- - Gourmet Hot Cocoa Mix http://bestfriendscocoa.com - -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Using $variable outside a foreach loop
On Fri, Jun 3, 2011 at 1:23 PM, Jim Gibson jimsgib...@gmail.com wrote: Declare the variable just before the loop, and remove the 'my' from the foreach statement: my $name; foreach $name ( ... ) { ... } That won't do. What that code actually translated to is my $name; for my $name ( ... ) { ... } With the second $name masking the first! IIRC this is explained somewhere in PBP, but I don't have the book at hand right now. In any case, if you want to use the variable outside of the for, don't name the two variables the same. The rough rule of thumb is that leaving off the my in a for(each) is probably introducing subtle bugs into your program. Brian.
Re: Using $variable outside a foreach loop
BF == Brian Fraser frase...@gmail.com writes: BF On Fri, Jun 3, 2011 at 1:23 PM, Jim Gibson jimsgib...@gmail.com wrote: Declare the variable just before the loop, and remove the 'my' from the foreach statement: my $name; foreach $name ( ... ) { ... } BF That won't do. What that code actually translated to is BF my $name; BF for my $name ( ... ) { ... } not true. perl -le 'my $x = zzz ; for $x ( qw( foo bar ) ) { print L: $x } print E: $x' L: foo L: bar E: zzz foreach without a my will localize the loop variable. that isn't the same as my. BF With the second $name masking the first! IIRC this is explained BF somewhere in PBP, but I don't have the book at hand right now. In BF any case, if you want to use the variable outside of the for, BF don't name the two variables the same. The rough rule of thumb is BF that leaving off the my in a for(each) is probably introducing BF subtle bugs into your program. why search PBP when the perldocs are very clear about it and easily searched? from perldoc perlsyn: The foreach loop iterates over a normal list value and sets the variable VAR to be each element of the list in turn. If the variable is preceded with the keyword my, then it is lexically scoped, and is therefore visible only within the loop. Otherwise, the variable is implicitly local to the loop and regains its former value upon exiting the loop. If the variable was previously declared with my, it uses that variable instead of the global one, but it's still localized to the loop. This implicit localisation occurs only in a foreach loop. so in my oneliner the my allowed the $x to not need redeclaring in the foreach but it still localized the value to the loop. but as i said in another post, the OP just likely wants to use $name as a loop var again which he can with another my declare. uri -- Uri Guttman -- u...@stemsystems.com http://www.sysarch.com -- - Perl Code Review , Architecture, Development, Training, Support -- - Gourmet Hot Cocoa Mix http://bestfriendscocoa.com - -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Using $variable outside a foreach loop
On Jun 3, 2011, at 10:22 AM, Uri Guttman wrote: smy $sortstr = substr(00$totalcells, -2); that looks like you are forcing leading 0's. the common idiom for that is sprintf %02d, $totalcells. your way works but is harder to read. Thanks, Uri. I didn't catch that. I didn't write this script. I'm using it to learn from and cleaning it up at the same time. I know that learning Perl from an older script probably isn't the best way to do it, but since I have a vested interest in how this script works, it's forcing me to learn it faster than I would otherwise. However, if anyone knows of a shopping cart written in modern perl, I'd love to have a look. s$html =~ s|/tdtd|/td\ntd|g; why are you doing that insert of a newline each time in that loop? you don't use or modify $html anywhere else in this loop. Actually, it's being used on an HTML template and just makes the HTML code look cleaner. s I want to use $name in another loop just after this one, but when I do, I get Global symbol $name requires explicit package. did you want to use $name as the loop variable again? that is perfectly fine as this $name is scoped only to that loop. if you just want to use $name for any other reason you need to just declare it with my. I wasn't very clear in what I wanted. Sorry. I wanted to use the value of $name in another loop but after testing, it looks like Shawn was correct when he wrote: The variable used in a foreach loop is independent of anything outside the loop. I actually had to use another variable in the second loop to grab the name. Thanks to everyone who responded. I got it to work now. Marc -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Using $variable outside a foreach loop
On 11-06-03 03:58 PM, sono...@fannullone.us wrote: I wasn't very clear in what I wanted. Sorry. I wanted to use the value of $name in another loop but after testing That implies something is wrong with your logic. The question is: what value of $name do you want? The first? The last? Either you want the second loop nested in the first, or you want a completely independent one that iterates through all the values. -- Just my 0.0002 million dollars worth, Shawn Confusion is the first step of understanding. Programming is as much about organization and communication as it is about coding. The secret to great software: Fail early often. 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: Using $variable outside a foreach loop
On Jun 3, 2011, at 1:38 PM, Shawn H Corey wrote: That implies something is wrong with your logic. Yep. I came to the same conclusion. =:) -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Using $variable outside a foreach loop
On 2011-06-03 17:37, sono...@fannullone.us wrote: Maybe it's too early in the morning here, but I can't seem to remember how to use a lexical $variable that is defined inside a foreach loop, outside of that loop.=:\ Here's the loop: foreach my $name (split (/, */, $names)) { next unless ($name =~ /\w/); my $sortstr = substr(00$totalcells, -2); $html =~ s|/tdtd|/td\ntd|g; $cell{$sortstr$name} = !--//CELL $name//--; $cell{$sortstr$name} =~ s/\[NAME\]/$name/sig; $totalcells++; } I want to use $name in another loop just after this one, but when I do, I get Global symbol $name requires explicit package. Could someone please point me in the right direction? What would be the use of that? If you declare $name before the loop, it will (after leaving the loop) have the last value assigned to it. What would you want that for? To me, yours is an X-Y problem. (see google) You should probably just declare a new variable for the other loop. -- Ruud -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Using $variable outside a foreach loop
R == Ruud rvtol+use...@isolution.nl writes: R On 2011-06-03 17:37, sono...@fannullone.us wrote: Maybe it's too early in the morning here, but I can't seem to remember how to use a lexical $variable that is defined inside a foreach loop, outside of that loop.=:\ Here's the loop: foreach my $name (split (/, */, $names)) { next unless ($name =~ /\w/); my $sortstr = substr(00$totalcells, -2); $html =~ s|/tdtd|/td\ntd|g; $cell{$sortstr$name} = !--//CELL $name//--; $cell{$sortstr$name} =~ s/\[NAME\]/$name/sig; $totalcells++; } I want to use $name in another loop just after this one, but when I do, I get Global symbol $name requires explicit package. Could someone please point me in the right direction? R What would be the use of that? R If you declare $name before the loop, it will (after leaving the loop) R have the last value assigned to it. What would you want that for? not true. see a post i made with a one liner. $name is localized (if not my) so the previous value before the loop is seen after the loop. loop values don't affect the outer $name at all. uri -- Uri Guttman -- u...@stemsystems.com http://www.sysarch.com -- - Perl Code Review , Architecture, Development, Training, Support -- - Gourmet Hot Cocoa Mix http://bestfriendscocoa.com - -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Using $variable outside a foreach loop
On Jun 3, 2011 3:17 PM, Uri Guttman u...@stemsystems.com wrote: perl -le 'my $x = zzz ; for $x ( qw( foo bar ) ) { print L: $x } print E: $x' L: foo L: bar E: zzz That's odd, I would have thought that would have given 'foo bar bar'. So, how would you keep data from a loop once you're outside of the loop?
Re: Using $variable outside a foreach loop
sw == shawn wilson ag4ve...@gmail.com writes: sw On Jun 3, 2011 3:17 PM, Uri Guttman u...@stemsystems.com wrote: perl -le 'my $x = zzz ; for $x ( qw( foo bar ) ) { print L: $x } print sw E: $x' L: foo L: bar E: zzz sw That's odd, I would have thought that would have given 'foo bar bar'. So, sw how would you keep data from a loop once you're outside of the loop? you don't use a loop variable for that. just declare it before the loop, assign as needed inside the loop and it will be there. if that gets messy as it can, i change the code to use a sub with the loop inside and return the value. uri -- Uri Guttman -- u...@stemsystems.com http://www.sysarch.com -- - Perl Code Review , Architecture, Development, Training, Support -- - Gourmet Hot Cocoa Mix http://bestfriendscocoa.com - -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: script takes long time to run when comparing digits within strings using foreach
On 2011-05-27 10:18, eventual wrote: I have an array , @datas, and each element within @datas is a string that's made up of 6 digits with spaces in between like this “1 2 3 4 5 6”, so the array look like this @datas = ('1 2 3 4 5 6', '1 2 9 10 11 12', '1 2 3 4 5 8', '1 2 3 4 5 9' , '6 7 8 9 10 11'); Now I wish to compare each element of @datas with the rest of the elements in @datas in such a way that if 5 of the digits match, to take note of the matching indices, and so the script I wrote is appended below. a. Do once what you can do only once. There are at least 2 points where you didn't: 1. prepare @datas before looping; 2. don't compare the same stuff more than once. b. Assemble a result, and report at the end. Don't use any 'shared resources' like incrementing global counters while going along. #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my @data = DATA; $_ = { map { $_ = 1 } split } for @data; $ARGV[0] and print Dumper( \@data ); my @result; for my $i ( 0 .. $#data - 1 ) { my @k = keys %{ $data[ $i ] }; for my $j ( $i + 1 .. $#data ) { my $n = 0; exists $data[ $j ]{ $_ } and ++$n for @k; $n = 5 and push @result, [ $i, $j ]; } } print Dumper( \@result ); __DATA__ 1 2 3 4 5 6 1 2 9 10 11 12 1 2 3 4 5 8 1 2 3 4 5 9 6 7 8 9 10 11 -- Ruud -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: script takes long time to run when comparing digits within strings using foreach
eventual wrote: Hi, Hello, I have an array , @datas, and each element within @datas is a string that's made up of 6 digits with spaces in between like this “1 2 3 4 5 6”, so the array look like this @datas = ('1 2 3 4 5 6', '1 2 9 10 11 12', '1 2 3 4 5 8', '1 2 3 4 5 9' , '6 7 8 9 10 11'); Now I wish to compare each element of @datas with the rest of the elements in @datas in such a way that if 5 of the digits match, to take note of the matching indices, and so the script I wrote is appended below. However, the script below takes a long time to run if the datas at @datas are huge( eg 30,000 elements). I then wonder is there a way to rewrite the script so that the script can run faster. Thanks ## script below ### #!/usr/bin/perl use strict; my @matched_location = (); my @datas = ('1 2 3 4 5 6', '1 2 9 10 11 12', '1 2 3 4 5 8', '1 2 3 4 5 9' , '6 7 8 9 10 11'); my $iteration_counter = -1; foreach (@datas){ $iteration_counter++; my $reference = $_; my $second_iteration_counter = -1; my $string = ''; foreach (@datas){ $second_iteration_counter++; my @individual_digits = split / /,$_; my $ctr = 0; foreach(@individual_digits){ if($reference =~/^$_ | $_ | $_$/){ $ctr++; } } if ($ctr= 5){ $string = $string . $second_iteration_counter ; } } $matched_location[$iteration_counter] = $string; } my $ctr = -1; foreach(@matched_location){ $ctr++; print Index $ctr of \@matched_location = $_\n; } Your program can be reduced to: my @matched_location; my @datas = ( '1 2 3 4 5 6', '1 2 9 10 11 12', '1 2 3 4 5 8', '1 2 3 4 5 9', '6 7 8 9 10 11' ); for my $i ( 0 .. $#datas ) { for my $j ( 0 .. $#datas ) { $matched_location[ $i ] .= $j if 5 = grep $datas[ $i ] =~ /(?:^|(?= ))$_(?= |$)/, split ' ', $datas[ $j ] } } print map Index $_ of \@matched_location = $matched_location[$_]\n, 0 .. $#matched_location; You should benchmark it to see if it is any faster than your original code. John -- Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction. -- Albert Einstein -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
script takes long time to run when comparing digits within strings using foreach
Hi, I have an array , @datas, and each element within @datas is a string that's made up of 6 digits with spaces in between like this “1 2 3 4 5 6”, so the array look like this @datas = ('1 2 3 4 5 6', '1 2 9 10 11 12', '1 2 3 4 5 8', '1 2 3 4 5 9' , '6 7 8 9 10 11'); Now I wish to compare each element of @datas with the rest of the elements in @datas in such a way that if 5 of the digits match, to take note of the matching indices, and so the script I wrote is appended below. However, the script below takes a long time to run if the datas at @datas are huge( eg 30,000 elements). I then wonder is there a way to rewrite the script so that the script can run faster. Thanks ## script below ### #!/usr/bin/perl use strict; my @matched_location = (); my @datas = ('1 2 3 4 5 6', '1 2 9 10 11 12', '1 2 3 4 5 8', '1 2 3 4 5 9' , '6 7 8 9 10 11'); my $iteration_counter = -1; foreach (@datas){ $iteration_counter++; my $reference = $_; my $second_iteration_counter = -1; my $string = ''; foreach (@datas){ $second_iteration_counter++; my @individual_digits = split / /,$_; my $ctr = 0; foreach(@individual_digits){ if($reference =~/^$_ | $_ | $_$/){ $ctr++; } } if ($ctr = 5){ $string = $string . $second_iteration_counter ; } } $matched_location[$iteration_counter] = $string; } my $ctr = -1; foreach(@matched_location){ $ctr++; print Index $ctr of \@matched_location = $_\n; }
Re: script takes long time to run when comparing digits within strings using foreach
Hi eventual, On Friday 27 May 2011 11:18:01 eventual wrote: Hi, I have an array , @datas, and each element within @datas is a string that's made up of 6 digits with spaces in between like this “1 2 3 4 5 6”, so the array look like this @datas = ('1 2 3 4 5 6', '1 2 9 10 11 12', '1 2 3 4 5 8', '1 2 3 4 5 9' , '6 7 8 9 10 11'); Now I wish to compare each element of @datas with the rest of the elements in @datas in such a way that if 5 of the digits match, to take note of the matching indices, and so the script I wrote is appended below. However, the script below takes a long time to run if the datas at @datas are huge( eg 30,000 elements). I then wonder is there a way to rewrite the script so that the script can run faster. Thanks ## script below ### #!/usr/bin/perl use strict; my @matched_location = (); my @datas = ('1 2 3 4 5 6', '1 2 9 10 11 12', '1 2 3 4 5 8', '1 2 3 4 5 9' , '6 7 8 9 10 11'); my $iteration_counter = -1; foreach (@datas){ $iteration_counter++; my $reference = $_; my $second_iteration_counter = -1; my $string = ''; foreach (@datas){ $second_iteration_counter++; my @individual_digits = split / /,$_; my $ctr = 0; foreach(@individual_digits){ if($reference =~/^$_ | $_ | $_$/){ $ctr++; } } if ($ctr = 5){ $string = $string . $second_iteration_counter ; } } $matched_location[$iteration_counter] = $string; } my $ctr = -1; foreach(@matched_location){ $ctr++; print Index $ctr of \@matched_location = $_\n; } First of all, you should add use warnings; to your code. Then you should get rid of the implicit $_ as loop iterator because it's easy to break. For more information see: http://perl-begin.org/tutorials/bad-elements/ Other than that - you should use a better algorithm. One option would be to sort the integers and then use a diff/merge-like algorithm: http://en.wikipedia.org/wiki/Merge_algorithm A different way would be to use a hash to count the number of times each number occured in the two sets, and then see how many of them got a value of 2 (indicating they are in both sets). But at the moment, everything is very inefficient there. Regards, Shlomi Fish -- - Shlomi Fish http://www.shlomifish.org/ Star Trek: We, the Living Dead - http://shlom.in/st-wtld I often wonder why I hang out with so many people who are so pedantic. And then I remember - because they are so pedantic. -- Israeli Perl Monger 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/
Question/Problem with foreach loop
Hi, In this code, the intent is to iterate through the tasks and modify the ID field. The Task record (entity) should not be modified if it's state equals Completed. When I run this routine, there are two problems: Problem 1) The if statement is not being evaluated. The record (even if it's in the Completed state is being modified. Problem 2) Subsequent records (ie any record after the first one is not modfied). In other words, if I have multiple records, just the first one in the list gets modified. All others are skipped. Can someone help me figure out where I am going wrong with this? Thanks. snip # Iterate through all tasks foreach (@$tasks) { # Get a task entity for the current taskid (in $_) my $taskEntity = $session-GetEntity ('almtask', $_); $taskEntity-GetFieldValue(state)-GetValue(); if ($taskEntity eq Completed) {return;} # did not work# if ($taskEntity eq Completed) {return '';} # did not work# if ($taskEntity eq Completed) {exit 1;} else { $session-OutputDebugString (Setting task entity to modify\n); # Modify this task... $taskEntity-EditEntity ('Modify'); $session-OutputDebugString (Modifying task\n); $session-OutputDebugString (Setting task's project id to $ProjectID); # Set the project field to the new ProjectID my $returnMsg = $taskEntity-SetFieldValue ('project', $ProjectID); return $returnMsg unless $returnMsg eq ''; snip -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Question/Problem with foreach loop
On 5/18/11 Wed May 18, 2011 5:06 PM, CM Analyst cmanal...@yahoo.com scribbled: Hi, In this code, the intent is to iterate through the tasks and modify the ID field. The Task record (entity) should not be modified if it's state equals Completed. When I run this routine, there are two problems: Problem 1) The if statement is not being evaluated. The record (even if it's in the Completed state is being modified. Problem 2) Subsequent records (ie any record after the first one is not modfied). In other words, if I have multiple records, just the first one in the list gets modified. All others are skipped. Can someone help me figure out where I am going wrong with this? Thanks. snip # Iterate through all tasks foreach (@$tasks) { You would be better to use an explicit variable here rather than the default $_, especially since you are calling methods in the loop that might modify the value of $_: foreach my $task ( @$tasks ) { # Get a task entity for the current taskid (in $_) my $taskEntity = $session-GetEntity ('almtask', $_); We don't know what $session contains and what GetEntity does. $taskEntity-GetFieldValue(state)-GetValue(); You have a bareword here (state). If this is supposed to be a string, then you should quote it. state could be a function (or even a keyword in later Perls): $taskEntity-GetFieldValue('state')-GetValue(); Do you have 'use strict;' in your program. if ($taskEntity eq Completed) {return;} You probably don't want 'return' here. If you want to skip this task and go to the next one in the loop, then you should use 'next'. 'return' will exit from a function (although we don't know if this code is in a function since you haven't shown us the whole code.): next if $taskEntity eq 'Completed'; -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Question/Problem with foreach loop
CA == CM Analyst cmanal...@yahoo.com writes: CA my $taskEntity = $session-GetEntity ('almtask', $_); that gets a perl object in $taskEntity. CA $taskEntity-GetFieldValue(state)-GetValue(); where is the value being assigned to? $taskEntity is not being modified or set in that line of code. it is just the object used to make the call. CA if ($taskEntity eq Completed) {return;} since that is the object, it will never eq Completed. you need to save the value from the previous line and compare that. this should work: my $value = $taskEntity-GetFieldValue(state)-GetValue(); if ( $value eq Completed) { return; } see how that saves the value in a variable and then compares to that variable. you need to learn more about OO in perl and how to differentiate an object from the values that methods can return. uri -- Uri Guttman -- u...@stemsystems.com http://www.sysarch.com -- - Perl Code Review , Architecture, Development, Training, Support -- - Gourmet Hot Cocoa Mix http://bestfriendscocoa.com - -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach loop
Thanks Rob. That seems to have done the trick. I understand this is a for loop, but do you mind breaking it down line by line so I fully understand what it is doing? Thank you, Chris for my $i (44..47) { my $rlp = $data[$i]; $sum{$cell}{$sect}{$carr}{$dist} += $rlp if $rlp; } -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach loop
On 3/25/11 Fri Mar 25, 2011 9:11 AM, Chris Stinemetz chrisstinem...@gmail.com scribbled: Thanks Rob. That seems to have done the trick. I understand this is a for loop, but do you mind breaking it down line by line so I fully understand what it is doing? My name isn't Rob, but I can give you a line-by-line description. for my $i (44..47) { $i is a lexically-scoped scalar variable that will have the values 44, 45, 46, and 47 through four successive iterations of the statements enclosed by the for loop. my $rlp = $data[$i]; $rlp is a lexically-scoped variable that will be assigned a value fetched from the 44th, 45th, etc. element of the @data array. $sum{$cell}{$sect}{$carr}{$dist} += $rlp if $rlp; The value assigned to $rlp in the previous line will be added to the value in the element of a four-level nested hash as indexed by the values of $cell, $sect, $carr, and $dist if and only if the value of $rlp evaluates to true. This will be true for all values other than '', 0, and undef, so no addition of undefined values will occur. Numerical conversions of the hash element and the scalar variable are possible, depending upon what their values are. } End of for loop. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
RE: foreach loop
Thanks again Jim! I have one more question..lol I appreciate all your help! I would like $dist be part of the print statement, but I am not sure how to code it correctly. I am getting the following error: Global symbol @dist requires explicit package name at ./jim.pl line 38. Execution of ./banding aborted due to compilation errors. #!/usr/bin/perl use warnings; use strict; #my $filepath = 'C:/temp/PCMD'; # my $filepath = '/home/cstinemetz/perl_programs/1.EVDOPCMD'; # my $outfile = 'output.txt'; # open my $fh, '', $filepath or die ERROR opening $filepath: $!; # open my $out, '', $outfile or die ERROR opening $outfile: $!; my %sum; while (DATA){ next unless /;/; chomp; my @data = split /;/; my($cell,$sect,$chan,$carr,$rlp1,$rlp2,$rlp3,$rlp4,$dist,$precis) = @data[31,32,38,39,44,45,46,47,261,262]; $carr = ( $cell 299 $chan == 175 ) ? 2 : ( $chan == 1025 ) ? 2 : 1 ; #nested ternary operator $dist = ( length( $dist ) 1 ) ? $dist/6.6/8/2*10/10 : 0 ; $sum{$cell}{$sect}{$carr} += $rlp1 += $rlp2 += $rlp3 += $rlp4 || 0 ; } my @data; for my $cell ( sort keys %sum ) { for my $sect ( sort keys %{$sum{$cell}} ) { for my $carr ( sort keys %{$sum{$cell}{$sect}} ) { push( @data, [$dist[ $sum{$cell}{$sect}{$carr}, $cell, $sect, $carr ]]); } } } for my $record ( sort { $a-[1] = $b-[1] || $a-[2] = $b-[2] || $a-[3] = $b-[3] } @data ) { my( $val, $cell, $sect, $carr, $dist ) = @$record; print $cell\t $sect\t $carr\t $dist\t $val\n; } __DATA__ PACE | EVDOPCMD | 33.0 | 101218 | 07 | 8;1023240136;1218;0;1;00a01a2bcdc7;0310003147702376;ac016d4a;;;5.6.128.8;0;43234169;43234349;;;1;1;1;;0;;19;5.6.128.22;172.30.151.5;304;3;304;3;15;175;15;175;15;175;1;1798;1251;0;0;2;19;20;1;1;1;0;128;5.6.128.8;;;301;5.6.128.8;;;8;304;31;43244037;;;1;18;43234169;01;;43234416;0;0;304;3;21;19;175;15;405;1;1;1;1;0;125;1|| 8;1023240137;1218;0;1;00a01db74ace;;ac0174ca;43243423;1678442111;5.6.128.8;1;0;;43242544;43244207;43243423;43243647;;;1000;1;1;;0;;19;5.6.128.26;;372;2;372;2;;43243012;0;43243562;15;175;15;175;15;175;1;5;48;19;20;49;50;;0;1;2;0;68;5.6.128.8;;;301;5.6.128.8;;;8;372;21;43244207;;;1;18;43243423;01;;43242544;0;0;372;2;21;19;175;15;177;3;1;0;0;0;68;1|43243753;0;0;372;2;21;19;175;15;177;3;1;1;1;0;71;1| 8;1023240138;1218;0;1;00a02017ccdb;0310003147833882;aca344d7;;;5.6.128.13;0;43234160;43234358;;;1;1;1;;0;;19;5.6.128.31;172.30.151.5;320;2;320;2;15;75;15;75;15;75;1;2162;1317;0;0;2;19;20;1;1;1;0;104;5.6.128.13;;;306;5.6.128.13;;;8;320;21;43244164;;;1;18;43234160;01;;43234404;0;0;320;2;21;19;75;15;279;6;1;1;1;0;64;1|| -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach loop
On 3/24/11 Thu Mar 24, 2011 9:04 AM, Chris Stinemetz cstinem...@cricketcommunications.com scribbled: I would like $dist be part of the print statement, but I am not sure how to code it correctly. The value of $dist will vary for each row. If you want to print out the correct value of $dist that corresponds to the value of the sum, then you will have to store the value. I am getting the following error: Global symbol @dist requires explicit package name at ./jim.pl line 38. Execution of ./banding aborted due to compilation errors. See note below line 38. #!/usr/bin/perl use warnings; use strict; #my $filepath = 'C:/temp/PCMD'; # my $filepath = '/home/cstinemetz/perl_programs/1.EVDOPCMD'; # my $outfile = 'output.txt'; # open my $fh, '', $filepath or die ERROR opening $filepath: $!; # open my $out, '', $outfile or die ERROR opening $outfile: $!; my %sum; while (DATA){ next unless /;/; chomp; my @data = split /;/; my($cell,$sect,$chan,$carr,$rlp1,$rlp2,$rlp3,$rlp4,$dist,$precis) = @data[31,32,38,39,44,45,46,47,261,262]; $carr = ( $cell 299 $chan == 175 ) ? 2 : ( $chan == 1025 ) ? 2 : 1 ; #nested ternary operator $dist = ( length( $dist ) 1 ) ? $dist/6.6/8/2*10/10 : 0 ; $sum{$cell}{$sect}{$carr} += $rlp1 += $rlp2 += $rlp3 += $rlp4 || 0 ; } I see you are changing your program requirements. You are now accumulating multiple rlp values instead of one. This line has two problems. The first is that you have placed the closing brace at the end of the line where it is easy to lose. Perhaps this is why you have mistakenly used the $dist variable in the lines below, where it is not in scope. The second problem is the multiple '+=' operators. Do you know what they will do in this case? I don't. I would have to run a test to see what the effect is on the intermediate variables. You might be doing more arithmetic than is necessary. If you want to accumulate the four variables, why not just do: $sum{$cell}{$sect}{$carr} += ($rlp1 + $rlp2 + $rlp3 + $rlp4) || 0 ; my @data; for my $cell ( sort keys %sum ) { for my $sect ( sort keys %{$sum{$cell}} ) { for my $carr ( sort keys %{$sum{$cell}{$sect}} ) { push( @data, [$dist[ $sum{$cell}{$sect}{$carr}, $cell, $sect, $carr ]]); The syntax $dist[ ... ] tells the Perl parser to access an element of the array @dist. The proper way to include $dist with the other values would be: push( @data, [$sum{$cell}{$sect}{$carr}, $cell, $sect, $carr, $dist ] ); but if you use that, you will get a compiler error, as $dist is not in scope here. You need to store the value of $dist when you read each record, and retrieve it before using it here. You will have to figure out how to save and retrieve the value of dist for each record. There will be one dist value for each record, but the value of the sum will be the sum of several records, so I think you have inconsistent logic in what you are trying to do. Which of the several dist values do you want printed with the sum values? } } } for my $record ( sort { $a-[1] = $b-[1] || $a-[2] = $b-[2] || $a-[3] = $b-[3] } @data ) { my( $val, $cell, $sect, $carr, $dist ) = @$record; This line is good, but you did not store your values this way. See above. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach loop
Jim Gibson wrote: On 3/24/11 Thu Mar 24, 2011 9:04 AM, Chris Stinemetz cstinem...@cricketcommunications.com scribbled: $sum{$cell}{$sect}{$carr} += $rlp1 += $rlp2 += $rlp3 += $rlp4 || 0 ; } I see you are changing your program requirements. You are now accumulating multiple rlp values instead of one. This line has two problems. The first is that you have placed the closing brace at the end of the line where it is easy to lose. Perhaps this is why you have mistakenly used the $dist variable in the lines below, where it is not in scope. The second problem is the multiple '+=' operators. Do you know what they will do in this case? I don't. I would have to run a test to see what the effect is on the intermediate variables. You might be doing more arithmetic than is necessary. Yes it is. That is modifying $rlp1, $rlp2 and $rlp3 as well as $sum{$cell}{$sect}{$carr}. And because the = operator is right associative $rlp3 is modified first and then $rlp2 and then $rlp1 and finally $sum{$cell}{$sect}{$carr}. Observe: $ perl -le' package JWK; use Carp; sub TIESCALAR { my $class = shift; my $value = shift || 0; carp JWK::TIESCALAR got $value; return bless \$value, $class; } sub FETCH { my $self = shift; confess wrong type unless ref $self; croak usage error if @_; carp JWK::FETCH returned $$self; return $$self; } sub STORE { my $self = shift; confess wrong type unless ref $self; $$self = shift; carp JWK::STORE set to $$self; croak usage error if @_; } sub DESTROY { my $self = shift; confess wrong type unless ref $self; carp JWK::DESTROY $$self; } package main; tie my $x, JWK, 23; tie my $y, JWK, 34; tie my $z, JWK, 45; my $count = $x + $y + $z; print \$count = $count; my $count = $x += $y += $z; print \$count = $count; ' JWK::TIESCALAR got 23 at -e line 31 JWK::TIESCALAR got 34 at -e line 32 JWK::TIESCALAR got 45 at -e line 33 JWK::FETCH returned 34 at -e line 35 JWK::FETCH returned 23 at -e line 35 JWK::FETCH returned 45 at -e line 35 $count = 102 JWK::FETCH returned 45 at -e line 37 JWK::FETCH returned 34 at -e line 37 JWK::STORE set to 79 at -e line 37 JWK::FETCH returned 79 at -e line 37 JWK::FETCH returned 23 at -e line 37 JWK::STORE set to 102 at -e line 37 JWK::FETCH returned 102 at -e line 37 $count = 102 JWK::DESTROY 45 at -e line 0 JWK::DESTROY 79 at -e line 0 JWK::DESTROY 102 at -e line 0 John -- Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction. -- Albert Einstein -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach loop
Jim, I am getting really close to finishing up this program. perl is lot's of fun and I appreciate all your help! The output is giving me the data I am looking for except for the following issues: How would I add the correct code to make sure the array has a numeric value before the loop iterations begin? I am getting the following error multiple times and when I look at the output there are blanks. How can I eliminate this? Argument isn't numeric in addition (+) at ./DOband.pl line 30, $fh line 3. Thank you in advance. My complete program is posted at the bottom. $sum{$cell}{$sect}{$carr} += $rlp1 += $rlp2 += $rlp3 += $rlp4 || 0 ; } If you want to accumulate the four variables, why not just do: $sum{$cell}{$sect}{$carr} += ($rlp1 + $rlp2 + $rlp3 + $rlp4) || 0 ; I changed my code to your suggestion. The output is the same, but yours is much cleaner so I kept yours. Thank you. #!/usr/bin/perl use warnings; use strict; my $filepath = 'C:/temp/PCMD'; #my $filepath = '/home/cstinemetz/perl_programs/1.EVDOPCMD'; #my $outfile = 'output.txt'; open my $fh, '', $filepath or die ERROR opening $filepath: $!; #open my $out, '', $outfile or die ERROR opening $outfile: $!; my %sum; while ($fh){ next unless /;/; chomp; my @data = split /;/; my($cell,$sect,$chan,$carr,$rlp1,$rlp2,$rlp3,$rlp4,$dist,$precis) = @data[31,32,38,39,44,45,46,47,261,262]; $carr = ( $cell 299 $chan == 175 ) ? 2 : ( $chan == 1025 ) ? 2 : 1 ; #nested ternary operator $dist = sprintf %.1f, ( length( $dist ) 1 ) ? $dist/6.6/8/2*10/10 : 0 ; $sum{$cell}{$sect}{$carr}{$dist} += ($rlp1 + $rlp2 + $rlp3 + $rlp4) || 0 ; } my @data; for my $cell ( sort keys %sum ) { for my $sect ( sort keys %{$sum{$cell}} ) { for my $carr ( sort keys %{$sum{$cell}{$sect}} ) { for my $dist ( sort keys %{$sum{$cell}{$sect}{$carr}} ) { push( @data, [ $sum{$cell}{$sect}{$carr}{$dist}, $cell, $sect, $carr, $dist,]); } } } } for my $record ( sort { $a-[1] = $b-[1] || $a-[2] = $b-[2] || $a-[3] = $b-[3] || $a-[4] = $b-[4] } @data ) { my( $val, $cell, $sect, $carr, $dist ) = @$record; print $cell\t $sect\t $carr\t $dist\t $val\n; } -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach loop
On 25/03/2011 02:36, Chris Stinemetz wrote: Jim, I am getting really close to finishing up this program. perl is lot's of fun and I appreciate all your help! The output is giving me the data I am looking for except for the following issues: How would I add the correct code to make sure the array has a numeric value before the loop iterations begin? I am getting the following error multiple times and when I look at the output there are blanks. How can I eliminate this? Argument isn't numeric in addition (+) at ./DOband.pl line 30,$fh line 3. Thank you in advance. #!/usr/bin/perl use warnings; use strict; my $filepath = 'C:/temp/PCMD'; #my $filepath = '/home/cstinemetz/perl_programs/1.EVDOPCMD'; #my $outfile = 'output.txt'; open my $fh, '', $filepath or die ERROR opening $filepath: $!; #open my $out, '', $outfile or die ERROR opening $outfile: $!; my %sum; while ($fh){ next unless /;/; chomp; my @data = split /;/; my($cell,$sect,$chan,$carr,$rlp1,$rlp2,$rlp3,$rlp4,$dist,$precis) = @data[31,32,38,39,44,45,46,47,261,262]; $carr = ( $cell 299 $chan == 175 ) ? 2 : ( $chan == 1025 ) ? 2 : 1 ; #nested ternary operator $dist = sprintf %.1f, ( length( $dist ) 1 ) ? $dist/6.6/8/2*10/10 : 0 ; $sum{$cell}{$sect}{$carr}{$dist} += ($rlp1 + $rlp2 + $rlp3 + $rlp4) || 0 ; } my @data; for my $cell ( sort keys %sum ) { for my $sect ( sort keys %{$sum{$cell}} ) { for my $carr ( sort keys %{$sum{$cell}{$sect}} ) { for my $dist ( sort keys %{$sum{$cell}{$sect}{$carr}} ) { push( @data, [ $sum{$cell}{$sect}{$carr}{$dist}, $cell, $sect, $carr, $dist,]); } } } } for my $record ( sort { $a-[1]= $b-[1] || $a-[2]= $b-[2] || $a-[3]= $b-[3] || $a-[4]= $b-[4] } @data ) { my( $val, $cell, $sect, $carr, $dist ) = @$record; print $cell\t $sect\t $carr\t $dist\t $val\n; } Your error is because the $rlp variables can sometimes be empty strings as well as numeric values, in which case they should be skipped over. Also, since $carr is never used again after being extracted from $data[39], I would write things this way. my ($cell, $sect, $chan, $dist, $precis) = @data[31, 32, 38, 261, 262]; $dist = sprintf '%.1f', length $dist 1 ? $dist / 6.6 / 8 / 2*10 / 10 : 0; my $carr = ( $cell 299 $chan == 175 ) || $chan == 1025 ? 2 : 1; for my $i (44..47) { my $rlp = $data[$i]; $sum{$cell}{$sect}{$carr}{$dist} += $rlp if $rlp; } HTH, Rob -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
RE: foreach loop
Thanks Jim, I am still unable to sum up the field $rlptxat. The error I am getting is below: Scalar found where operator expected at ./jim.pl line 52, near $sum (Missing semicolon on previous line?) my variable %sum masks earlier declaration in same scope at ./jim.pl line 54. my variable %sum masks earlier declaration in same statement at ./jim.pl line 55. my variable $cell masks earlier declaration in same statement at ./jim.pl line 55. my variable %sum masks earlier declaration in same scope at ./jim.pl line 56. my variable $cell masks earlier declaration in same scope at ./jim.pl line 56. my variable $sect masks earlier declaration in same scope at ./jim.pl line 56. my variable %sum masks earlier declaration in same scope at ./jim.pl line 58. my variable $cell masks earlier declaration in same scope at ./jim.pl line 58. my variable $sect masks earlier declaration in same scope at ./jim.pl line 58. my variable $chan masks earlier declaration in same scope at ./jim.pl line 58. syntax error at ./jim.pl line 52, near $sum Global symbol %sum requires explicit package name at ./jim.pl line 52. Global symbol $cell requires explicit package name at ./jim.pl line 52. Global symbol $sect requires explicit package name at ./jim.pl line 52. Global symbol $chan requires explicit package name at ./jim.pl line 52. Global symbol $rlptxat requires explicit package name at ./jim.pl line 54. Execution of ./jim.pl aborted due to compilation errors. My code is as follows: #!/usr/bin/perl use warnings; use strict; my @records = (); while (DATA){ next unless /;/; chomp; my @data = split /;/; my($cell,$sect,$chan,$carr,$rlptxat1,$dist,$precis) = @data[31,32,38,39,44,261,262]; $carr = ( $chan == 75 ) ? 2 : ( $chan == 1025 ) ? 2 : 1 ; #nested ternary operator $dist = ( length( $dist ) 1 ) ? $dist/6.6/8/2*10/10 : '' ; push @records, { cell= $cell, sect= $sect, carr= $carr, chan= $chan, RTD = $dist, RLP1= $rlptxat1, Precis = $precis, }; } my @sorted = sort { $a-{cell} = $b-{cell} || $a-{sect} = $b-{sect} || $a-{carr} = $b-{carr} } @records ; my %sum $sum{$cell}{$sect}{$chan} += $rlptxat for my $cell ( sort keys %sum ) { for my $sect ( sort keys %{$sum{$cell}} ) { for my $chan ( sort keys %{$sum{$cell}{$sect}} ) { print Value of sum($cell,$sect,$chan) is . $sum{$cell}{$sect}{$chan} . \n; } } } __DATA__ PACE | EVDOPCMD | 33.0 | 101218 | 07 | 8;1023240136;1218;0;1;00a01a2bcdc7;0310003147702376;ac016d4a;;;5.6.128.8;0;43234169;43234349;;;1;1;1;;0;;19;5.6.128.22;172.30.151.5;304;3;304;3;15;175;15;175;15;175;1;1798;1251;0;0;2;19;20;1;1;1;0;128;5.6.128.8;;;301;5.6.128.8;;;8;304;31;43244037;;;1;18;43234169;01;;43234416;0;0;304;3;21;19;175;15;405;1;1;1;1;0;125;1|| 8;1023240137;1218;0;1;00a01db74ace;;ac0174ca;43243423;1678442111;5.6.128.8;1;0;;43242544;43244207;43243423;43243647;;;1000;1;1;;0;;19;5.6.128.26;;372;2;372;2;;43243012;0;43243562;15;175;15;175;15;175;1;5;48;19;20;49;50;;0;1;2;0;68;5.6.128.8;;;301;5.6.128.8;;;8;372;21;43244207;;;1;18;43243423;01;;43242544;0;0;372;2;21;19;175;15;177;3;1;0;0;0;68;1|43243753;0;0;372;2;21;19;175;15;177;3;1;1;1;0;71;1| 8;1023240138;1218;0;1;00a02017ccdb;0310003147833882;aca344d7;;;5.6.128.13;0;43234160;43234358;;;1;1;1;;0;;19;5.6.128.31;172.30.151.5;320;2;320;2;15;75;15;75;15;75;1;2162;1317;0;0;2;19;20;1;1;1;0;104;5.6.128.13;;;306;5.6.128.13;;;8;320;21;43244164;;;1;18;43234160;01;;43234404;0;0;320;2;21;19;75;15;279;6;1;1;1;0;64;1||
Re: foreach loop
On 3/23/11 Wed Mar 23, 2011 10:02 AM, Chris Stinemetz cstinem...@cricketcommunications.com scribbled: Thanks Jim, I am still unable to sum up the field $rlptxat. The error I am getting is below: Scalar found where operator expected at ./jim.pl line 52, near $sum (Missing semicolon on previous line?) my %sum The above line needs a semicolon. Please reduce the size of your posts. Maybe shorten the data by including fewer rows and columns. The concepts will still be the same. Thanks. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach loop
On Mon, Mar 21, 2011 at 01:46, Mike McClain m.d.mccl...@cox.net wrote: snip my @report = map $_-{cell}\t$_-{sect}\t$_-{carr}\t$_-{chan}\t$_-{dist}\n , @sorted; print @report ; This map will consume a lot of memory, better do it using a foreach loop. In what way will the use of map here use any more memory than a foreach loop? snip The problem is that map returns a list. That list will exist in memory as you copy it to @report. Just before the assignment is finished, you will be using twice the amount of memory you expect. Perl doesn't tend to return memory to the system, so, even though no variable is using it, the memory used to hold the list will still be held by perl. Happily, perl will reuse the memory, so, as long as it isn't huge, it normally isn't a big deal. -- 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/
Re: foreach loop
On 3/23/11 Wed Mar 23, 2011 10:02 AM, Chris Stinemetz cstinem...@cricketcommunications.com scribbled: In addition to the missing semicolon, the declaration of %sum must appear before it is used, i.e. before the while(DATA) loop. The line adding values of $rlptxat1 to the sum must appear inside the while loop, not after it. Run this program on your data: #!/usr/local/bin/perl use warnings; use strict; my %sum; while (DATA){ next unless /;/; chomp; my @data = split /;/; my($cell,$sect,$chan,$carr,$rlptxat1,$dist,$precis) = @data[31,32,38,39,44,261,262]; $sum{$cell}{$sect}{$chan} += $rlptxat1 || 0; } for my $cell ( sort keys %sum ) { for my $sect ( sort keys %{$sum{$cell}} ) { for my $chan ( sort keys %{$sum{$cell}{$sect}} ) { print Value of sum($cell,$sect,$chan) is . $sum{$cell}{$sect}{$chan} . \n; } } } -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
RE: foreach loop
That worked! Thanks Jim. Chris -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
RE: foreach loop
Jim, I have another question. How do I sort the results so it is from smallest to largest starting with $cell,$sect,$carr? Thanks again for all you help. I am gaining a much better understanding. This is what I got: #!/usr/bin/perl use warnings; use strict; #my $filepath = 'C:/temp/PCMD'; #my $filepath = 'C:/cygwin/home/cstinemetz/perl_programs/1.EVDOPCMD'; # my $outfile = 'output.txt'; #open my $fh, '', $filepath or die ERROR opening $filepath: $!; # open my $out, '', $outfile or die ERROR opening $outfile: $!; my %sum; #my @records = (); while (DATA){ next unless /;/; chomp; my @data = split /;/; my($cell,$sect,$chan,$carr,$rlptxat1,$rlptxat2,$rlptxat3,$rlptxat4,$dist,$precis) = @data[31,32,38,39,44,45,46,47,261,262]; $carr = ( $chan == 75 ) ? 2 : ( $chan == 1025 ) ? 2 : 1 ; #nested ternary operator $dist = ( length( $dist ) 1 ) ? $dist/6.6/8/2*10/10 : 0 ; $sum{$cell}{$sect}{$carr}{$dist} += $rlptxat1 += $rlptxat2 += $rlptxat3 += $rlptxat4 || 0 ; } for my $cell ( sort keys %sum ) { for my $sect ( sort keys %{$sum{$cell}} ) { for my $carr ( sort keys %{$sum{$cell}{$sect}} ) { for my $dist ( sort keys %{$sum{$cell}{$sect}{$carr}} ) { print $cell\t $sect\t $carr\t $dist\t . $sum{$cell}{$sect}{$carr}{$dist} . \n; } } } } And this is the current output: 10 2 1 0.710227272727273 439 100 1 1 0 469 100 2 1 0 3207 101 3 1 0 96 102 3 1 0 1623 107 1 1 0 48 109 2 1 0 49 11 2 1 0 48 110 3 1 0.681818181818182 49 114 3 1 0 48 121 2 1 2.78409090909091 3628 -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach loop
On 3/23/11 Wed Mar 23, 2011 12:49 PM, Chris Stinemetz cstinem...@cricketcommunications.com scribbled: Jim, I have another question. How do I sort the results so it is from smallest to largest starting with $cell,$sect,$carr? It is difficult to sort a multi-level, nested hash. I would transfer the values to an array-of-arrays and sort that: #!/usr/local/bin/perl use warnings; use strict; my %sum; while (DATA){ next unless /;/; chomp; my @data = split /;/; my($cell,$sect,$chan,$carr,$rlptxat1,$dist,$precis) = @data[31,32,38,39,44,261,262]; $sum{$cell}{$sect}{$chan} += $rlptxat1 || 0; } my @data; for my $cell ( sort keys %sum ) { for my $sect ( sort keys %{$sum{$cell}} ) { for my $chan ( sort keys %{$sum{$cell}{$sect}} ) { push( @data, [ $sum{$cell}{$sect}{$chan}, $cell, $sect, $chan ]); } } } for my $record ( sort { $a-[0] = $b-[0] } @data ) { my( $val, $cell, $sect, $chan ) = @$record; print The value of ($cell,$sect,$chan) is $val\n; } -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
RE: foreach loop
No, it doesn't. What is a rlptxat element? Where do they come from. rlptxat is just an element indexed at 44 that has a value, in which I would like to sum up, when it has the same elements cell sect and carr in the record. I hope this helps Thank you, Chris At 8:03 PM -0600 3/20/11, Chris Stinemetz wrote: Jim, Thanks for your feedback. I am actually trying to sum up all rlptxat elements that have the same cell, sect, and chan elements in the array. I hope this clarifies. No, it doesn't. What is a rlptxat element? Where do they come from. You can define a multiple-level hash with three nested keys (cell, sect, chan) to hold the sum of all elements with the same key values (a triple): my %sum; Find values of cell, sect, and chan: $cell = ? $sect = ? $chan = ? Add the value with these keys to the sum: $sum{$cell}{$sect}{$chan} += ? Iterate over the result: for my $cell ( sort keys %sum ) { for my $sect ( sort keys %{$sum{$cell}} ) { for my $chan ( sort keys %{$sum{$cell}{$sect}} ) { print Value of sum($cell,$sect,$chan) is $sum{$cell}{$sect}{$chan}\n; } } } Good luck! -- Jim Gibson j...@gibson.org -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach loop
On 3/22/11 Tue Mar 22, 2011 2:24 PM, Chris Stinemetz cstinem...@cricketcommunications.com scribbled: No, it doesn't. What is a rlptxat element? Where do they come from. rlptxat is just an element indexed at 44 that has a value, in which I would like to sum up, when it has the same elements cell sect and carr in the record. OK. With this information and that from previous posts, your requirements may be summaryized as follows: You have a file with one record per line, each line consisting of a number of fields. Within each record may be found values of cell, sect, carr, and rlptxat at fixed column positions (e.g. 44 for rlptxat). You with to sum up the values of the rlptxat field for all records having the same values of cell, sect, and carr. Correct? At 8:03 PM -0600 3/20/11, Chris Stinemetz wrote: Jim, Thanks for your feedback. I am actually trying to sum up all rlptxat elements that have the same cell, sect, and chan elements in the array. I hope this clarifies. No, it doesn't. What is a rlptxat element? Where do they come from. You can define a multiple-level hash with three nested keys (cell, sect, chan) to hold the sum of all elements with the same key values (a triple): my %sum; Find values of cell, sect, and chan: Let @record be the array containing the values from each row, as returned by the split function, for example. Then: my $cell = $record[?] # ? is column number for cell field my $sect = $record[?] # ? is column number for sect field my $chan = $record[?] # ? is column number for chan field my $rlptxat = $record[44]; Or more succintly: my( $cell, $sect, $chan, $rlptxat ) = @record[ ?, ?, ?, 44 ]; # ? as above Add the value with these keys to the sum: $sum{$cell}{$sect}{$chan} += $rlptxat Iterate over the result: for my $cell ( sort keys %sum ) { for my $sect ( sort keys %{$sum{$cell}} ) { for my $chan ( sort keys %{$sum{$cell}{$sect}} ) { print Value of sum($cell,$sect,$chan) is . $sum{$cell}{$sect}{$chan} . \n; } } } And you are done. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
RE: foreach loop
Jim, You hit it right on. This is exactly what I am trying to do. OK. With this information and that from previous posts, your requirements may be summaryized as follows: You have a file with one record per line, each line consisting of a number of fields. Within each record may be found values of cell, sect, carr, and rlptxat at fixed column positions (e.g. 44 for rlptxat). You with to sum up the values of the rlptxat field for all records having the same values of cell, sect, and carr. Correct? I took your advice but I am still unable to get the results I want. Below is what I have with your code added. I also changed it from $fh to DATA so you can get an idea of the input data and copy and paste it if you need to. Thanks for a all your help! Chris #!/usr/bin/perl use warnings; use strict; #my $filepath = 'C:/temp/PCMD'; #my $filepath = 'C:/cygwin/home/cstinemetz/perl_programs/1.EVDOPCMD'; #my $outfile = 'output.txt'; #open my $fh, '', $filepath or die ERROR opening $filepath: $!; #open my $out, '', $outfile or die ERROR opening $outfile: $!; my @records = (); while (DATA){ next unless /;/; chomp; my @data = split /;/; my($cell,$sect,$chan,$carr,$rlptxat,$dist,$precis) = @data[31,32,38,39,44,261,262]; # my %sum # $sum{$cell}{$sect}{$chan} += $rlptxat # for my $cell ( sort keys %sum ) { # for my $sect ( sort keys %{$sum{$cell}} ) { # for my $chan ( sort keys %{$sum{$cell}{$sect}} ) { # print Value of sum($cell,$sect,$chan) is . # $sum{$cell}{$sect}{$chan} . \n; # } # } # } $carr = ( $chan == 75 ) ? 2 : ( $chan == 1025 ) ? 2 : 1 ; #nested ternary operator $dist = ( length( $dist ) 1 ) ? $dist/6.6/8/2*10/10 : '' ; push @records, { cell = $cell, sect = $sect, carr = $carr, chan = $chan, RTD= $dist, Precis = $precis, }; } my @sorted = sort { $a-{cell} = $b-{cell} || $a-{sect} = $b-{sect} || $a-{carr} = $b-{carr} } @records ; for my $tuple ( @sorted ){ #print sprintf(%15s\t%10s\t%10s\n,$tuple-{cell}\t $tuple-{sect}\t $tuple-{carr}); print $tuple-{cell}\t $tuple-{sect}\t $tuple-{carr}\t $tuple-{chan}\t $tuple-{RTD}\n; } # for my $tuple ( @sorted ){ # print $out $tuple-{cell} $tuple-{sect} $tuple-{carr} $tuple-{RTD}\n; # } # close $out; __DATA__ PACE | EVDOPCMD | 33.0 | 101218 | 07 | 8;1023240136;1218;0;1;00a01a2bcdc7;0310003147702376;ac016d4a;;;5.6.128.8;0;43234169;43234349;;;1;1;1;;0;;19;5.6.128.22;172.30.151.5;304;3;304;3;15;175;15;175;15;175;1;1798;1251;0;0;2;19;20;1;1;1;0;128;5.6.128.8;;;301;5.6.128.8;;;8;304;31;43244037;;;1;18;43234169;01;;43234416;0;0;304;3;21;19;175;15;405;1;1;1;1;0;125;1|| 8;1023240137;1218;0;1;00a01db74ace;;ac0174ca;43243423;1678442111;5.6.128.8;1;0;;43242544;43244207;43243423;43243647;;;1000;1;1;;0;;19;5.6.128.26;;372;2;372;2;;43243012;0;43243562;15;175;15;175;15;175;1;5;48;19;20;49;50;;0;1;2;0;68;5.6.128.8;;;301;5.6.128.8;;;8;372;21;43244207;;;1;18;43243423;01;;43242544;0;0;372;2;21;19;175;15;177;3;1;0;0;0;68;1|43243753;0;0;372;2;21;19;175;15;177;3;1;1;1;0;71;1| 8;1023240138;1218;0;1;00a02017ccdb;0310003147833882;aca344d7;;;5.6.128.13;0;43234160;43234358;;;1;1;1;;0;;19;5.6.128.31;172.30.151.5;320;2;320;2;15;75;15;75;15;75;1;2162;1317;0;0;2;19;20;1;1;1;0;104;5.6.128.13;;;306;5.6.128.13;;;8;320;21;43244164;;;1;18;43234160;01;;43234404;0;0;320;2;21;19;75;15;279;6;1;1;1;0;64;1||
RE: foreach loop
At 9:58 PM -0600 3/22/11, Chris Stinemetz wrote: Jim, You hit it right on. This is exactly what I am trying to do. OK. With this information and that from previous posts, your requirements may be summaryized as follows: You have a file with one record per line, each line consisting of a number of fields. Within each record may be found values of cell, sect, carr, and rlptxat at fixed column positions (e.g. 44 for rlptxat). You with to sum up the values of the rlptxat field for all records having the same values of cell, sect, and carr. Correct? I took your advice but I am still unable to get the results I want. Below is what I have with your code added. I also changed it from $fh to DATA so you can get an idea of the input data and copy and paste it if you need to. But you commented out my code, and deleted the part that prints the results. Your code does not sum anything. You don't need to sort the records to produce a sum. Run your data through my code and see what you get. Then explain why it does not do what you want. -- Jim Gibson j...@gibson.org -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach loop
On Sun, Mar 20, 2011 at 10:06:25AM +0200, Shlomi Fish wrote: On Sunday 20 Mar 2011 05:43:38 Chris Stinemetz wrote: I am trying to code a foreach loop, that will add all occurrences of the element rlptxat that have the same elements cell, sect and chan. snip $record{dist}/6.6/8/2*10/10 : '' ; Chris take this much of this calculation '6.6/8/2*10/10' outside the loop and precalculate the constant portion then inside the loop only calculate $record{dist}*$your_constant my @report = map $_-{cell}\t$_-{sect}\t$_-{carr}\t$_-{chan}\t$_-{dist}\n , @sorted; print @report ; This map will consume a lot of memory, better do it using a foreach loop. In what way will the use of map here use any more memory than a foreach loop? Thanks, Mike -- Satisfied user of Linux since 1997. O ascii ribbon campaign - stop html mail - www.asciiribbon.org -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach loop
Hi Chris, On Sunday 20 Mar 2011 05:43:38 Chris Stinemetz wrote: I am trying to code a foreach loop, that will add all occurrences of the element rlptxat that have the same elements cell, sect and chan. My failed attempt can be located in between the ### lines. If I understand your code correctly, then you should somehow serialise those into the same hash key (possibly using Storable.pm/JSON/etc.). Don't use the old $my_hash{$key1, $key2, $key3} notation. You may also opt to construct a hash of hashes. Now a few other comments: Below is what I have so far. Thank you in advance, Chris #!/usr/bin/perl use warnings; use strict; use File::Slurp; my $filepath = 'C:/temp/PCMD'; my $output = 'output.txt'; You should add some empty lines here: http://perl-begin.org/tutorials/bad-elements/#paragraphs my %cols = ( cell= 31, sect= 32, chan= 38, dist= 261, precis = 262, rlptxat = 44, ); my @records; my @lines = read_file( $filepath ); chomp @lines; You should read the file line-by-line, using: $fh Not slurp it. foreach my $line ( @lines ) { next unless $line =~ /;/; my %record; # this gets just what you want into a hash using a hash slice and an # array slice. # the order of keys and values will be the same for any # given hash @record{ keys %cols } = (split /;/, $line)[ values %cols ]; $record{rlptxat} = ( length($record{rlptxat}) 1 ) ? $record{rlptxat}{cell, sect, chan, dist}++ : '' ; $record{carr} = ( $record{chan} == 75 ) ? 2 : ( $record{chan} == 1025 ) ? 2 : 1 ; #1; # Common carrier $record{dist} = ( length( $record{dist}) 1 ) ? $record{dist}/6.6/8/2*10/10 : '' ; push( @records, \%record ) ; } my @sorted = sort { $a-{cell} = $b-{cell} || $a-{sect} = $b-{sect} || $a-{carr} = $b-{carr} } @records ; my @report = map $_-{cell}\t$_-{sect}\t$_-{carr}\t$_-{chan}\t$_-{dist}\n , @sorted; print @report ; This map will consume a lot of memory, better do it using a foreach loop. Regards, Shlomi Fish write_file($output, @report) ; -- - Shlomi Fish http://www.shlomifish.org/ My Favourite FOSS - http://www.shlomifish.org/open-source/favourite/ You are banished! You are banished! You are banished! Hey! I'm just kidding! 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: foreach loop
SF == Shlomi Fish shlo...@iglu.org.il writes: my @records; my @lines = read_file( $filepath ); chomp @lines; SF You should read the file line-by-line, using: SF$fh SF Not slurp it. there is no reason to read it line by line. it is small enough to slurp. slurping is faster and generally cleaner than line by line. considering he was doing a poor version of slurping before, this is much better. print @report ; SF This map will consume a lot of memory, better do it using a foreach loop. again, not. his file isn't that large. given he wants to print to stdout and also a file, it is easier to build up the report one time and print twice. simple and also faster. uri -- Uri Guttman -- u...@stemsystems.com http://www.sysarch.com -- - Perl Code Review , Architecture, Development, Training, Support -- - Gourmet Hot Cocoa Mix http://bestfriendscocoa.com - -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
RE: foreach loop
So back to the question. How can I nest this foreach loop correctly to add all occurrences of the element rlptxat that have the same elements cell, sect and chan in the array? $record{rlptxat} = ( length($record{rlptxat}) 1 ) ? $record{rlptxat}{cell, sect, chan, dist}++ : '' ; Thank you very much. Chris #!/usr/bin/perl use warnings; use strict; use File::Slurp; my $filepath = 'C:/temp/PCMD'; my $output = 'output.txt'; my %cols = ( cell= 31, sect= 32, chan= 38, dist= 261, precis = 262, rlptxat = 44, ); my @records; my @lines = read_file( $filepath ); chomp @lines; foreach my $line ( @lines ) { next unless $line =~ /;/; my %record; # this gets just what you want into a hash using a hash slice and an array slice. # the order of keys and values will be the same for any # given hash @record{ keys %cols } = (split /;/, $line)[ values %cols ]; $record{rlptxat} = ( length($record{rlptxat}) 1 ) ? $record{rlptxat}{cell, sect, chan, dist}++ : '' ; $record{carr} = ( $record{chan} == 75 ) ? 2 : ( $record{chan} == 1025 ) ? 2 : 1 ; #1; # Common carrier $record{dist} = ( length( $record{dist}) 1 ) ? $record{dist}/6.6/8/2*10/10 : '' ; push( @records, \%record ) ; } my @sorted = sort { $a-{cell} = $b-{cell} || $a-{sect} = $b-{sect} || $a-{carr} = $b-{carr} } @records ; my @report = map $_-{cell}\t$_-{sect}\t$_-{carr}\t$_-{chan}\t$_-{dist}\n , @sorted; print @report ; write_file($output, @report) ; -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
RE: foreach loop
At 8:31 AM -0600 3/20/11, Chris Stinemetz wrote: So back to the question. How can I nest this foreach loop correctly to add all occurrences of the element rlptxat that have the same elements cell, sect and chan in the array? $record{rlptxat} = ( length($record{rlptxat}) 1 ) ? $record{rlptxat}{cell, sect, chan, dist}++ : '' ; That doesn't compile on my system under 'use strict:' because cell, sect, chan, dist are barewords, i.e. not variables or strings. They will look more like parameterless functions to the Perl interpreter. While they are allowed in some circumstances under 'strict', this is not one of them. You should make them explicitly strings, either as ('cell', 'sect', 'chan', 'dist') or as qw( cell sect chan dist) (note the absence of commas in the second version. Since you are assigning a hash slice, which has multiple values, you should use @record{...} instead of $record{...}, which is a single, scalar value: @record{rlptxat} = ( length($record{rlptxat}) 1 ) ? @record{rlptxat}{ qw(cell sect chan dist)}++ : '' ; However, it is not clear what you are trying to do. The rlptxat element is the 45th field on the input line. Are you trying to replace that element with a reference to a hash containing 4 elements from elsewhere in the line? Or are you trying to increment the values in those other 4 elements. Try writing multiple lines to do what you want. Don't try to stuff everything into one line until you know Perl better. If you write a bunch of lines to do something, people here will gladly tell you how you could have done it in fewer lines. -- Jim Gibson j...@gibson.org -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
RE: foreach loop
Jim, Thanks for your feedback. I am actually trying to sum up all rlptxat elements that have the same cell, sect, and chan elements in the array. I hope this clarifies. Thank you, Chris -Original Message- From: Jim Gibson [mailto:jimsgib...@gmail.com] Sent: Sunday, March 20, 2011 5:58 PM To: beginners@perl.org Subject: RE: foreach loop At 8:31 AM -0600 3/20/11, Chris Stinemetz wrote: So back to the question. How can I nest this foreach loop correctly to add all occurrences of the element rlptxat that have the same elements cell, sect and chan in the array? $record{rlptxat} = ( length($record{rlptxat}) 1 ) ? $record{rlptxat}{cell, sect, chan, dist}++ : '' ; That doesn't compile on my system under 'use strict:' because cell, sect, chan, dist are barewords, i.e. not variables or strings. They will look more like parameterless functions to the Perl interpreter. While they are allowed in some circumstances under 'strict', this is not one of them. You should make them explicitly strings, either as ('cell', 'sect', 'chan', 'dist') or as qw( cell sect chan dist) (note the absence of commas in the second version. Since you are assigning a hash slice, which has multiple values, you should use @record{...} instead of $record{...}, which is a single, scalar value: @record{rlptxat} = ( length($record{rlptxat}) 1 ) ? @record{rlptxat}{ qw(cell sect chan dist)}++ : '' ; However, it is not clear what you are trying to do. The rlptxat element is the 45th field on the input line. Are you trying to replace that element with a reference to a hash containing 4 elements from elsewhere in the line? Or are you trying to increment the values in those other 4 elements. Try writing multiple lines to do what you want. Don't try to stuff everything into one line until you know Perl better. If you write a bunch of lines to do something, people here will gladly tell you how you could have done it in fewer lines. -- Jim Gibson j...@gibson.org -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/ -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
RE: foreach loop
At 8:03 PM -0600 3/20/11, Chris Stinemetz wrote: Jim, Thanks for your feedback. I am actually trying to sum up all rlptxat elements that have the same cell, sect, and chan elements in the array. I hope this clarifies. No, it doesn't. What is a rlptxat element? Where do they come from. You can define a multiple-level hash with three nested keys (cell, sect, chan) to hold the sum of all elements with the same key values (a triple): my %sum; Find values of cell, sect, and chan: $cell = ? $sect = ? $chan = ? Add the value with these keys to the sum: $sum{$cell}{$sect}{$chan} += ? Iterate over the result: for my $cell ( sort keys %sum ) { for my $sect ( sort keys %{$sum{$cell}} ) { for my $chan ( sort keys %{$sum{$cell}{$sect}} ) { print Value of sum($cell,$sect,$chan) is $sum{$cell}{$sect}{$chan}\n; } } } Good luck! -- Jim Gibson j...@gibson.org -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: foreach loop
于 2011-3-21 13:33, Jim Gibson 写道: Iterate over the result: for my $cell ( sort keys %sum ) { for my $sect ( sort keys %{$sum{$cell}} ) { for my $chan ( sort keys %{$sum{$cell}{$sect}} ) { print Value of sum($cell,$sect,$chan) is $sum{$cell}{$sect}{$chan}\n; } } } And Data::Dumper could help you find out the complicated data structure. terry. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
foreach loop
I am trying to code a foreach loop, that will add all occurrences of the element rlptxat that have the same elements cell, sect and chan. My failed attempt can be located in between the ### lines. Below is what I have so far. Thank you in advance, Chris #!/usr/bin/perl use warnings; use strict; use File::Slurp; my $filepath = 'C:/temp/PCMD'; my $output = 'output.txt'; my %cols = ( cell= 31, sect= 32, chan= 38, dist= 261, precis = 262, rlptxat = 44, ); my @records; my @lines = read_file( $filepath ); chomp @lines; foreach my $line ( @lines ) { next unless $line =~ /;/; my %record; # this gets just what you want into a hash using a hash slice and an # array slice. # the order of keys and values will be the same for any # given hash @record{ keys %cols } = (split /;/, $line)[ values %cols ]; $record{rlptxat} = ( length($record{rlptxat}) 1 ) ? $record{rlptxat}{cell, sect, chan, dist}++ : '' ; $record{carr} = ( $record{chan} == 75 ) ? 2 : ( $record{chan} == 1025 ) ? 2 : 1 ; #1; # Common carrier $record{dist} = ( length( $record{dist}) 1 ) ? $record{dist}/6.6/8/2*10/10 : '' ; push( @records, \%record ) ; } my @sorted = sort { $a-{cell} = $b-{cell} || $a-{sect} = $b-{sect} || $a-{carr} = $b-{carr} } @records ; my @report = map $_-{cell}\t$_-{sect}\t$_-{carr}\t$_-{chan}\t$_-{dist}\n , @sorted; print @report ; write_file($output, @report) ; -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Problem with foreach loop
Hello list, Could someone please explain why this test script: my @arr1 = qw(one two three); my @arr2 = qw(1 2 3); foreach my $arr1 ( @arr1 ) { print Arr1: $arr1\n; foreach my $arr2 ( @arr2 ) { print Arr2: $arr2\n; if ( $arr2 eq '2' ) { shift @arr1; } } } produces that result: oracle:/opt/data/magna/wartung/work/nora ./test.pl Arr1: one Arr2: 1 Arr2: 2 Arr2: 3 Arr1: three Arr2: 1 Arr2: 2 Arr2: 3 whereas I had expected the output to be like this: oracle:/opt/data/magna/wartung/work/nora ./test.pl Arr1: one Arr2: 1 Arr2: 2 Arr2: 3 Arr1: two # why not? Arr2: 1 # why not? Arr2: 2 # why not? Arr1: three Arr2: 1 Arr2: 2 Arr2: 3 Thanks in advance! Regards, Nora
WG: Problem with foreach loop
Sorry, cp-accident... The proper result should be of course: oracle:/opt/data/magna/wartung/work/nora ./test.pl Arr1: one Arr2: 1 Arr2: 2 Arr1: two Arr2: 1 Arr2: 2 Arr1: three Arr2: 1 Arr2: 2 Regards, Nora -Ursprüngliche Nachricht- Von: HACKER Nora Gesendet: Montag, 27. September 2010 09:20 An: beginners@perl.org Betreff: Problem with foreach loop Hello list, Could someone please explain why this test script: my @arr1 = qw(one two three); my @arr2 = qw(1 2 3); foreach my $arr1 ( @arr1 ) { print Arr1: $arr1\n; foreach my $arr2 ( @arr2 ) { print Arr2: $arr2\n; if ( $arr2 eq '2' ) { shift @arr1; } } } produces that result: oracle:/opt/data/magna/wartung/work/nora ./test.pl Arr1: one Arr2: 1 Arr2: 2 Arr2: 3 Arr1: three Arr2: 1 Arr2: 2 Arr2: 3 whereas I had expected the output to be like this: oracle:/opt/data/magna/wartung/work/nora ./test.pl Arr1: one Arr2: 1 Arr2: 2 Arr2: 3 Arr1: two # why not? Arr2: 1 # why not? Arr2: 2 # why not? Arr1: three Arr2: 1 Arr2: 2 Arr2: 3 Thanks in advance! Regards, Nora -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Problem with foreach loop
Hi Nora, On Monday 27 September 2010 09:19:46 HACKER Nora wrote: Hello list, Could someone please explain why this test script: my @arr1 = qw(one two three); my @arr2 = qw(1 2 3); foreach my $arr1 ( @arr1 ) { print Arr1: $arr1\n; foreach my $arr2 ( @arr2 ) { print Arr2: $arr2\n; if ( $arr2 eq '2' ) { shift @arr1; You shouldn't modify an array (@arr1 in this case) while iterating over it using foreach. Otherwise, the results will be unpredictable. One option to overcome it is to do: [code] my @arr1_copy = @arr1; while (defined (my $arr1_elem = shift(@arr1_copy))) { # Do something with $arr1_elem } [/code] This will not work properly if @arr1 contains undef elements but it's relatively easy to fix: [code] while (@arr1_copy) { my $arr1_elem = shift; } [/code] Regards, Shlomi Fish -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
AW: Problem with foreach loop
Hi Michael, Thanks for your fast reply. I didn't realize that the shift is of immediate effect not only to the array but also to the current element of iteration in the loop itself. LG, Nora Von: Michael Newman [mailto:newman.michae...@gmail.com] Gesendet: Montag, 27. September 2010 09:34 An: HACKER Nora Betreff: Re: Problem with foreach loop When $arr2 eq '2', you shift 'one' off @arr1, but you're still working with$ arr[0], which is now 'two'. When the second foreach ends, it moves onto $arr1[1], which is 'three'. Also, if you want it to stop at '2', put a last; after you shift from @arr1. On Sep 27, 2010 3:22 AM, HACKER Nora nora.hac...@stgkk.at wrote: Hello list, Could someone please explain why this test script: my @arr1 = qw(one two three); my @arr2 = qw(1 2 3); foreach my $arr1 ( @arr1 ) { print Arr1: $arr1\n; foreach my $arr2 ( @arr2 ) { print Arr2: $arr2\n; if ( $arr2 eq '2' ) { shift @arr1; } } } produces that result: oracle:/opt/data/magna/wartung/work/nora ./test.pl Arr1: one Arr2: 1 Arr2: 2 Arr2: 3 Arr1: three Arr2: 1 Arr2: 2 Arr2: 3 whereas I had expected the output to be like this: oracle:/opt/data/magna/wartung/work/nora ./test.pl Arr1: one Arr2: 1 Arr2: 2 Arr2: 3 Arr1: two # why not? Arr2: 1 # why not? Arr2: 2 # why not? Arr1: three Arr2: 1 Arr2: 2 Arr2: 3 Thanks in advance! Regards, Nora
Re: Problem with foreach loop
On Mon, Sep 27, 2010 at 9:19 AM, HACKER Nora nora.hac...@stgkk.at wrote: Hello list, Could someone please explain why this test script: my @arr1 = qw(one two three); my @arr2 = qw(1 2 3); foreach my $arr1 ( @arr1 ) { print Arr1: $arr1\n; foreach my $arr2 ( @arr2 ) { print Arr2: $arr2\n; if ( $arr2 eq '2' ) { shift @arr1; } } } produces that result: oracle:/opt/data/magna/wartung/work/nora ./test.pl Arr1: one Arr2: 1 Arr2: 2 Arr2: 3 Arr1: three Arr2: 1 Arr2: 2 Arr2: 3 whereas I had expected the output to be like this: oracle:/opt/data/magna/wartung/work/nora ./test.pl Arr1: one Arr2: 1 Arr2: 2 Arr2: 3 Arr1: two # why not? Arr2: 1 # why not? Arr2: 2 # why not? Arr1: three Arr2: 1 Arr2: 2 Arr2: 3 Thanks in advance! Regards, Nora Ok, for starters your output is different from the above listed example. The actual output is: Arr1: one Arr2: 1 Arr2: 2 Arr1: two Arr2: 2 Arr1: three Arr2: 3 Which makes a lot of sense, you after all start you loop printing Arr1[0] then in that same loop you print Arr2[0] and Arr2[1] at which point you shift Arr2; and leave the inner loop, now you are at the end of your main loop so you print Arr[1] and again start a new inner loop printing Arr[0] (which thanks to your shift now is equal to 2 and because this is the case your if statement again shifts Arr2 and ends the inner loop, back in the main loop there is nothing more to do so we start the loop again this time printing Arr1[2] and we enter the inner loop printing Arr2[0] which now is 3 so the if statement never becomes true and we exit the inner loop, the main loop has come to the end of the array as well so we exit that and the code ends. There is nothing weird about what is happening here. I think that you are using a few different scripts to test different things and by now your output and your actual script do not match which causes most of the confusion. I found the best way to actually get your head around the most complex loops is to write/draw them out and get an actual picture of what is happening. If you look at most modelling technique this is exactly what they do, it is the best way for a humans brain to process what is going on. ;-) Anyway to get the result you want you should simply pop your second array when you encounter a 3 and in that case of course not print... foreach my $arr1 ( @arr1 ) { print Arr1: $arr1\n; foreach my $arr2 ( @arr2 ) { if ( $arr2 eq '3' ) { pop @arr2; } else { print Arr2: $arr2\n; } } } That will result in: Arr1: one Arr2: 1 Arr2: 2 Arr1: two Arr2: 1 Arr2: 2 Arr1: three Arr2: 1 Arr2: 2 Regards, Rob