I am writing this blog entry to talk to all the programmers out there, who post regularly post on the board, who are in the industry, who are new or who are experienced… code organization is key to a great looking program and to help reduce your debugging troubles. Often times I sit on the Dream.In.Code web board helping out when I am suddenly hit with a post that is so sloppy and messy there is no wonder the person is having trouble with it. So in this entry we will cover a few good tips for controlling the spacing and layout of the program in general to help you help yourself… right here on the Programming Underground!
New programmers especially like to write all their statements together in a clumped mess as if they are trying to fit all their code on one page of notebook paper. Lets debunk that myth… computer editors are much bigger than notebook paper (yes I know it is shocking!). It is ok to write out your lines with a little spacing to increase readability. The flip side of this are the newbies who put too much space between lines. While you have endless space, you want to keep the lines close enough together so that they make sense.
Now every programmer has their own style for spacing, indentation, and organization of code, but typically all the great programs out there have some sort of standardization in format and when looked at by other programmers they see the “elegance”. What do they mean by code elegance? They look at the code and it is nicely laid out in such a way that it is easy to read, lines are quickly associated with other lines that make logical sense, and solutions are self contained in logical functions and classes. So readable in fact that they just make sense as to what the code is doing.
The first thing I like to do when tackling a problem on the board is organize the code a bit. Add the proper indentations and add spaces to break statements apart. Once I can see how things are organized I typically can see where things like braces mismatching, parenthesis are missing etc. Lets take a look at what I mean…
Here is a recent question on the board in PHP (yes I know it has some bugs like missing quotes etc… we are not here to debug per say, just organize it to make it easier to debug) …
<?php $db = "testdb.txt"; $form = "<form method=\"post\" action=\"test.php\"> Entry Number; <input name=\"entry\" type=\"text\" size=\"20\"> <input name=\"submit\" type=\"submit\" value=\"submit\"> </form>"; $entry_num = $_POST["entry"]; $entry_to_write = "<br>It's entry number $entry_num."; if($_POST["submit"] == submit) { $f_handle = fopen($db, 'a'); fwrite($f_handle,$entry_num."\n"); fclose($f_handle); echo "<b>Entry Entered into system</b>"; $file = file("testdb.txt"); array_reverse($file); foreach($file as $line) echo "$line<br>"; } else { echo $form; } ?>
As you can see we have several lines there all jumbled together into a mass of I don’t know what. We appear to have some if statements and a loop, but where those individual items start and end is a bit confusing at first glance. Lets take this example and introduce some basic rules…
1) Put a blank line before and after loops and whole control statements
2) Put a space after control statement keywords like “if, else if, foreach, while, and for”
3) Indent whenever inside curly braces (and even if a statement has one line and curly braces are not needed, use them anyways! You never know when someone may add on to the loop or control statement later.)
4) Separate chunks of variable declarations from other statements and try to put variable declarations in the general vicinity of the statements that use them.
So lets apply rule number 1 to our code…
<?php $db = "testdb.txt"; $form = "<form method=\"post\" action=\"test.php\"> Entry Number; <input name=\"entry\" type=\"text\" size=\"20\"> <input name=\"submit\" type=\"submit\" value=\"submit\"> </form>"; $entry_num = $_POST["entry"]; $entry_to_write = "<br>It's entry number $entry_num."; if($_POST["submit"] == submit) { $f_handle = fopen($db, 'a'); fwrite($f_handle,$entry_num."\n"); fclose($f_handle); echo "<b>Entry Entered into system</b>"; $file = file("testdb.txt"); array_reverse($file); foreach($file as $line) echo "$line<br>"; } else { echo $form; } ?>
Did you notice the difference? We put a blank line before and after the foreach statement. It is minor in this case, but in some other cases you can add anywhere from 10-50 lines throughout the length of the program. Now lets go to step 2 and add spaces before our control statement keywords…
<?php $db = "testdb.txt"; $form = "<form method=\"post\" action=\"test.php\"> Entry Number; <input name=\"entry\" type=\"text\" size=\"20\"> <input name=\"submit\" type=\"submit\" value=\"submit\"> </form>"; $entry_num = $_POST["entry"]; $entry_to_write = "<br>It's entry number $entry_num."; if ($_POST["submit"] == submit) { $f_handle = fopen($db, 'a'); fwrite($f_handle,$entry_num."\n"); fclose($f_handle); echo "<b>Entry Entered into system</b>"; $file = file("testdb.txt"); array_reverse($file); foreach ($file as $line) echo "$line<br>"; } else { echo $form; } ?>
Again the change is minor. Minor changes is what we are after here. The process of adding the white space is not a huge one, but again on bigger functions it is a bit more of a chore. In the example above we added a space after the keyword “if” and the keyword “foreach”. Some programmers like to smash their left parenthesis against the keyword as a matter of style, but when you want to draw a bit more attention to the loop, the extra space is the difference between “Thenwe” and “Then we” making sense in the sentence “Then we went to step 3 of our rules, adding indentation.”
Adding indentation is usually the most crucial of the steps I have mentioned. Since it really makes the eye of the reader follow along in a logical fashion we can see what statements belong to what control flow statements. You can see which statements are in a loop and which are not etc. This process is going to be the step where you will typically find out if you have a curly brace mismatch because as you indent, you start looking for the end of a function or an if statement and realize there isn’t one.
<?php $db = "testdb.txt"; $form = "<form method=\"post\" action=\"test.php\"> Entry Number; <input name=\"entry\" type=\"text\" size=\"20\"> <input name=\"submit\" type=\"submit\" value=\"submit\"> </form>"; $entry_num = $_POST["entry"]; $entry_to_write = "<br>It's entry number $entry_num."; if ($_POST["submit"] == submit) { $f_handle = fopen($db, 'a'); fwrite($f_handle,$entry_num."\n"); fclose($f_handle); echo "<b>Entry Entered into system</b>"; $file = file("testdb.txt"); array_reverse($file); foreach ($file as $line) echo "$line<br>"; } else { echo $form; } ?>
In the example above you see we added some indentation to just about every line and we start to see the code fitting a structure. We also quickly notice that the line that reads echo “$line
“; actually belongs to the foreach loop and that the foreach loop has no start or end curly braces (in the earlier examples it looked like the curly brace for the ending of the if statement might have belonged to the foreach statement.
Now we see where we would put some code if we wanted to add it to the program. If I want to write something like an introduction statement into this code, I can see that if I go to the else clause of the if statement there, I could easily put the line right above the echo $form line.
While we are on this step, lets go ahead and add in the opening and closing curly braces for the foreach statement even though it does not need it… because it is one line. Someone in the future might want to add more code to this loop and we will save them time and increase readability by just putting them in to begin with.
<?php $db = "testdb.txt"; $form = "<form method=\"post\" action=\"test.php\"> Entry Number; <input name=\"entry\" type=\"text\" size=\"20\"> <input name=\"submit\" type=\"submit\" value=\"submit\"> </form>"; $entry_num = $_POST["entry"]; $entry_to_write = "<br>It's entry number $entry_num."; if ($_POST["submit"] == submit) { $f_handle = fopen($db, 'a'); fwrite($f_handle,$entry_num."\n"); fclose($f_handle); echo "<b>Entry Entered into system</b>"; $file = file("testdb.txt"); array_reverse($file); foreach ($file as $line) { echo "$line<br>"; } } else { echo $form; } ?>
Now the last step is to start grouping similar statements together, like variable declarations, function calls or statements. We can start by inserting some lines between setting $f_handle and function calls that are right after it.
<?php $db = "testdb.txt"; $form = "<form method=\"post\" action=\"test.php\"> Entry Number; <input name=\"entry\" type=\"text\" size=\"20\"> <input name=\"submit\" type=\"submit\" value=\"submit\"> </form>"; $entry_num = $_POST["entry"]; $entry_to_write = "<br>It's entry number $entry_num."; if ($_POST["submit"] == submit) { $f_handle = fopen($db, 'a'); fwrite($f_handle,$entry_num."\n"); fclose($f_handle); echo "<b>Entry Entered into system</b>"; $file = file("testdb.txt"); array_reverse($file); foreach ($file as $line) { echo "$line<br>"; } } else { echo $form; } ?>
Once we complete this step we will see that statements start to form their own little “cliques” that are related or work together. At this point we can often see what statements don’t seem to fit with others, where ordering might matter, and we can see the logical progression of the code. It also shows you perfect places where you might want to consider putting in some comments (like right before the declaration for $entry_num, the if statement, the array_reverse call, and the foreach loop).
Now we are at the point where we can actually read what is going on and start finding the bugs and or problems. The program has expanded about 4 or 5 lines in total and over large functions this might lead to the introduction of 20+ lines of whitespace, but as long as functions stay roughly a screen full or less, it is usually not a problem to work with.
Whitespace like anything else can be used as a tool to find your way through the code. When you are beating your head against the wall with a problem (or especially a syntax error) try taking a break and make the code “look pretty” with some white space. Usually you stumble across the syntax error as you do that or you hit the eureka moment and solve your own problem. It will also cut down your time trying to decipher what exactly you were doing yesterday or last week and the quicker you can get climatized to your code, the quicker you can begin coding new stuff again.
Thanks!