Thursday, 28 January 2010

Program Structure

One of the best things about the basic programming language is that it is easy to get started  and  requires very little in the way of method to write and run simple programs. Once a budding programmer gets to grips with commands INPUTS, PRINT, DO LOOP, IF THEN, variables and so on even fairly complex programming tasks can be achieved with success. However their comes a time in every unstructured programmers life when he or she wishes that there was a more sensible way of doing things. Originally basic used line numbers, GOTO's and GOSUBS to jump from one part of the program to another. This was called spaghetti coding and required the memory of an elephant to remember what everything was doing. The line IF X = 1 THEN  GOTO  1000 is not very descriptive and because of this, Procedures were introduced to guide or even force programmers to structure the flow of programs and programmers thought processes. QBasic, while maintaining backward compatibility with older versions has incorporated a great deal of the structure of Pascal and if one wishes there is no reason why  Qbasic can't be used to as a teaching tool every bit as good as Pascal. And as the basic language is used by over 50% of professional programmers using Microsoft Visual Studio, learning Qbasic in a structured way will serve well for the future.


Top Down Programming Techniques


The Top Down approach is a technique that can be used to plan almost any activity life and involves looking at a problem as a whole then dividing  it  into clearly defined segments. To explain this I will use the Fahrenheit to Celsius and Celsius to Fahrenheit program that demonstrated the use of DO LOOPS and IF THEN selections. To approach the problem in a top down fashion we need to identify each action. So we need


Program Control

Display Welcome Screen and Instruction
Test User Selection
Do Celsius to Fahrenheit Calculation
Do Fahrenheit To Celsius Calculation
Say Goodbye


So now we have defined the basic segments we can add a little more detail.


________________________________________
Program Control
 Call Display Welcome Screen and Instructions


While User input <> "E"
     Get User Selection


     Call Test User Selection

Loop
Say GoodBye
End Program
_____________________________________


Display Welcome Screen and Instruction
  Clear the Screen 
     Print message welcoming the user 
       Display message to informing users to enter 
       F for Fahrenheit to Celsius  
       C for Celsius to Fahrenheit
       E to End the program 
End (Return to Calling Procedure)

______________________________________


Test User Selection



      If UserInput = "C" then  Do Celsius to Fahrenheit 
      If UserInput = "F" then  Do Fahrenheit to Celsius



End Return to control

______________________________________



Do Celsius to Fahrenheit Calculation
   Display instruction 
   Get user input
   Calculate answer
   Display answer
   Pause 
End (Return to calling procedure) 
______________________________________


Do Fahrenheit To Celsius Calculation
Display instruction     Get user input
   Calculate answer
   Display answer
   Pause 
End (Return to Calling Procedure)

______________________________________


Although the above pseudo code   over elaborates way to describe such a simple program it's design allows the developer to break the problem down. 

Note: The way that you write pseudo code is really a matter of personal preference and as far as I know their are no books on correct etiquette. The only important fact is that it is unambiguous and in a commercial setting, clear enough to be used to communicate your ideas to other programmers.


So we will now write the program using a structured approach. At this point it is important that you understand how to use DECLARE SUBroutines, to create SUBS and CALL subs. In the same way that we have   declared variables at the beginning of a program we will have to declare all of the sub routines that will be used in the program as this is necessary before the subroutines can be created. Once sub routines are created Qbasic will divide the program. Instead of being able to see the whole program in one window, after creating the subroutine it can only be accessed by clicking on the the View Menu and clicking on SUBS or pressing on the F2 key and selecting from the list of subs. When you wish to return to the main program you must click on the Call Menu and select the listed Item, which will be the name that you have save the program under. The main program will be used for control and will often have little more than CALL's to initialize the program- Drawing Welcome Screens and instructions then looping and calling other subroutines based on some kind of user input. Another advantage of subroutines are that once written they can then be called from any other point in the program thus saving the inefficiency of repeating the same code at different points in a single program.  One other point that I need to make is that Variables must be passed to Subroutines so this must be included in the Subroutine declarations. Don't worry to much about this at present as I will cover this later.  This probably all sounds like double Dutch at the moment but we will take it step by step and I promise that it will soon make more sense.Once you've opened the QBasic Editor:


REM Declare Variables
DIM UserChoice$ AS STRING


REM Declare Subroutines
DECLARE SUB InitialiseProgram( )
DECLARE SUB EndProgram( )

DECLARE SUB TestChoice(UserChoice$) 
REM UserChoice will be passed to the subroutine from the main program


DECLARE SUB CalculateFahrToCelsius( )
DECLARE SUB CalculateCelsiusToFahr( )


Once you have written this code save the program. Now that the subroutines have been declared they can now be created. This may be the most confusing part.


Now type in the following code:


SUB InitaliseProgram( )


You will notice that the instant that you press the enter button the screen will clear and will now say


SUB InitialiseProgram 


END






To get back to the main program click on CALLS menu Item (Between DEBUG and UTILITY)


Now you are back in the main program type in


SUB EndProgram


