Craig n Dave 2.3
Refining algorithms to make them more robust
Refining algorithms to make them more robust is about:
- Writing code which anticipates a range of possible output
- Making sure “bad” data doesn’t crash the program
- Make sure only data of the correct data type is entered.
- Checking and handling missing or blank data.
- Input validation
- Force the input into an “integer” date type
- Invalid data - data of the correct data type but outside the validation limit.
- Making the prompt more descriptive
- Exception handling
- Erroneous data - data of the incorrect data type no longer crashes the program
Suitable test data
Test data needs to include a range of:
- Normal inputs
- Boundary inputs
- Invalid inputs
- Erroneous inputs
How to identify syntax and logic errors
The purpose and types of testing
Maintainability
Defensive designs considerations part 2
Defensive designs considerations part 1
Maintainable code
- Helps others to understand your code
- Focus on key aspects
- Use comments to:
- Visually divide parts of the program
- Explain the purpose of the programs
- Explain sections of code - typically selections, iterations or procedures
- Explain unusual approaches that were necessary
- Proper indentation
- Functions and procedures
- Use sensible, descriptive identifiers (variables).
- Use constants declared at the top of the program
- Use whitespace to make sections of a program easier to read
Reasons for testing:
- Ensure that there are no bugs
- Check the program has an acceptable performance and usability
- To ensure that unauthorised access is prevented
- To check the program meets the requirements
Types of testing
Interactive testing:
- Each new module is tested as it is written.
- Program branches are checked for functionality
- Checking new modules does not introduce new errors in existing code.
- Tests to ensure the program handles erroneous data and exceptional situations.
Final / Terminal testing:
- Testing that all modules work together (integration testing)
- Testing the program produces the required results with normal, boundary invalid and erroneous data.
- Checking the program meets the requirements with real data.
- A beta test may find more errors.
Syntax errors:
- The rules of the language have been broken.
- The program will not run (compiled languages).
- Syntax errors can happen because variables are not declared or initialised before use, incompatibility of variable types e.g. total =”A” (total declared as an integer), using assignments incorrectly e.g. 2+2 = x, keywords misspelt e.g. prnt(“Enter choice”)
Logic errors:
- The program runs but does not give the expected output
- Logic errors can happen because conditions and arithmetic operations are wrong, sequences of commands are wrong, division by 0, exceptions e.g. file not found.
Normal inputs:
- Data which should be accepted by a program without causing errors
Boundary inputs:
- Data of the correct data type which is on the edge of accepted validation boundaries
Erroneous inputs:
- Data of the incorrect type which should be rejected by a computer system
- This includes no input being given when one is expected.
Invalid inputs:
- Data of the correct data type but outside accepted validation checks.
Anticipating misuse
Input validation:
- Checking data input by the user meets specific criteria / rules before processing:
- Type check: checking that the input is of the correct data type as in integer, string, real (float)
- Range check: checking that the input is within the correct range such as between 1 and 2
- Presence check: checking that some data has been entered e.g. reject blank inputs
- Format check: checking that the input is in the correct format such as dd/mm/yyyy
- Length check: checking that the input has the correct (or min/max) number of characters e.g. password
- By using input validation techniques a programmer can make their program:
- More robust
- More user friendly
- Prevent further errors occurring later in the program
Division by 0:
- In mathematics there is no number which can be divided by 0
- Therefore the ALU (arithmetic logic unit) is unable to compute a division by 0 e.g.:
num = 0
average = total / num - This line of code, whilst syntactically correct will cause the program to crash
- A programmer should always check that a variable does not equal 0 before attempting a division
Communication error:
- Online systems require connections to host servers
- If this connection is dropped, unable to be established or the server is overloaded, it could potentially cause a program to crash or hang when loading / saving data.
- A programmer should enable ways for the user to cancel requests or for them to fail gracefully, reporting the communication error.
- The program may be able to automatically resume when the connection is available again
Printer and other peripheral errors:
- If a program outputs a hardcopy, the printer may run out of paper, ink or have a jam
- The programmer should NOT assume that an output to a printer was successful and always have options to reprint reports or receipts.
Disk errors:
- Programs that read and write to files need to handle many types of exceptions including:
- The file/folder not being found
- The disk being out of space
- The data in the file being corrupt
- The end of the file being reached
- Robust programs will handle all of these situations by checking files and data before attempting to use them for further processing
Authentication:
- Data used in systems should be secure
- This can be achieved by using:
- Username and password to access systems
- Recovering a password requiring clicking on a link within an email that is sent to the registered address
- Encryption of data files.
- Online bots can automatically submit data to online forms
- This can be protected against by using software such as reCAPTCHA that verifies that the user is a human.
- Programmers should also be aware of the potential for SQL injection hacks and other methods used by hackers.