Steps to Design
There are three fundamental steps you should perform when you have a program to write:
Define the output and data flows.
Develop the logic to get to that output.
Write the program.
Notice that writing the program is the last step in writing the program. This is not as silly as it sounds. Remember that physically building the house is the last stage of building the house; proper planning is critical before any actual building can start. You will find that writing and typing in the lines of a program is one of the easiest parts of the programming process. If your design is well thought out, the program practically writes itself; typing it in becomes almost an afterthought to the whole process.
Step 1: Define the Output and Data Flows
Before beginning a program, you must have a firm idea of what the program should produce and what data is needed to produce that output. Just as a builder must know what the house should look like before beginning to build it, a programmer must know what the output is going to be before writing the program. Anything that the program produces and the user sees is considered output that you must define. You must know what every screen in the program should look like and what will be on every page of every printed report.
Some programs are rather small, but without knowing where you’re heading, you might take longer to finish the program than you would if you first determined the output in detail. Suppose you wanted to add a Python-based program that allowed a small business to record and store customer contact information. To start, you should make a list of all fields that the program is to produce onscreen. You would not only list each field but also describe the fields. Table 3.1 details the fields on the program’s window.
TABLE 3.1 Fields that your contact management program might display
|Contacts||Scrolling list||Displays the list of contacts|
|Name||Text field||Holds contact’s name|
|Address||Text field||Holds contact’s address|
|City||Text field||Holds contact’s city|
|State||Text field||Holds contact’s state|
|Zip||Text field||Holds contact’s zip code|
|Home Phone #||Text field||Holds contact’s phone number|
|Cell Phone #||Text field||Holds contact’s mobile number|
|Text field||Holds contact’s email address|
|Stage||Fixed, scrolling list||Displays a list of possible stages this contact might reside in, such as being offered a special follow-up call or perhaps the initial contact|
|Notes||Text field||Miscellaneous notes about the contact, such as whether the contact has bought from the company before|
|Filter Contacts||Fixed, scrolling list||Enables the user to search for groups of contacts based on the stage the contacts are in so that the user can see a list of all contacts who have been sent a mailing|
|Edit||Function||Enables the user to modify an existing contact|
|Add||Function||Enables the user to add a new contact|
|Delete||Function||Enables the user to delete an existing contact|
Many of the fields you list in an output definition may be obvious. The field called Name obviously will hold and display a contact’s name. Being obvious is okay. Keep in mind that if you write programs for other people, as you often will do, you must get approval of your program’s parameters. One of the best ways to begin is to make a list of all the intended program’s fields and make sure that the user agrees that everything is there. Perhaps your client has specific interests, like wanting the Twitter handle of contacts as well. By communicating with your client, you will get a better idea of what you need to add to the program.
As you’ll see later this hour, in the section “Rapid Application Development,” you’ll be able to use programs to put together a model of the actual output screen that your users can see. With the model and with your list of fields, you have double verification that the program contains exactly what the user wants.
Input windows such as the Contacts program data-entry screen are part of your output definition. This may seem contradictory, but input screens require that your program place fields on the screen, and you should plan where these input fields must go.
The output definition is more than a preliminary output design. It gives you insight into what data elements the program should track, compute, and produce. Defining the output also helps you gather all the input you need to produce the output.
The output definition consists of many pages of details. You must be able to specify all the details of a problem before you know what output you need. Even command buttons and scrolling list boxes are output because the program will display these items.
In Hour 1, “Hands-On Programming,” you learned that data goes into a program, and the program outputs meaningful information. You should inventory all the data that goes into a program. If you’re using Python to make a customer contact program, you need to know what specific data the owners want to collect from the users. Define what each piece of data is. Perhaps the owners want to ask customers whether they want to submit a name and email address for the weekly sales email blast. Does the company want any additional data from the user, such as physical address, age, and income?
In Hour 4, “Getting Input and Displaying Output,” you’ll learn how to put these ideas into a program. You will learn how a program asks for data and produces information on the screen. This I/O (input/output) process is the most critical part of an application. You want to capture all data required and in an accurate way.
Something is still missing in all this design discussion. You understand the importance of gathering data. You understand the importance of knowing where you’re headed by designing the output. But how do you go from data to output? That’s the next step in the design process: You need to determine what processing will be required to produce the output from the input (data). You must be able to generate proper data flows and calculations so that your program manipulates that data and produces the correct output. The final sections of this hour discuss ways to develop the centerpiece—the logic for your programs.
All output screens, printed reports, and data-entry screens must be defined in advance so you know exactly what is required of your programs. You must also decide what data to keep in files and the format of your data files. As you progress in your programming education, you will learn ways to lay out data files in appropriate formats.
When capturing data, you want to gather data from users in a way that is reasonable, requires little time, and has prompts that request the data in a friendly and unobtrusive manner. Prototyping (discussed next) and rapid application development can help.
In the days of expensive hardware and costly computer usage time, the process of system design was, in some ways, more critical than it is today. The more time you spent designing your code, the smoother the costly hands-on programming became. This is far less true today because computers are inexpensive, and you have much more freedom to change your mind and add program options than before. Yet the first part of this hour was spent in great detail explaining why up-front design is critical.
The primary problem many new programmers have today is that they do absolutely no design work. That’s why many problems take place, such as the one mentioned earlier this hour about the company that wanted far more in its program than the programmer ever dreamed of.
Although the actual design of output, data, and even the logic in the body of the program itself is much simpler to work with, given the power and low cost of today’s computing tools, you still must maintain an eagle eye toward developing an initial design with agreed-upon output from your users. You must also know all the data that your program is to collect before you begin your coding. If you don’t, you will have a frustrating time as a contract programmer or as a corporate programmer because you’ll constantly be playing catch-up with what the users actually want and failed to tell you about.
One of the benefits of the Windows operating system is its visual nature. Before Windows, programming tools were limited to text-based design and implementation. Designing a user’s screen today means starting with a programming language such as Visual Basic, drawing the screen, and dragging to the screen objects that the user will interact with, such as an OK button. Therefore, you can quickly design prototype screens that you can send to the user. A prototype is a model, and a prototype screen models what the final program’s screen will look like. After the user sees the screens that he or she will interact with, the user will have a much better feel for whether you understand the needs of the program.
Many Windows programming languages, such as Visual C++ and Visual Basic, include prototyping tools. For comparison, Figure 3.1 shows the Visual Basic development screen. The language covered in these early chapters, Python, is more likely to help you behind the scenes, working with the data and analyzing it as needed. You can certainly perform input and output functions with Python, but if you are developing a Windows application, other languages are more appropriate, such as what you see in Figure 3.1. The screen looks rather busy, but the important things to look for are the Toolbox and the output design window. To place controls such as command buttons and text boxes on the form that serves as the output window, the programmer only has to drag that control from the Toolbox window to the form. So, to build a program’s output, the programmer only has to drag as many controls as needed to the form and does not have to write a single line of code in the meantime.
Figure 3.1 Program development systems such as Visual Basic provide tools that you can use to create output definitions visually.
Once you place controls on a form window with a programming tool such as Visual Basic, you can do more than show the form to your users. You actually can compile the form, just as you would a program, and let your user interact with the controls. When the user is able to work with the controls, even though nothing happens as a result, the user is better able to tell if you understand the goals of the program. The user often notices if there is a missing piece of the program and can also offer suggestions to make the program flow more easily from a user’s point of view.
Rapid Application Development
A more advanced program design tool used for defining output, data flows, and logic itself is called rapid application development, or RAD for short. RAD is the process of quickly placing controls on a form—not unlike you just saw done with Visual Basic—connecting those controls to data, and accessing pieces of prewritten code to put together a fully functional application without writing a single line of code. In a way, programming systems such as Visual Basic are fulfilling many goals of RAD. When you place controls on a form, as you’ll see done in far more detail in Hour 20, “Programming with Visual Basic 2012,” the Visual Basic system handles all the programming needed for that control. You don’t ever have to write anything to make a command button act like a command button should. Your only goal is to determine how many command buttons your program needs and where they are to go.
But these tools cannot read your mind. RAD tools do not know that, when the user clicks a certain button, a report is supposed to print. Programmers are still needed to connect all these things to each other and to data, and programmers are needed to write the detailed logic so that the program processes data correctly. Before these kinds of program development tools appeared, programmers had to write thousands of lines of code, often in the C programming language, just to produce a simple Windows program. At least now the controls and the interface are more rapidly developed. Perhaps someday a RAD tool will be sophisticated enough to develop the logic also. But in the meantime, don’t quit your day job if your day job is programming, because you’re still in demand.
Top-Down Program Design
For large projects, many programming staff members find that a top-down design helps them focus on what a program needs and helps them detail the logic required to produce the program’s results. Top-down design is the process of breaking down a problem into more and more detail until you finalize all the details. With top-down design, you produce the details needed to accomplish a programming task.
The problem with top-down design is that programmers tend not to use it. They tend to design from the opposite direction (called bottom-up design). When you ignore top-down design, you impose a heavy burden on yourself to remember every detail that will be needed; with top-down design, the details fall out on their own. You don’t have to worry about the petty details if you follow a strict top-down design because the process of top-down design takes care of producing the details.
Top-down design involves a three-step process:
Determine the overall goal.
Break that goal into two, three, or more detailed parts. Don’t add too many details, or you might leave things out.
Keep repeating steps 1 and 2—and put off the details as long as possible—until you cannot reasonably break down the problem any further.
You can learn about top-down design more easily by relating it to a common real-world problem before looking at a computer problem. Top-down design is not just for programming problems. Once you master top-down design, you can apply it to any part of your life that you must plan in detail. Perhaps the most detailed event that a person can plan is a wedding. Therefore, a wedding is the perfect place to see top-down design in action.
What is the first thing you must do to have a wedding? First, find a prospective spouse. (You’ll need a different book for help with that.) When it comes time to plan the wedding, the top-down design is the best way to approach the event. The way not to plan a wedding is to worry about the details first, yet this is the way most people plan a wedding. They start thinking about the dresses, the organist, the flowers, and the cake to serve at the reception. The biggest problem with trying to cover all these details from the beginning is that you lose sight of so much; it is too easy to forget a detail until it’s too late. The details of bottom-up design get in your way.
What is the overall goal of a wedding? Thinking in the most general terms possible, “Have a wedding” is about as general as it can get. If you were in charge of planning a wedding, the general goal of “Have a wedding” would put you right on target. Assume that “Have a wedding” is the highest-level goal.
Now that you know where you’re heading, begin by breaking down the overall goal into two or three details. For instance, what about the colors of the wedding, what about the guest list, what about paying the officiant...oops, too many details! The idea of top-down design is to put off the details for as long as possible. Don’t get in a hurry. When you find yourself breaking the current problem into more than three or four parts, you are rushing the top-down design. Put off the details. Basically, you can break down “Have a wedding” into the following two major components: the ceremony and the reception.
The next step of top-down design is to repeat the same process with the new components. The ceremony is made up of the people and the location. The reception includes the food, the people, and the location. The ceremony’s people include the guests, the wedding party, and the workers (officiant, organist, and so on—but those details come a little later).
Eventually, you will have several pages of details that cannot be broken down any further. For instance, you’ll probably end up with the details of the reception food, such as peanuts for snacking. (If you start out listing those details, however, you could forget many of them.)
Now move to a more computerized problem; assume that you are assigned the task of writing a payroll program for a company. What would that payroll program require? You could begin by listing the payroll program’s details, such as:
Print payroll checks.
Calculate federal taxes.
Calculate state taxes.
What is wrong with this approach? If you said that the details were coming too early, you are correct. The perfect place to start is at the top. The most general goal of a payroll program might be “Perform the payroll.” This overall goal keeps other details out of this program (no general ledger processing will be included, unless part of the payroll system updates a general ledger file) and keeps you focused on the problem at hand.
Consider Figure 3.2. This might be the first page of the payroll’s top-down design. Any payroll program has to include some mechanism for entering, deleting, and changing employee information such as address, city, state, zip code, number of exemptions, and so on. What other details about the employees do you need? At this point, don’t answer that question. The design is not ready for all those details.
Figure 3.2 The first page of the payroll program’s top-down design would include the highest level of details.
There is a long way to go before you finish with the payroll top-down design, but Figure 3.2 is the first step. You must keep breaking down each component until the details finally appear.
Only when you and the user gather all the necessary details through top-down design can you decide what is going to comprise those details.
Step 2: Develop the Logic
After you and the user agree to the goals and output of the program, the rest is up to you. Your job is to use that output definition to decide how to make a computer produce the output. You have broken down the overall problem into detailed instructions that the computer can carry out. This doesn’t mean you are ready to write the program—quite the contrary. You are now ready to develop the logic that produces that output.
The output definition goes a long way toward describing what the program is supposed to do. Now you must decide how to accomplish the job. You must order the details that you have so they operate in a time-ordered fashion. You must also decide which decisions your program must make and the actions produced by each of those decisions.
Throughout the rest of this 24-hour tutorial, you’ll learn the final two steps of developing programs. You will gain insight into how programmers write and test a program after developing the output definition and getting the user’s approval on the program’s specifications.
In the past, users would use tools such as flowcharts and pseudocode to develop program logic. A flowchart is shown in Figure 3.3. It is said that a picture is worth a thousand words, and the flowchart provides a pictorial representation of program logic. The flowchart doesn’t include all the program details but represents the general logic flow of the program. If your flowchart is correctly drawn, writing the actual program becomes a matter of rote. After the final program is completed, the flowchart can act as documentation for the program.
Flowcharts are made up of industry-standard symbols. Plastic flowchart symbol outlines, called flowchart templates, are still available at office supply stores to help you draw better-looking flowcharts instead of relying on freehand drawing. There are also some programs that guide you through the creation of a flowchart and enable you to print flowcharts on your printer.
Although some still use flowcharts today, RAD and other development tools have virtually eliminated flowcharts except for depicting isolated parts of a program’s logic for documentation purposes. Even in its heyday in the 1960s and 1970s, flowcharting did not completely catch on. Some companies preferred another method for logic description called pseudocode, sometimes called structured English, which involves writing logic using sentences of text instead of the diagrams used in flowcharting.
Pseudocode doesn’t have any programming language statements in it, but it also is not free-flowing English. It is a set of rigid English words that allow for the depiction of logic you see so often in flowcharts and programming languages. As with flowcharts, you can write pseudocode for anything, not just computer programs. A lot of instruction manuals use a form of pseudocode to illustrate the steps needed to assemble parts. Pseudocode offers a rigid description of logic that tries to leave little room for ambiguity.
Figure 3.3 The flowchart depicts the payroll program’s logic graphically.
Here is the logic for the payroll problem in pseudocode form. Notice that you can read the text, yet it is not a programming language. The indention helps keep track of which sentences go together. The pseudocode is readable by anyone, even by people unfamiliar with flowcharting symbols:
For each employee: If the employee worked 0 to 40 hours then net pay equals hours worked times rate. Otherwise, if the employee worked between 40 and 50 hours then net pay equals 40 times the rate; add to that (hours worked -40) times the rate times 1.5. Otherwise, net pay equals 40 times the rate; add to that 10 times the rate times 1.5; add to that (hours worked -50) times twice the rate. Deduct taxes from the net pay. Print the paycheck.
Step 3: Writing the Code
The program writing takes the longest to learn. After you learn to program, however, the actual programming process takes less time than the design if your design is accurate and complete. The nature of programming requires that you learn some new skills. The next few hourly lessons will teach you a lot about programming languages and will help train you to become a better coder so that your programs will not only achieve the goals they are supposed to achieve but also will be simple to maintain.