you just read through them like anything else...you handle the first one first...so..let's assume width is 4.
we reach line 2, and set i to 1. We check and find that i is less than width, so we enter the body of the loop.
the first thing we do in this loop is...start a new loop. so we set j to 1. we check to see if j is <= i, which it is (both are 1). so we enter this loop.
we are now on line 6. and we basically set the string to "[ ]" (since it was an empty string).
NOTE: the inner loop does not have any curly brackets, so there is only one line in the body. The indentation doesn't necessarily tell you that. If line 7 were indented, it would still not be part of the inner loop. This is one reason to ALWAYS use brackets, even when your body only has one line.
we have finished the inner loop, so, we increment j to 2. Test j <= i, which fails, so we exit the inner loop, and proceed with the next thing in the outer loop.
that gets us to line 7, so we put a newline on the end of our string.
we now exit the body of the outer loop, so we increment i to 2. i <= width is true, so we execute the body of the outer loop.
The first thing we do is execute a new loop. Note that this iteration of the loop on line 5 has NO IDEA it was ever executed before. it's starting over. So, set j to 1, test j <= i (true), append "[ ]" to the string, which now contains "[ ]/n[ ]".
increment j to 2, which IS <= i, so we add another "[ ]". j becomes 3, exiting the inner loop, and we append "\n" to the string.
and you just keep going like that.
There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors