Lost in the loops
April 25, 2013 2:34 PM   Subscribe

Programming question: I'm looking for recommendations for some kind of visualization tool to help me stay organized within complex nested loops and if statements.

This may be a noob question, even though I'm not really a noob. My biggest problem writing code is that I get lost when writing nested loops and if statements, and in turn, my logic gets all confused. So it takes a really long time for me to put together something relatively simple. Tabbing, code folding, prolific commenting..nothing seems to help me. It's like I'm trying to produce something multidimensional in all linear terms, and I just wind up getting confused. Do I just need to think about it in different terms? Help!
posted by Cat Pie Hurts to Computers & Internet (12 answers total) 5 users marked this as a favorite
 
Do I just need to think about it in different terms?

Yes. If something's getting too rats-nest-y, you need to rethink how you're solving the problem.

Getting too deep with nested loops is a warning flag, just like making too long of a sub/method/function.

Break things out into different subs/functions/methods, normalize the data you're working with, draw out what you're trying to do on something a little more plastic (piece of paper, pencil), and just step back, and figure it out a better way.

You, or someone that has to work with your code will not want to slit your throat, in 6 months.

I'm thinking a visualization tool is only going to help you go, "whoa - it's not my imagination, this IS too complex!"

And also, you'll get better at visualizing what you're doing. You ARE writing something linearly, but unless you're working in like a shell language, or aren't using functions at all (and even then), no code is being run top-down.
posted by alex_skazat at 2:44 PM on April 25, 2013 [5 favorites]


Good programming practice is to reduce the number of nested loops and if statements you end up with for exactly this reason.

I recommend reading Clean Code by Uncle Bob Martin, it is the bible when it comes to writing maintainable, readable code!
posted by Wysawyg at 2:46 PM on April 25, 2013 [2 favorites]


Another tack is to use abstraction to shield yourself from the mechanics of the loops and the iteration--If you can invent a higher level name for a a series of operations, you can reduce the number of details you need to keep in your head at one time.

I often find this useful--instead of writing one big guess-plaintext function with nested loops and dictionaries, I write a guess-next-byte function that abstracts away some levels of logic and call that from guess-plaintext. Going through the exercise of separating the logic into new functions and determining what the inputs and outputs will be helps with the abstraction process.

"Civilization advances by extending the number of important operations which we can perform without thinking about them."
posted by jjwiseman at 3:25 PM on April 25, 2013


One thing I tend to do is use conditionals to break out of blocks instead of nesting. For example, instead of this:

for(i=0;i>j;i++)
{
    if(condition){
        if(othercondition){
            if(thirdcondition){
                //some code
            }
        }
    }
}

I will do this

for(i=0;i>j;i++)
{
    // Break if condition is not met
    if(!condition){
        break;
    }

    // Break if other condition is not met
    if(!othercondition){
        break;
    }

    // Break if third condition is not met
    if(!thirdcondition){
        break;
    }

     // some code
}
posted by Nothing at 3:47 PM on April 25, 2013 [2 favorites]


You have the 'Arrow Anti-Pattern', which is a code smell. Jeff has some useful ideas.
posted by j_curiouser at 4:30 PM on April 25, 2013 [2 favorites]


Ha I wrote something very similar to Nothing, but had an attack of Doubt so I didn't post it.

But seeing as I'm not alone, I will ! :

There are some really terrible anti-patterns that you must avoid, for example this one (I'm sure it must have a name).
file1 = open( "file1" );
if( file1 )
{
      file2 = open("file2");
      if( file2 )
      {
            frobbed = frobit( quux );
            if( frobbed )
            {
                 DoWhateverItWas(file1,file2,frobbed);
            }
            else
            {
                  error("couldn't frob");
            }
     }
     else
     {
            error( "couldn't open file.. uh 2 I think");
     }
}
else
{
    error("couldn't, um, was it open file... i?");
}
Much better to avoid all the nesting by stopping early when something goes wrong e.g.:
file1 = open( "file1" );
if( ! file1 )
{
    error("Couldn't open file 1");
    return false;
}

file2 = open("file2");
if( ! file2 )
{
    error("Couldn't open file 2");
    return false;
}

frobbed = frobit( quux );
if( ! frobbed )
{
    error("Couldn't frob it");
    return false;
}


DoWhateverItWas(file1,file2,frobbed);
The old old rule of thumb about fitting a function all on 2 screens at once is a good one, but you have to limit yourself a little now that we have higher resolutions - "if it doesn't fit in 80 lines and 80 columns then some of it should be in seperate functions" isn't as snappy.

On preview I see it does have a name, thank you j_curiouser.
posted by samj at 4:33 PM on April 25, 2013


Do you have an example (pseudo code or problem statement would be fine) of what's currently giving you trouble?
posted by Metasyntactic at 5:05 PM on April 25, 2013


One of the best suggestions I ever heard was to put a comment before any loop, explaining exactly what that loop was doing and why. It's been invaluable.
posted by asterix at 5:15 PM on April 25, 2013 [1 favorite]


I learned to program (casually) back when whitespace was free. I ruthlessly nest all loops with liberal tabspace. Not just because it fits into my German nature for orderliness, but because it helps me see what's going on.

And yeah, if you are using a language with functions, use them to keep things clear. I'm pretty sure compilers don't see a difference anymore. I think the rule when I was doing it was more than a few statements should go into a function. The main() function should be as simple and stupid as possible.

And use select/case/choose statements instead of complicated IF statements. Or a master select, with sub IF statements.

If your logic isn't right, go back to the literal drawing board and make a flowchart. If making a flowchart seems hard, then you don't know how to solve the problem, you are just hoping something ends up working.
posted by gjc at 6:42 PM on April 25, 2013


Yes - if your code is so nested that you are getting confused, then use one of the strategies laid out above to reduce the nesting. Also, in loops, make sure that you use indices that have descriptive names, for instance use 'rowIndex' instead of 'i'.
posted by nightwood at 8:02 PM on April 25, 2013


Also, try to think in terms of preconditions, post-conditions, and invariants. Often, code with very complicated control flow can be understandable if at any point the state of the world can be described by a small number of simple statements. So, for example, it doesn't matter if there are seventeen different ways to make i non-negative; if you can always assert that during these three lines, i will be non-negative, then your code will feel simple.
posted by d. z. wang at 9:08 PM on April 25, 2013


Yeah, what everyone says -- break it into smaller pieces. If/elseif/else isn't so bad, but if you find you want multiple elseif's, consider a case/switch statement, or see if you can rethink things and put some of the logic into subroutines (and what you're shooting for is for each of those to be short, discrete, and easy-to-understand.)

Make sure you understand what the language offers in terms of different ways to escape the loop -- 'next' or 'last' statements in some languages. And understand your language's exception mechanism (which most modern languages have); if your logic is getting bogged down with error-checking and what to do if there is one, exceptions might help simplify it.
posted by Zed at 10:09 AM on April 26, 2013


« Older Romance novel suggestions, similar to Danielle...   |   What do you think of these work benefits? And tips... Newer »
This thread is closed to new comments.