Press enter to skip the top menu

Python Intermediate

Usability

Introduction

There are no new programming concepts introduced here. The program code shown in Listing 1 below is designed in such a way that makes it easier for the user to operate than any of the programs we have written so far.

The concept of making programs and other digital outcomes easy to operate is referred to as Usability

This concept was initiated by Jakop Nielsen in 1994. He developed ten usability heuristics, now known as the Nielsen Norman Heuristics.

A heuristic can be described as proceeding to a solution by trial and error or by rules that are only very loosely defined. This looseness allows us to apply the heuristics to a variety of digital outcomes from basic programming to sophisticated GUI applications. In our programming example below we can only apply four of the heuristics:

Programming is the best medium for demonstrating heuristics 5 and 9. Once we have completed Web Development we will have demonstrated how to implement the rest of them.

AS92004 Create a computer program - Model Solution

NCEA Standard Guidelines

Achievement Create a computer program involves:

Merit Create a well-structured computer program involves:

Excellence Create a flexible and robust computer program involves:

The computer program must:

The main heuristics we shall be implementing here will be

Before looking at this, however, we will first go through the code in listing 1 and discuss its structure and logic.

This is a simple program that calculates the payroll for a number of employees. Those employees are paid a fixed hourly rate. However they may work a different number of hours each week. For this reason, when their payroll is being processed, we know their names and hourly rate from our records but we don't know their hours worked as that changes week by week.

Knowing the above facts we will try to design and code a program that will hopefully prevent errors from occurring when entering data.

Listing 1
                            #A list of employees and their hourly rate
                            Workers=[["John Smith", 25], ["Tom Thumb",36],["Dick Jones",32],["Harry Potter", 45]]
                            #Main variables for the program are declared
                            Payroll=[]
                            PayrollRecord=[]
                            MinHours=5.0
                            MaxHours=60.0
                            TaxRate=0.0
                            for AnEmployee in Workers:
                                EmployeeName=AnEmployee[0]
                                HourlyRate=AnEmployee[1]
                                #A while loop that validates the hours worked as being in the range 5 - 60
                                HoursWorked=float(input(f'Enter number of hours worked by {EmployeeName} It must be in the range {MinHours} to {MaxHours} : '))
                                IterationCount=0
                                while HoursWorked < MinHours or HoursWorked > MaxHours:
                                    IterationCount+=1
                                    if IterationCount == 4:
                                        print("Program being terminated due to suspicious data entry")
                                        exit()
                                    ChancesLeft=4-IterationCount
                                    ErrorFeedback=f'The value you entered for hours worked was {HoursWorked}\n'
                                    ErrorFeedback +=f'The value must be between {MinHours} and {MaxHours}\n'
                                    print(ErrorFeedback)
                                    print(f'You have {ChancesLeft} chances left')
                                    HoursWorked=float(input(f'Enter number of hours worked by {EmployeeName} It must be in the range {MinHours} to {MaxHours} : '))        
                                #Pay Details calculated
                                GrossPay= HourlyRate * HoursWorked
                                if GrossPay <= 500:
                                    Tax = GrossPay * 0.25
                                else:
                                    Tax = GrossPay * 0.33
                                Net = GrossPay-Tax;
                                #A single employee's payroll details appended to the PayrollRecord list
                                PayrollRecord.append(EmployeeName)
                                PayrollRecord.append(HourlyRate)
                                PayrollRecord.append(HoursWorked)
                                PayrollRecord.append(GrossPay)
                                PayrollRecord.append(Tax)
                                PayrollRecord.append(Net)
                                #The payroll details we have just added to a small list are now appended to the main list
                                Payroll.append(PayrollRecord)
                                print(f'Pay data for {EmployeeName} has been saved')
                                PayrollRecord=[]
                            #In the final loop below each individual emmployee's details are read from the Payroll list
                            #and printed on the screen
                            for PayrollRecord in Payroll:
                                OutputPay=f'Employee Name: {PayrollRecord[0]}\nHourly Rate: {PayrollRecord[1]}\nHours Worked: {PayrollRecord[2]}\n'
                                OutputPay+=f'Gross Pay: {PayrollRecord[3]}\nTax Paid: {PayrollRecord[4]}\nNet Pay: {PayrollRecord[5]}\n\n'
                                print(OutputPay)
                        

There is only minimum documentation here, just enough to give the reader an idea of what the different parts of the code do.


Error Prevention

Line 2 creates a list named Workers. This list contains four smaller lists. These smaller lists are have two elements each, comprised of a name and a number. These are the employees' names and their hourly rates.

By having this data hard coded into our program we ensure that no data entry errors will occur when we need to access an employee's name or hourly rate. This is demonstrated in lines 10 and 11.

This is our first example of Error Prevention. Next we shall meet a somewhat different example.

Our value of the hours worked is not constant but changes week by week. Thus we can't hard code it into the program as we did the names and hourly rates. Instead it has to be entered manually.

Manual data entry is a major source of incorrect data and therefore of errors. We shall now look at how we can prevent those type of errors from occurring.

