Re: Looping made easy...
by halley (Prior) on Jul 22, 2003 at 16:55 UTC
|
Computer Science 101
Every loop has three features, and three features make any loop.
An initial condition. If you have a control variable, initialize it to a known value. If you have a data set you're working from, it should be populated and ready for processing. If you want a stream of data to be input, open the stream.
A test for a terminating condition. If you're using a control variable, check to see if it has reached or exceeded the final predicted value. If you have a data set or data stream, check if there are no more elements available. If so, terminate the loop.
A body of work. Unless magic were to somehow intrude, or your problem didn't require a loop in the first place, you will change the condition somehow. You will make progress. Any realized progress, in physics or code, is called 'work.' The control variable must be incremented. The current position in a data set (or the size of the remaining portion of the data set) must be moved forward. The data stream must be consumed. If none of these are done, you have an infinite loop, because your initial condition never changes to meet or exceed the desired termination conditions.
Separate from that primer, what does your input data look like, and what were you expecting for a result? We can't debug code in isolation, we can only explain the failure to reach the desired results and offer suggestions to achieve better results.
-- [ e d @ h a l l e y . c c ] | [reply] |
Re: Looping made easy...
by thelenm (Vicar) on Jul 22, 2003 at 17:06 UTC
|
A couple of comments on the specific code example you
posted, hopefully they will be helpful to you...
If I'm going to be doing something a specific number of
times, or if I need a loop counter, I often write a for
loop over a range, rather than a while loop.
For example, for my $i (0..89) instead of
my $i=0; while ($i <= 89) { ... ++$i }. I find
that this greatly simplifies things and makes the code's
purpose readable and clear (except that 89 is still a magic
number - why 89?).
Variables should have the smallest scope possible. So
instead of using $a, etc. as globals and then
resetting their values at the top of the loop, just declare
them as lexical variables. For example, my ($a, $b, $c, $d);
instead of $a=''; $b=''; etc. Of course, it
goes without saying that you should probably have better
variable names that indicate what they are actually used for.
And $a and $b are special variables
used by Perl's sort routine, so you should
avoid those specific variable names unless you know exactly
why you are using them.
You can avoid having named variables if you are just
going to throw away what gets assigned to them. You don't
seem to be using $a, $c, $d, or $i,
so you can get away without declaring them at all.
$stuff[89..93] probably doesn't do what you
expect. It will return the first element of @stuff.
My guess is that maybe you're trying to take elements 89, 90, 91, 92
of @stuff and assign them to ($a, $b, $c, $d).
Is that right?
Taking into account what I've said, here's how I might
rewrite your loop (by the way, what are you trying to do
with this loop?):
my @fields;
for (0..89) {
my $field = $stuff[90];
print $field;
push @fields, "$field\t";
}
Ta da! A loop that's easy to follow (but not very useful,
it would seem...) Was that at all helpful?
-- Mike
--
XML::Simpler does not require XML::Parser or a SAX parser.
It does require File::Slurp.
-- grantm, perldoc XML::Simpler | [reply] [d/l] [select] |
Re: Looping made easy...
by bobn (Chaplain) on Jul 22, 2003 at 17:03 UTC
|
Your code has baffled me. What is this meant to do? We might be able to answer your questions better. Issues:
-
You test $i, you incremnt $i, but you never actually use $i.
- ($a, $b, $c, $d) = split(/[\t]/, $stuff[89..93]); should probably be: ($a, $b, $c, $d) = split(/[\t]/, @stuff[89..93]); - except if you want the 90th through 94th values of @stuff put into the four variables ($a, $b, $c, $d), you don't need the split, and you only need to do it once.
-
Whatever that line of code does, it does it 90 times (for $i = (0..89)) - is this what you wanted?
Give us a small piece of real code and tell us what you wanted it to do and we might be able to help. As it stands, I personalkly can olnly say: perldoc perlsyn .
--Bob Niederman, http://bob-n.com
| [reply] [d/l] [select] |
Re: Looping made easy...
by derby (Abbot) on Jul 22, 2003 at 17:15 UTC
|
I'm starting to sound like a squeaky wheel but please check out Effective Perl Programming
(especially item 12). There's no reason for anyone to not have read what is
one of the best books on perl. It's informative, it will help you not get lost and it's available online for free (but it's definetly worth the money
so don't be cheap - buy it).
There's getting to be a unique subculture here. I've been noticing more and more bioinformatic questions and while I applaud and appreciate the magnitude of their endeavours (and their use of perl), I'm starting to question how much
emphasis is placed on the informatic part of their studies.
I know I for one would hate spending most of the night pouring over chem and biology texts only to then be confronted by some of the horrid comp sci texts that are out there especially if you have a prof that's more interested in using his/her self-published works. So please if your into bioinformatics and you only have room for one perl book - please make it Effective Perl Programming.
-derby | [reply] |
|
|
Actually, it depends on where one is studying. I know that at UCI, there are many individuals who are very good programmers and geneticists at the same time. I don't represent the subculture by any means, as I've just finished my undergrad and, through an internship, am now learning about a whole new field of science. Perl is my first computer language I've learned (discluding BASIC from my apple 2e days as a child), so much of this is still very new for me. Having been exposed to some of the graduate students here, I think you will find them to be quite proficient at what they do; I wish I were only half as good:-).
PS-I've got access to far more than one book on Perl. And yes, this was probably one of my more stupid questions on the forum, but sometimes these things clear up misconceptions in my mind, as the previous answers already have. TO ALL: You have my sincere thanks for your help! Hopefully I'll have more eloquent and advanced questions in the future...
| [reply] |
|
|
bioinformatics,
By subculture, I meant here on perlmonks we're getting a lot of beginner questions centered around
bioinformatics where traditionally most of our beginner questions have been
from web developers.
Please don't think I was directing my remarks directly at you. I'm sure your perl and programming skills are much better than my bio skills. I was just
curious as to how much informatics was being combined with the bio part. You've set me straight and for that I thank you.
So please continue to ask any questions you have but really take a look at
that book. It will help you understand idiomatic perl better.
-derby
| [reply] |
Re: Looping made easy...
by sgifford (Prior) on Jul 22, 2003 at 17:36 UTC
|
Perhaps one of the problems you're running into is variable scope. If you use the global variable $i for all of your loop counters, they'll end up stepping all over each other if one loop calls another, since they're sharing a counter variable. If you localize your counter variables with my, each loop will have a copy of its own (even if they all happen to have the same name). For example, your loop could be written as:
for(my $i=0;$i<=89;$i++) { ... }
or
foreach my $i (0..89) { ... }
| [reply] [d/l] [select] |
Re: Looping made easy...
by flounder99 (Friar) on Jul 22, 2003 at 18:02 UTC
|
Why loop? All you need is two lines of code to do what you want.
push @b,($stuff[90]."\t")x90;
print @b[-90..-1];
update -- Actually to get all the side effects you need three lines of code.
($a,$b,$c,$d, $i)= ('',$stuff[90]."\t",'','',90);
push @b,($b)x90;
print @b[-90..-1];
-- flounder | [reply] [d/l] [select] |
Re: Looping made easy...
by eric256 (Parson) on Jul 22, 2003 at 17:05 UTC
|
I'm not entirely sure what your question was, but it does appear that a C style loop is more what you are looking for in that case.
for (my $i = 0; $i <= 89; $i++) {
...
}
Also i was noticeing that your code is going to return the same parts of $stuff over and over. What are you trying to do?
Eric Hodges | [reply] [d/l] |