Pascal Programming: Week 3 Notes Robust Input Allow for varied user input to general questions: "Y" or "y" or "Yes" or "yes" or "1" Exception Handling More on Program Development Top-Down Design Stepwise Refinement Divide and Conquer Black Box Method Object-Oriented Data Abstraction Program Declaration Order: -Constants -Variables -Procedures NOTE: A procedure cannot appear before it is declared. Pascal Procedures Small versions of a program Procedure Declaration/heading, body, compound statements Procedure Body wrapped in BEGIN/END pair How procedures work. Passing Parameters Formal versus Actual Parameters pg. 125-128 Pass by reference - variable parameters Pass by value - value parameters What is being passed? - In the case of variable parameters, the actual parameter is a variable. - In the case of value parameters, the actual parameter may be a variable or any other expression that yields a value of the appropriate type, not necessarily a constant. Parameter Flow (in/out two-way vs. one-way) Parameter List Parameter Naming Conventions pg. 133 Procedure Documentation Preconditions, Postconditions, Internal Manipulation Example: looping structures Procedural abstraction is a useful design tool when implementing a program. It should be the first step in designing and writing programs and associated procedures. You must specify what each procedure does before you start to design how the procedure will do it. The comment section should describe the procedure's actions and the list of parameters to show which items will be affected by the procedure's actions. After this is done then you can begin to design how the procedure will execute it. This will make it easier for you to debug and analyze your program and if you discover that your specifications cannot be realized in a reasonable way then you know you must back up and rethink what the procedure should do. This will minimize design error and save time. No need to write code that won't work or won't work properly. Procedure Testing Test as separate units. Utilize Drivers and Stubs Global Versus Local Variables Variable boundaries Scope Dangers of Global Variable in Procedures Files: Text Files Declaring Files - Actual Filename versus Variable Filename Opening and Closing Files Reading and Writing to Text Files Example PROGRAM Payroll (input, output); {******************************************************} {*Written by: Joe Cool } {*Pascal 2210-0007 Sept. 6, 1997 } {*155-55-9999 } {******************************************************} {* This is a payroll program that will accept as input the number of minutes worked. It will calculate the number of hours worked and the pay, given a particular pay rate. The pay rate is based on minutes worked. } {******************************************************} USES Crt; CONST Rate = 20; {rate is .20 cents per minutes} MoneyLength = 7; {field width for currency} VAR TimeWorked, Ans: Integer; PayDue: Real; RunProgram,List: Boolean; PayrollFile: Text; PROCEDURE OutputTime (Minutes: integer); {*******************************************************} {PRE: Input is accepted from user for the number of minutes they have worked. PROCESS: Given a number of minutes >= 0; the number of hours worked is calculated and displayed. POST: The number of minutes and hours worked is displayed and the actual parameter "Minutes" is unchanged. } {*******************************************************} VAR Hours: Integer; BEGIN {procedure OutputTime} Hours:= Minutes DIV 60; Minutes:= Minutes MOD 60; Writeln(Hours, ' hours and ', Minutes, ' minutes. '); END; {procedure OutputTime} PROCEDURE ComputePay (Minutes: integer; VAR Pay: real); {*******************************************************} {PRE: Minutes is equal to the time worked in minutes. PROCESS: The global constant Rate is used to calculate the amount of pay due POST: Pay is set to the pay due expressed in dollars. {*******************************************************} VAR PennyPay: Integer; BEGIN {Procedure ComputePay} PennyPay:= Rate * Minutes; Pay:= PennyPay/100; END; {Procedure ComputePay} PROCEDURE RecordData (VAR Payroll: text; Pay: real); {*******************************************************} {PRE: Passes in a file that may or may not have data PROCESS: Writes payroll information to the file. POST: A file with payroll information added. {*******************************************************} BEGIN {Procedure RecordData} APPEND(PayrollFile); Writeln(PayrollFile, Paydue:7:2); CLOSE(PayrollFile); END; {Procedure RecordData} PROCEDURE ListData (VAR Payroll: text); {*******************************************************} {PRE: Passes in a file that may or may not have data PROCESS: Reads payroll information to the file. POST: Lists data on screen. {*******************************************************} VAR History: Real; BEGIN {Procedure ListData} RESET(PayrollFile); Write('The following Listing contains the contents '); Write('of the Payroll File'); Writeln; Writeln; IF EOF(Payrollfile) Then Writeln('The File is Empty.') ELSE REPEAT {*******************************************************} {PRE: Payroll file exits and is not empty, EOF()=false; PROCESS: Reads the contents of the file. POST: Information is displayed to the screen and EOF()=true; {*******************************************************} Readln(PayrollFile, History); Writeln('$ ',History:7:2); UNTIL EOF(Payrollfile); {Repeat Loop End} CLOSE(PayrollFile); END; {Procedure ListData} Homework Assignment 3: Advanced ATM Due: 9/18/97 Build on your existing work for the previous ATM assignment. This time, use whatever looping structures you feel fit best. Allow the user to use the ATM until they have completed all their transactions. This system will read and write all data to a text file. In this way, it will be a "smart" system, always retaining current balance information. Use procedures to streamline your code. You will write a minimum of THREE (3) procedures for the same program: 1.) Procedure Inquiry(account_num); 2.) Procedure Withdrawal(account_num, amount); 3.) Procedure Deposit(account_num, amount); For extra credit, add additional procedures for checking account number validity, transfers between accounts, etc. See how the usage of procedure makes the code of the main program body more legible and easy to follow. Don't forget to properly document each procedure as you would individual programs and looping structures. BEGIN {Main Program} TimeWorked:= 0; Ans:= 0; PayDue:= 0.0; RunProgram:= false; List:= false; Assign(PayrollFile, 'pay.txt'); Clrscr; Writeln; Write('Would you like to calculate your pay rate? '); Writeln('Enter 1 = ''yes'' or 0 = ''no'' '); Writeln; Readln(Ans); IF Ans = 1 Then RunProgram := true Else RunProgram := false; While RunProgram Do {*******************************************************} {PRE: Run is true PROCESS: The program calculates pay due until the user wishes to stop. POST: Run is false {*******************************************************} BEGIN {While Run Loop} Writeln; Writeln('Please enter the number of minutes you worked: '); Writeln; Readln(TimeWorked); Write('You worked: '); OutputTime(TimeWorked); ComputePay(Timeworked, Paydue); Writeln; Writeln('At ', Rate, ' cents per minute, '); Writeln('you earned: $', PayDue:MoneyLength:2); Writeln; Ans:= 0; Writeln; Writeln('Would you like to save recent pay history?'); Writeln('Enter 1 = ''yes'' or 0 = ''no'' '); Writeln; Readln(Ans); IF Ans = 1 Then List:= true Else List:= false; IF List Then RecordData(PayrollFile, PayDue); Ans:= 0; List:=false; Writeln; Write('Would you like to run the program again? '); Writeln('Enter 1 = ''yes'' or 0 = ''no'' '); Writeln; Readln(Ans); IF Ans = 1 Then RunProgram := true Else RunProgram := false; END; {While Run Loop} Writeln; Writeln('Would you like to see recent payroll history?'); Writeln('Enter 1 = ''yes'' or 0 = ''no'' '); Writeln; Readln(Ans); IF Ans = 1 Then List:= true Else List:= false; IF List Then ListData(PayrollFile); Writeln; Writeln('Goodbye'); Readln; END. {Main Program}