Press enter to skip the top menu

Programming User Interface

A structured Program

NCEA Compatibility

Module: AS91883 Develop a computer program

Requirements: using methods, functions, procedures, actions, conditions and control structures effectively, checking input data for validity, input from a user, user-defined methods, functions or procedures.

Go to top

Learning Outcomes

On completion of this page you will know how to develop a program that complies with the heuristics of good human computer interface, as well as being well structured and commented to comply with the NCEA requirements sepcified above.

You will also learn how to use formatted strings

Go to top

Heuristics Used

  • #1: Visibility of system status
  • #2: Match between system and the real world
  • #5: Error Prevention
  • #6: Recognition rather than recall
  • Go to top

    Introduction

    In the previous pages we looked at simple programs whose sole aim was demonstrating how to add features to a program to enhance human computer interface. On this page we have restructured this program into individual functions, which are then called from main().

    Of those functions we shall be paying attention to the first two. Here we have created two generic validating functions: one for validating floating point numbers and another for validating integers. Although based on the validating functions from the previous examples, we have here introduced formatted strings. Thus we shall be having a quick look at those before examining the restructured program.

    Go to top

    Formatted strings are somewhat similar to the mail merge facility provided by word processors.

    Formatted Strings

    Listing 1
                            meal="Breakfast"
                            menu1="Muesli and yoghurt"
                            menu2="Bacon and eggs"
                            cafeMenu=("Today's {meal} options are: {menu1} or {menu2}").format(meal=meal,menu1=menu1,menu2=menu2)
                            print(cafeMenu)
                        

    The code above could be the first stage of creating an automated menu for a restaurant or cafe.

    In the first three lines it defines three variables which it names meal, menu1 and menu2. To each fo those it gives the values "Breakfast", "Muesli and yoghurt" and "Bacon and eggs". Nothing new here!

    Line 4 however is a bit of a cruncher. It consists of two parts: building up the string and matching the fields of the string to the variables declared in lines 1 to 3.

    Below is the first part

    ("Today's {meal} options are: {menu1} or {menu2}")

    At first glance this looks like an English sentence except for the three items between curly brackets. Those three items are named meal, menu1 and menu2. This means that they will connect to the three variables declared in lines 1 to 3. This connection happens in the second part which is shown below.

    format(meal=meal,menu1=menu1,menu2=menu2)

    Here it is matching the {meal} placeholder in the string with the variable meal declared at line 1. This happens to contain the value "Breakfast". Thus when printed out the string cafeMenu would start off as "Today's Breakfast options are:..."

    What we have said about meal applies also to the other two variables menu1 and menu2 as well as their placeholder counterparts

    Thus the entire line would be "Today's Breakfast options are: Muesli and yoghurt or Bacon and eggs". This is confirmed when we run the program, as shown below.

    A string created using string format
    Fig 1: The output from Listing 1
    Go to top

    A structured program for formatted strings

    The example in Listing 1 should be simple and easy to follow. With no distractions, it focuses on how to incorporate external variables into a string in order to produce a complete English sentence.

    It is, however, very inefficient and would have to be almost entirely rewritten if we wanted a different output

    Below we have a structured version of it that can easily produce completely different menus.

    Listing 2
                            def makeMenu(meal, menu1, menu2):
                                menuData=("Today's {meal} options are {menu1} or {menu2}").format(meal=meal,menu1=menu1,menu2=menu2)
                                print(menuData)
                            
                            def main():
                                makeMenu("breakfast","Muesli and yoghurt","bacon and eggs")
                                makeMenu("lunch","Quiche and salad","Fish and chips")
                                makeMenu("dinner","Lamb Stew","Spam and boiled turnips")
                        

    This version contains two functions: the user defined function makeMenu() and the default function main()

    The function makeMenu()has been designed to be as similar to the code in Listing 1 as possible. Its three arguments, meal, menu1 and menu2 are taken directly from Listing 1.

    At line 2 the string is formatted in exactly the same way as we did before.

    The code in main(), however, shows us that the new version is more versatile than its predecessor. It consists of three calls to makeMenu(), each time with different menus. The output can be seen in Fig 2 below.

    A string created using string format
    Fig 2: The output from Listing 2
    Go to top

    A Structured Program

    .

    Listing 3
                            """
                            This is a generic function for validating floating point numbers for being within
                             a specified range. It has three arguments: a description of the data item to be validated, 
                            the smallest value it is allowed and the largest.
                            From those three arguments the function can construct both a prompt and an error message.
                            It uses a while loop to perform the validation.
                            Its priming read is the user's first data entry. This tested for being outside of the 
                            allowed range. If this is true then the loop's body is activated.
                            An error message is constructed using a formatted string.
                            This is presented to the user followed by a prompt to reenter a value.
                            """
                            def validateFloat(descr, smallest, largest):
                                prompt = ("Enter value for {descr}. The value must be greater than {smallest} and less than {largest}").format(descr=descr, smallest=smallest, largest=largest)
                                val = float(input(prompt))
                                while val < smallest or val > largest:
                                    strErrMsg = ("The {descr} must have a value between {smallest} and {largest}. The value you entered was {val}.").format(descr=descr, smallest=smallest, largest=largest, val = val)
                                    print(strErrMsg)
                                    val = float(input(prompt))
                                return val
                            """
                            This function is almost identical to the previous one. Their sole difference is that this function
                            validates integer values instead of floating points
                            """
                            def validateInt(descr, smallest, largest):
                                prompt = ("Enter value for {descr}. The value must be greater than {smallest} and less than {largest}").format(descr=descr, smallest=smallest, largest=largest)
                                val = int(input(prompt))
                                while val < smallest or val > largest:
                                    strErrMsg = ("The {descr} must have a value between {smallest} and {largest}. The value you entered was {val}.").format(descr=descr, smallest=smallest, largest=largest, val = val)
                                    print(strErrMsg)
                                    val = int(input(prompt))
                                return val
                            """
                            The next four functions calculate the gross, tax, superannuation payments and net.
                            They form the processing section of the program
                            """
                            def calculateGross(hrs, rt):
                                return hrs * rt
                            
                            def calculateTax(grs):
                                return grs * 0.25
                            
                            def calculateSuper(grs, superC):
                                sup = 0
                                if superC == 0:
                                    sup = 0
                                elif superC == 1:
                                    sup = grs * 0.05
                                elif superC == 2:
                                    sup = grs * 0.1
                                else:
                                    sup = grs * 0.15
                                print(sup, superC)
                                return sup
                            
                            def calculateNet(grs, tax, sup):
                                return grs - tax - sup
                            """
                            The next two functions form the output section of the program
                            The first displays both the input data and the processed data
                            while the second writes the same data to a file
                            """
                            def showData(hrs, rt, grs, tax, sup, net):
                                print("Hours: ", hrs)
                                print("Rate:   ", rt)
                                print("Gross: ", grs)
                                print("Tax:   ", tax)
                                print("Super  ", sup)
                                print("Net:   ", net)
                            
                            def saveData(hrs, rt, grs, tax, sup, net):
                                myfile=open('Payroll File.txt','a')
                                myfile.write(str(hrs) +"\n")
                                myfile.write(str(rt) +"\n")
                                myfile.write(str(grs) +"\n")
                                myfile.write(str(tax) +"\n")
                                myfile.write(str(sup) +"\n")
                                myfile.write(str(net) +"\n")
                                myfile.close()
                                print("Data has been saved to the file")
                            
                            """
                            The program's control section.
                            It performs no calculations. It just declares all necessary variables,
                            calls the validating functions followed by the processing (calculating)
                            functions, followed in turn by the output functions
                            """
                            def main(): 
                                #declaration of variables
                                fltHours=0.0
                                fltRate=0.0
                                fltSuper=0.0
                                fltGross=0.0
                                fltTax=0.0
                                fltNet=0.0
                                fltSuper=0.0
                                intSuperCode=0
                            
                                #user input
                                fltHours = validateFloat("hours", 5, 60)
                                fltRate = validateFloat("rate", 20, 80)
                                intSuperCode = validateInt("supe code", 0, 3)
                            
                                #calculation
                                fltGross = calculateGross(fltHours, fltRate)
                                fltTax = calculateTax(fltGross)
                                fltSuper = calculateSuper(fltGross, intSuperCode)
                                fltNet = calculateNet(fltGross, fltTax, fltSuper)
                            
                                #output
                                showData(fltHours, fltRate, fltGross, fltTax, fltSuper, fltNet)
                                saveData(fltHours, fltRate, fltGross, fltTax, fltSuper, fltNet)
                            
                            if __name__ == "__main__":
                                main()
                            
                            print("Programme finished")
    
                        

    As well as the function main() this program has eight other user defined functions. Except for the first two they should be familiar to you by now. Therefore we shall concentrate on the functions validateFloat() and validateInt()

    Unlike our previous menu generator the function validateFloat() is meant to produce prompts that will give a user clear unambiguous instructions about the data they they are to enter into a computer.

    The function is passed three arguments: a description of the data item, the smallest value allowed and the largest value allowed. The argument names are descr, smallest and largest The template string is shown below.

    ("Enter value for {descr}. The value must be greater than {smallest} and less than {largest}")

    The values of the three arguments passed to the function validateFloat() will be passed into the the three similarly named placeholders by the format function shown below.

    .format(descr=descr, smallest=smallest, largest=largest)

    This works exactly like the example in Listing 2 above.

    The structure of the function validateInt() is structured like validateFloat(). The only difference is that one deals with floating point numbers and the other deals with integers.

    Go to top

    Summary

    Working through this page we looked at formatted strings and building prompts and error message that would guide users of a computer application towards entering valid data into the same application. Although this topic was covered in the previous two pages, the programs were written solely for the purpose of demonstrating how to build a good human computer interface. In this page we looked at building the same human computer interface, but this time using properly structured programs.

    Go to top