The user is to input prices of items for sale. At the end of the day the total of the sales made, the number of items sold and the average price of items sold is to be displayed.
Discussion
It isn't possible to hold all of the prices in separate variables - we don't know
how many prices are to be added up. It is far simpler to keep a running total (the
total so far), so at the end this will be the total of all of the numbers.
As prices must be more than zero, a sentinel value of 0 can be used (-1 or some other suitable value could also be used in this problem).
Run Price (0 to exit) ? 1.5 Price (0 to exit) ? 2 Price (0 to exit) ? 0 Count = 2, Total = 3.50, Average = 1.75
| Inputs | Processing | Output |
| price | Input prices Sum the prices Count the items Calculate the average price Display count, totalPrice, average |
count totalPrice average |
sumPrices()
totalPrice = 0
count = 0
Input price
WHILE price <> 0 DO
totalPrice = totalPrice + price
count = count + 1
Input price
ENDWHILE
Display count, totalPrice
IF count > 0 THEN
average = totalPrice / count
Display average
ELSE
Display "No values input, unable to calculate average"
ENDIF
STOP
| Name | Data Type | Description |
| average | Double | The average price of the items sold |
| count | Integer | The number of items sold |
| price | Double | The price of the item for sale in $ |
| totalPrice | Double | The total price of all the items in $ |
1 sumPrices() 2 totalPrice = 0 3 count = 0 4 Input price 5 WHILE price <> 0 DO 6 totalPrice = totalPrice + price 7 count = count + 1 8 Input price 9 ENDWHILE 10 Display count, totalPrice 11 IF count > 0 THEN 12 average = totalPrice / count 13 Display average 14 ELSE 15 Display "No values input, unable to calculate average" 16 ENDIF 17 STOP
Inputs: prices = 1.50, 2, 0. Correct results: average = 1.75, count = 2, totalPrice = 3.50.
' Name: sumPrices ' Purpose: Produce statistics on a series of prices displaying the total, average and count ' Author: Tim Whitfort
Option Compare Database Option Explicit
Sub Main()
Dim average As Double ' The average price of the items sold
Dim count As Long ' The number of items sold
Dim price As Double ' The price of the item for sale in $
Dim totalPrice As Double ' The total price of all the items in $
totalPrice = 0
count = 0
price = InputBox("Price (0 to exit) ?")
While price <> 0
totalPrice = totalPrice + price
count = count + 1
price = InputBox("Price (0 to exit) ?")
Wend
Debug.Print "Total price: $"; Format(totalPrice, "0.00")
Debug.Print "Number of items sold: "; count
If count > 0 Then
average = totalPrice / count
Debug.Print "Average price: $"; Format(average, "0.00")
Else
Debug.Print "No values input, unable to calculate average"
End If
End Sub
Problems involving repeated input terminated by inputting a sentinel value have a similar format, as shown below:
inputWithSentinel()
...
Input value
WHILE value <> sentinel DO
...
Input value
ENDWHILE
...
STOP
The above problem introduced totaling or summing. A variable is used to store a running total of the total of the numbers input so far. At the end the running total represents the total to all the numbers. The total variable can be called anything (e.g. total, sum, x). The data type of the total is usually the same as the data type of the value it is summing up. The logic to totaling problems tends to be very similar:
inputAndTotaling()
total = 0
Input value
WHILE condition DO
Optionally do some processing on the value
total = total + value
Input value
ENDWHILE
Do something with the total
STOP
In earlier problems involving loops, a counter was used in controlling how many times the loop was executed. e.g. For counter = 1 To 10. In the following logic, the counter is simply used to count how many times the loop repeated, it is not used in deciding when the loop is to end.
inputAndCounting()
count = 0
Input value
WHILE condition DO
count = count + 1
Optionally do some processing on the value
Input value
ENDWHILE
Do something with count
STOP
Note: in the above example the count is not used to control the loop, it is simply counting how many values were input.
Averaging requires totaling and counting. Care needs to be taken to ensure that there is something to average (if count = 0 then division by zero occurs, crashing the program)
inputAveraging()
total = 0
count = 0
Input value
WHILE condition DO
total = total + value
count = count + 1
Optionally do some processing on the value
Input value
ENDWHILE
Do something with total, count
IF count > 0 THEN
average = total / count
DO something with average
ENDIF
STOP
Checking whether a value is correct is known as Validation. We will look at validating values input by a user. When inputting a value, a user may get a value right the first time, or may take a number of attempts to get it right. To ensure that the value input is valid a loop is used which repeats until the user gets it right.
Example Problems:
If validation isn't performed, the program needs to check each time the value is used for invalid values, this may require checking in multiple places, or alternatively incorrect results may occur because invalid input values are not detected and used in processing. (e.g. allowing mark of -50). Input validation requires the user to input a value while it is wrong (until they it is correct). This requires a loop as it is unknown how many times it will take the user to get the input correct. Therefore the only way out of the loop is to input a correct value.
Performing validation checks on input allows the checking to be performed in one place, rather than throughout the code, and simplifies the logic as the programmer can assume that the value is correct.
Write a program that allows a user to input a mark and checks that the mark is between 1 and 100.
Note: this is really just part of a program. Once the mark is obtained something would normally be done with it.
| Inputs | Processing | Output |
| mark | Input mark Check mark is correct Display mark |
mark |
A While loop is required to repeat asking for a mark until it is correct (the loop is repeated while the value is wrong).
validateMark()
Input mark
WHILE mark < 0 OR mark > 100 DO
Display "Error: mark must be between 0 and 100"
Input mark
ENDWHILE
Display mark, " is a valid mark"
STOP
| Name | Data Type | Description |
| mark | Integer | A subject mark. Range: 0 to 100 inclusive. |
1 validateMark() 2 Input mark 3 WHILE mark < 0 OR mark > 100 DO 4 Display "Error: mark must be between 0 and 100" 5 Input mark 6 ENDWHILE 7 Display mark, " is a valid mark" 8 STOP
Inputs: mark = 70; Correct result: "70 is a valid mark"
| Line Number | mark | Conditions | Input/Output |
| 1, 2 | 70 | mark ? 70 | |
| 3 | 70 < 0 OR 70 > 100 ? is F OR F ? is F | ||
| 7 | mark = 70 | ||
| 8 |
Inputs: mark = 101. Correct Results: "Error: mark must be between 0 and 100";
Input mark
Inputs: mark = 100. Correct Results: "100 is a valid mark"
| Line Number | mark | Conditions | Input/Output |
| 1, 2 | 101 | mark ? 101 | |
| 3 | 101 < 0 OR 101 > 100 ? is F OR T ? is T | ||
| 4 | Invalid mark | ||
| 5 | 100 | mark ? 100 | |
| 6, 3 | 100 < 0 OR 100 > 100 ? is F OR F ? is F | ||
| 7 | mark = 100 | ||
| 8 |
Inputs: mark = -1. Correct Results: "Error: mark must be between 0 and 100";
Input mark
Inputs: mark = 0. Correct Results: "0 is a valid mark"
| Line Number | mark | Conditions | Input/Output |
| 1, 2 | -1 | mark ? -1 | |
| 3 | -1 < 0 OR -1 > 100 ? is T OR F ? is T | ||
| 4 | Invalid mark | ||
| 5 | 0 | mark ? 0 | |
| 6, 3 | 0 < 0 OR 0 > 100 ? is F OR F ? is F | ||
| 7 | mark = 100 | ||
| 8 |
' Name: validateMark
' Purpose: Validate a mark input by a user
' Author: Tim Whitfort
Option Compare Database
Option Explicit
Sub Main()
Dim mark As Long ' A subject mark. Range: 0 to 100 inclusive.
mark = InputBox("Mark (0 to 100) ?")
' While the mark is wrong
While mark < 0 Or mark > 100
' MsgBox displays a message on the screen in a dialog box
MsgBox ("Error: mark must be between 0 and 100")
mark = InputBox("Mark (0 to 100) ?")
Wend
Debug.Print mark; " is a valid mark"
End Sub
Write a program that allows a user to input a character representing a club membership type (F=Full, J=Junior, L=Life) and checks that the membership type is valid.
| Inputs | Processing | Output |
| membershipType | Input membershipType Check membershipType is correct Display membershipType |
membershipType |
A While loop is required to repeat asking for a membershipType until it is correct.
validateMembershipType() STOP
| Name | Data Type | Description |
| membershipType | String | The type of membership in the club. Values: F=Full, J=Junior, L=Life. |
Inputs: membershipType = "F". Correct Results: "The membership type input is F"
Inputs: membershipType = "Z". Correct Results: "Error: membership
type must be F, J or L"; Input membershipType
Inputs: membershipType = "J". Correct Results: "The membership type
input is J"
' Name: validateMembershipType ' Purpose: Validate a membership type input by the user ' Author: Tim Whitfort Option Compare Database Option Explicit Sub Main() End Sub
Typically validation has the following logic:
Input value
WHILE value is wrong DO
Display "Error: value is wrong"
Input value
ENDWHILE
Where the value is valid over a range (e.g. 1 to 12) the condition has the format:
Input value
WHILE value < minimumValidValue OR value > maximumValidValue DO
Display error
Input value
ENDWHILE
Where the value is valid for a number of discrete values (e.g. one of the numbers 1, 7, and 23) the condition has the format:
Input value
WHILE value <> validValue1 AND value <> validValue2 AND ... DO
Display error
Input value
ENDWHILE
Written by Tim Whitfort.