Lines 13 - 25 contains a while loop with the priming read at line 13. Here the user is prompted to enter the the value for the hours worked. The while loop's condition at line 15 tests the value entered for being less than 5 or greater than 60. If this is not true then the condition is false and the loop terminates. Control will then pass to line 27 where the calculation of the pay can begin.

On the other hand if the condition at line 15 is true, i.e. if the data is outside the accepted range, then the error processing at lines 16 - 25 occurs. This is divided into two parts: terminating the application at lines 16 - 19 and providing feedback to the user at lines 20 - 24.

Line 16 is the first line of the body of the while loop. It increments the value of IterationCount by 1. At line 17 the variable IterationCount is tested for being equal to 4. If it is then there have been three failed attempts at entering the value of the hours worked. In most cases the arouses suspicion and thus lines 18 and 19 are executed. The first informs the user why the program is terminating while the second simply calls the exit() function which terminates the program.

This is exactly what happens at an ATM machine; if you enter the wrong PIN number too often the machine swallows your card. In our case a suspicious payroll run has been terminated.

Another form of error prevention is to clearly inform the user the type of data that they are allowed to enter.

At lines 13 and 25 the user is clearly told what type of data they are expected to enter and the lower and upper regions of that data.

Fig 1: this shows the the prompt form line 14 of Listing 1. It is informing the user the type of data expected and the allowed range of numbers


#9 Help users recognize, diagnose, and recover from errors

Despite our best efforts errors still happen. When they do then we must inform the user in as positive a way as possible what went wrong and how to fix it.

Creating a good error message is shown at lines 21 and 22 while line 23 prints it. The result is shown below in Fig 2.

Fig 2: when the user enters a too high a value he is given two messages: the first informing the user that of the value he entered and the second one prompting him of the range of the correct values.

Visibility of System Status

Human Computer Interaction is not all about error prevention. We perform more actions than that. Some very common things we do include:

Sometimes, when opening files, especially from the internet, it may take a long time. In this case the system should communicate with the user that the file is still in the process of being opened.

When we are editing, saving or deleting data we would like some assurance that these activities are either still in progress or have successfully completed. These progresses are usually communicated through progress bars, percentage completed boxes or spinning circles.

Fig 3: a progress bar showing a process is 71% complete

Image by Freepik

When booking airline tickets we often come across the message "only 5 seats left at this price". This is the system giving us information that we might find useful.

Fig 4: Screenshot of the PB Tech website

Above we have an image from a store's website listing a selection of laptops. Immediately beneath each laptop image we have a row of stars followed by a number in blue. This is the number of customers who gave feedback about the product. This number, directly, has nothing to do with the laptop itself, however, it tells the viewer that 11 customers were very happy with this product - considering the number of stars they gave it.

This is another example of visibility of system status. Do we have an example of it in our code? Yes we do.

Listing 2
                            HoursWorked=float(input(f'Enter number of hours worked by {EmployeeName} It must be in the range {MinHours} to {MaxHours} : ')) 
                            IterationCount=0 
                            while HoursWorked < MinHours or HoursWorked > MaxHours: 
                                IterationCount+=1 
                                if IterationCount == 4:
                                    print("Program being terminated due to suspicious data entry")
                                    exit() 
                                ChancesLeft=4-IterationCount 
                                ErrorFeedback=f'The value you entered for hours worked was {HoursWorked}\n' 
                                ErrorFeedback +=f'The value must be between {MinHours} and {MaxHours}\n' 
                                print(ErrorFeedback) 
                                print(f'You have {ChancesLeft} chances left') 
                                HoursWorked=float(input(f'Enter number of hours worked by {EmployeeName} It must be in the range {MinHours} to {MaxHours} : '))        
                        

Listing 2 contains the while loop that validates the value of the hours worked entered by the user. We could let this loop iterate for as long as the user continued to enter values less than 5 or greater than 60. This would be a waste of time especially since such activity could indicate someone trying to break the system. For this reason we limit the number of attempts to four. Listing 2 above shows how we go about this.

At line 14 we set the variable IterationCount to zero. At line 15 we enter the body of the loop and in the next line we increase the value of IterationCount to 1. It will continue to increase by 1 for every other iteration.

At line 17 we test if IterationCount has a value of 4. If it does then three iterations have already occurred and the program must be terminated.

Before we do this, we must inform the user of why this occurring. This is done at line 18 where we inform the use that we are suspicious of the data being entered. The program is terminated at line 19 using the exit() function.

If IterationCount has not reached a value of 4 then lines 18 and 19 are skipped and at line 20 the variable ChancesLeft is given the value of 4 less the value of IterationCount. This will be the number of iterations left.

At line 24 the value of ChancesLeft is communicated to the user.

Fig 5: notice the number of chances left being communicated to the user as well as the reason for the program being terminated

We have one more example of the visibility of system status in our code. At line 41 of Listing 1 the completed payroll record of a single employee is appended to the main payroll list. In the next line the user is given the message that record has been saved. This is shown in Fig 6 below.

Fig 6: notice that the even numbered lines confirm that an employee's record has been saved

Summary

Error Prevention Summary

The error prevention features presented in this code are:

Visibility of System Status: Summary

The instances of this heuristic in our code are:

Go to top

Revision

Multi choice

Fill in the blanks

Go to top