Now type in


SUB TestChoice(UserChoice$)


The same thing will happen  so return to the main program and create SUB's for all the rest. Now you will have your basic program structure.












To access any of the Subroutines simply click on the VIEW menu item and select SUBs...








Then a dialog box will open containing all the names of the newly created subroutines or 'procedures' as they would be called in Pascal or 'Functions' as they would be called in C and C++.


You may have noted the fact that after each sub procedure declaration I have put a ( ) parenthesis but on the Sub procedure TestChoice(UserChoice$) the parenthesis contains the variable UserChoice$. This variable  contains the input value that the user enters and this will be passed to the Subroutine TestChoice. This value will then be passed from the main program to the Subroutine TestChoice.  Based on this this value, be it a C for Celsius to Fahrenheit  or an F for Fahrenheit to Celsius  TestChoice will CALL the right subroutines to do the calculation. Once the calculation is displayed the procedure will end and return control the CALLing procedure. The Calling Procedure TestChoice will then return control to the main program which will allow the user to continue doing more calculations until the user enters an 'E' to end the program.
Remember that the main program will be used to control the initial flow of the program. So now I will write the program as seen in the editor then write the code that you will have to put into the Sub routines. Apart form the Sub routines I have used two extra commands LOCATE and SLEEP. LOCATE locates the position of the next PRINT statement so LOCATE 5,5 would move the following print statement to a location 5 characters down and 5 characters along. SLEEP is the same a pause in other versions of basic. SLEEP on its own allows the computer to suspend the program until a key is pressed and SLEEP 2 will suspend operations for two seconds.


/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
REM declare Variables
DIM UserChoice$ AS STRING


REM Declare Sub Routines
DECLARE SUB InitialiseProgram( )
DECLARE SUB EndProgram( )
DECLARE SUB TestChoice(UserChoice$) 
REM UserChoice will be passed to the subroutine from the main program  


DECLARE SUB CalculateFahrToCelsius( )
DECLARE SUB CalculateCelsiusToFahr( )




REM all the Subroutines will be written after the main program
CALL InitialiseProgram 


REM E or e End the program so this loop will keep executing the 
REM code inside the loop until it is terminated by the user by pressing E
DO WHILE InputChoices$ <> "E" and InputChoices$ <> "e"

   REM by using the INKEY$ user does not have to press enter
   InputChoices$ = INKEY$
   LOCATE 10,8
   PRINT "Press F for Fahrenheit C for Celsius or E for End. 
   Call FOrC(InputChoices$)


LOOP


REM When the user presses E the loop ends and the End Message is called


Call EndProgram
_____________________________________


Sub WelcomeScreen


CLS 
LOCATE 8,17
PRINT "Welcome to F to C and C to F Calculator"
REM Of course you could make this a little bit more exiting but this
REM will do for now

END SUB
______________________________________


SUB ChooseFOrC(InputChoices$)


REM ChooseFOrC Subroutine tests the user input 
REM If the User Input is F or C then the program CALLS
REM the CToF or FToC Subroutines

If InputChoices$ = "F" or InputChoices$ = "f" then 
     CALL FToC
END IF


If InputChoices$ = "C" or InputChoices$ = "c" then 
     CALL CToF
END IF


END SUB
______________________________________


SUB CToF


DIM Celsius AS SINGLE

CLS
LOCATE 10,25
INPUT "Enter Celsius"; Celsius
REM Overwrite the previous input with Answer
LOCATE 10,25
PRINT Celsius; " Celsius = "; (Celsius  + 32) * 1.8; "Fahrenheit"
LOCATE 15,30 
PRINT "Press a Key To Continue"
SLEEP
CLS 


END SUB
______________________________________


SUB FToC


DIM Fahrenheit AS SINGLE
CLS
LOCATE 10,25


INPUT "Enter Fahrenheit"; Celsius
REM Overwrite the previous input with Answer
LOCATE 10,25
PRINT Fahrenheit; " Fahrenheit = "; (Fahrenheit  - 32) / 1.8; " Celsius"
LOCATE 15,30 
PRINT "Press a Key To Continue"
SLEEP
CLS 


END SUB
______________________________________


SUB EndProgram 


CLS 
LOCATE 10,20
PRINT " THANK YOU FOR USING THE TEMPERATURE CALCULATOR"
REM This time the SLEEP command pauses for 3 Seconds then ends
SLEEP 3


/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\


And There you have it, if all goes well when run the program will allow the user to calculate F to C of C to F until the E or e is pressed. Its a very basic program and I can think of many improvements. I may come back to this program in future lessons to demonstrate routines using the ASCII Character set to create low resolution boxes and windows. to improve the look of the program. Perhaps you can think of other conversions that you would like to incorporate into the program. Simply change the instructions, add more tests to the selection and subs for working out the maths.
Now you can see how to think about program structure from a top down perspective perhaps you might think of your own program to test what you have learnt. In the next lesson I will use the same program to demonstrate FUNCTIONS.

No comments:

Post a Comment