A-Level Paper-2 Student Notes
A-Level Paper-2 Student Notes
Decomposition
Decomposition means breaking tasks down into smaller parts in order to explain a process more
clearly. Decomposition is another word for step-wise refinement. This led us to structured
programming using procedures and functions with parameters.
Pattern recognition
Pattern recognition means looking for patterns or common solutions to common problems and
exploiting these to complete tasks in a more efficient and effective way.
Abstraction
Abstraction involves filtering out information that is not necessary to solving the problem.
Abstraction gives us the power to deal with complexity. An algorithm is an abstraction of a
process that takes inputs, execute-s a sequence of steps, and produces outputs. An abstract data
type defines an abstract set of values and operations for manipulating those values.
Data modelling
Data modelling involves analyzing and organizing data. Simple data types such as integer,
character and Boolean. The string data type is a composite type: a sequence of characters. When
we have groups of data items, we used one-dimensional (lD) arrays to represent linear lists and
two-dimensional (2D) arrays to represent tables or matrices. We stored data in text files. In
Chapter 10, we used data modelling to design database tables. We can set up abstract data types
to model real-world concepts, such as records, queues or stacks. When a programming language
does not have such data types built-in, we can define our own by building them from existing
data.
Algorithm design
Algorithm design involves developing step-by-step instructions to solve a problem.
Expressing Algorithms
Algorithm can be written in three ways.
Variable
A storage location in a memory for a data value that has an identifier name. Variable identifiers
should not contain spaces, only letters, digits and _ (the underscore symbol).
1. Assigning a value
Number ← 1
2. Updating a value
Number ← Number + 1
Number ← Number – 1
3. Copying a value
Number2 ← Number1
Constant
Constants are like variables in their declarations and the ability to look at the value stored inside
them; however, you cannot change the values while the program is running, the value of a
constant remains (rather unsurprisingly) constant.
Example
Convert a distance in miles and output the equivalent distance in km (1km = 1.6 miles).
Logic Statements
A number-guessing game follows different steps depending on certain conditions. Here is a
description of the algorithm.
• The player inputs a number to guess the secret number stored.
• If the guess was correct, output a congratulations message.
• If the number input was larger than the secret number, output message “secret number is
smaller”.
• If the number input was smaller than the secret number, output message “secret number
is greater”.
We can re-write the number-guessing game steps as an algorithm in pseudocode:
More complex conditions can be formed by using the logical operators AND, OR and NOT. For
example, the number-guessing game might allow the player multiple guesses; if the player has
not guessed the secret number after 10 guesses, a different message is output.
IF Guess = SecretNumber
THEN
OUTPUT "Well done. You have guessed the secret number"
ELSE IF Guess > SecretNumber AND NumberofGuesses = 10
THEN
OUTPUT "You still have not guessed the secret number"
ELSE IF Guess < SecretNumber
THEN
OUTPUT "secret number is smaller"
ELSE
OUTPUT "secret number is greater"
ENDIF
ENDIF
ENDIF
Nested IF Statement
Conditional statements within conditional statements.
This seems awfully cumbersome and we will now look a more elegant way of solving this, using
Nested IF's. First of all, nested means placing one thing inside another, so we are going to place
an IF inside another.
Case Statement
Create a program where someone types in the name of an animal and it outputs the sound the
animal makes. The animals it should handle are:
• Pig - Oink
• Cow - Moo
• Bear - Grr
• Sheep - Baa
• Tiger - Grr
• everything else - Meow
Try and complete this task by only using 5 case statements.
Loops/Iterations
BiggestSoFar ← -100
Counter ← 1
REPEAT
INPUT NextNumber
Counter ← Counter + 1
IF NextNumber > BiggestSoFar
THEN
BiggestSoFar ← NextNumber
ENDIF
UNTIL Counter = 10
OUTPUT BiggestSoFar
BiggestSoFar ← -100
FOR Counter ← 1 TO 10
INPUT NextNumber
IF NextNumber > BiggestSoFar
THEN
BiggestSoFar ← NextNumber
ENDIF
NEXT Counter
OUTPUT BiggestSoFar
BiggestSoFar ← -100
Counter ← 1
While Counter <> 10
Do
INPUT NextNumber
Counter ← Counter + 1
IF NextNumber > BiggestSoFar
THEN
BiggestSoFar ← NextNumber
ENDIF
END While
OUTPUT BiggestSoFar
Rogue value
A value used to terminate a sequence of values.
BiggestSoFar ← -100
REPEAT
INPUT NextNumber
IF NextNumber > BiggestSoFar
THEN
BiggestSoFar ← NextNumber
ENDIF
UNTIL NextNumber = 0
OUTPUT BiggestSoFar
This algorithm works even if the sequence consists of only one non-zero input. However, it will
not work if the only input is 0. In that case, we don’t want to perform the statements within the
loop at all. We can use an alternative construct, the WHILE...ENDWHILE loop.
INPUT NextNumber
BiggestSoFar ← NextNumber
WHILE NextNumber <> 0 DO // sequence terminator not encountered
INPUT NextNumber
IF NextNumber > BiggestSoFar
THEN
BiggestSoFar ← NextNumber
ENDIF
ENDWHILE
OUTPUT BiggestSoFar
SecretNumber ← Random()
NumberOfGuesses ← 0
REPEAT
INPUT Guess
NumberOfGuesses ← NumberOfGuesses + 1
IF Guess > SecretNumber
THEN
// the player is given the message to input a smaller number
ENDIF
IF Guess < SecretNumber
THEN
// the player is given the message to input a larger number
ENDIF
UNTIL Guess = SecretNumber
OUTPUT NumberOfGuesses
SecretNumber ← Random()
INPUT Guess
NumberOfGuesses ← 1
WHILE Guess <> SecretNumber DO
IF Guess > SecretNumber
THEN
// the player is given the message to input a smaller number
ENDIF
IF Guess < SecretNumber
THEN
// the player is given the message to input a larger number
ENDIF
INPUT Guess
NumberOfGuesses ← NumberOfGuesses + 1
ENDWHILE
OUTPUT NumberOfGuesses
RunningTotal ← 0
FOR Counter ← 1 TO 10
INPUT NextNumber
RunningTotal ← RunningTotal + NextNumber
NEXT Counter
OUTPUT RunningTotal
Average ← RunningTotal / 10
OUTPUT Average
The problem to be solved: Take as input two numbers and a symbol. Output a grid made up
entirely of the chosen symbol, with the number of rows matching the first number input and the
number of columns matching the second number input. For example, the three input values 3, 7
and &, result in the output:
&&&&&&&
&&&&&&&
&&&&&&&
INPUT NumberOfRows
INPUT NumberOfColumns
INPUT Symbol
FOR RowCounter ← 1 TO NumberOfRows
FOR ColumnCounter ← 1 TO NumberOfColumns
OUTPUT Symbol // without moving to next line
NEXT ColumnCounter
OUTPUT Newline // move to the next line
NEXT RowCounter
Stepwise Refinement: Breaking down the steps of an outline solution into smaller and
smaller steps.
Modules: Another method of developing a solution is to decompose the problem into sub-
tasks. Each sub-task can be considered as a ‘module’ that is refined separately. Modules are
procedures and functions.
Procedure: A sequence of steps that is given an identifier and can be called to perform a sub-
task.
Function: a sequence of steps that is given an identifier and returns a single value; function call
is part of an expression.
Local variable: A variable that is accessible only within the module in which it is declared.
Global variable: A variable that is accessible from all modules.
Primitive Data Types: Primitive data types are those variables that can be defined simply by
commands built into the programming language.
The Record Type: The record type is known as a user-defined type, because the programmer
can decide which variables (fields) to include as a record. A data type that contains a fixed number
of components, which can be of different types.
As an example, a record could be used for a program using employee data. Pseudocode for
defining the type could be:
TYPE TEmployeeRecord
DECLARE EmployeeFirstName : STRING
DECLARE EmployeeFamilyName : STRING
DECLARE DateEmployed : DATE
DECLARE Salary : CURRENCY
END TYPE
A particular use of a record is for the implementation of a data structure where one or possibly
two of the variables defined are pointer variables.
TYPE PersonType
Name : STRING
DateOfBirth : DATE
Height : REAL
NumberOfSiblings : INTEGER
IsFullTimeStudent : BOOLEAN
ENDTYPE
To declare a variable of this type we write:
DECLARE Person : PersonType
Person.Name ← "Fred"
Person.NumberOfSiblings ← 3
Person.IsFullTimeStudent ← TRUE
To output a field of a record:
OUTPUT Person.Name
Person[1].Name ← "Fred"
OUTPUT Person[1].Name
Arrays
An array is an ordered set of data items, usually of the same type, grouped together using a single
identifier. Individual array elements are addressed using an array index for each array dimension.
A list is a one-dimensional (1D) array and a table or matrix is a two-dimensional (2D) array.
Linear search: Checking each element of an array in turn for a required value.
Searching a 1D array
The problem to be solved: Take a number as input. Search for this number in an existing 1D array
of seven numbers. Start at the first element of the array and check each element in turn until the
search value is found or the end of the array is reached. This method is called a linear search.
Bubble Sort: A sort method where adjacent pairs of values are compared and swapped.
n ← MaxIndex – 1
FOR i ← 0 TO MaxIndex – 1
FOR j ← 0 TO n
THEN
MyList [j + 1] ← Temp
ENDIF
NEXT j
n ← n – 1 // this means the next time round the inner loop, we don't look
at the values already in the correct positions.
NEXT i
n ← MaxIndex – 1
REPEAT
NoMoreSwaps ← TRUE
FOR j ← 0 TO n
THEN
MyList [j + 1] ← Temp
NoMoreSwaps ← FALSE
ENDIF
NEXT j
n←n–1
Two-Dimensional Arrays
Using pseudocode, the algorithm to set each element of array ThisTable to zero is:
Text Files
Data need to be stored permanently. One approach is to use a file. For example, any data held in
an array while your program is executing will be lost when the program stops. You can save the
data out to a file and read it back in when your program requires it on subsequent executions.
A text file consists of a sequence of characters formatted into lines. Each line is terminated by an
end-of-line marker. The text file is terminated by an end-of-file marker.
Writing to a Text File
Stack
What are the features of a stack in the real world? To make a stack, we pile items on top of each
other. The item that is accessible is the one on top of the stack. If we try to find an item in the
stack and take it out, we are likely to cause the pile of items to collapse.
The BaseOfStackPointer will always point to the first slot in the stack. The TopOfStackPointer will
point to the last element pushed (added) onto the stack. When an element is popped (removed)
from the stack, the TopOfStackPointer will decrease to point to the element now at the top of
the stack. When the stack is empty, TopOfStackPointer will have the value –1.
IF TOS ← 7
Then
Else
Input Item
TOS ← TOS +1
Stack[TOS] ← item
END If
IF TOS ← -1
Then
Else
Output ← Stack[TOS]
TOS ← TOS - 1
END IF
Queue
What are the features of a queue in the real world? When people form a queue, they join the
queue at the end. People leave the queue from the front of the queue. If it is an orderly queue,
no-one pushes in between and people don’t leave the queue from any other position. Figure
shows how we can represent a queue when five items have joined the queue in
this order: A, B, C, D, E.
To implement a queue using an array, we can assume that the front of the queue is at position
0. When the queue is empty, the EndOfQueuePointer will have the value –1. When one value
joins the queue, the EndOfQueuePointer will be incremented before adding the value to the array
element where the pointer is pointing to. When the item at the front of the queue leaves, we
need to move all the other items one slot forward and adjust EndOfQueuePointer.
IF EOQ ← 7 Then
ELSE
Input newitem
Queue[EOQ] ← newitem
EOQ ← EOQ + 1
END IF
IF EOQ ← -1 Then
ELSE
Output ←Queue[FOQ]
FOQ ← FOQ + 1
END IF
Linked Lists
We used an array as a linear list. In a linear list, the list items are stored in consecutive locations.
Using linked lists saves time, however we need more storage space for the pointer fields. To
implement a linked list using arrays, we can use a 1D array to store the data and a 1D array to
store the pointer.
Reading the array values across at the same index, one row represents a node. A value is added
to the next free element of the Data array and pointers are adjusted to incorporate the node in
the correct position within the linked list.
Below figure shows how a new node is added to the beginning of a linked list implemented
using arrays. Note that the value “A” is added at index 3 but the start pointer is adjusted to
make this the new first element of the list.
Figure shows how a new node is added to the end of a linked list implemented using arrays. Note
that the value “P” is added at index 3. The node that previously contained the null pointer (at
index 0) has its pointer adjusted to point to the new node.
When deleting a node, only pointers need to be adjusted. The old data can remain in the array,
but it will no longer be accessible as no pointer will point to it.
Below Figure shows how the start pointer is adjusted to effectively delete the first element of
the linked list. Note that the start pointer now contains the pointer value of the deleted node.
Below figure shows how the pointer value of the penultimate node of the linked list is changed
to the null pointer.
When adding a node that needs to be inserted into the list, the data is added to any free element
of the Data array. The pointer of the new node is set to point to the index of the node that comes
after the insertion point. Note that this is the value of the pointer of the node preceding the
insertion point. The pointer of the node preceding the insertion point is set to point to the new
node.
Unused nodes need to be easy to find. A suitable technique is to link the unused nodes to form
another linked list: the free list. Below figure shows our linked list and its free list.
When an array of nodes is first initialized to work as a linked list, the linked list will be empty. So,
the start pointer will be the null pointer. All nodes need to be linked to form the free list. Below
figure shows an example of an implementation of a linked list before any data is inserted into it.
Assume “L”, “B” and “D” were added to the linked list and to be kept in alphabetical order. Below
figure shows how the values are stored in the Data array and the pointers of the linked list and
free list adjusted.
Usually, we grouped together related data items into record data structures. To use a record
variable, we first define a record type. Then we declare variables of that record type.
We can store the linked list in an array of records. One record represents a node and consists
of the data and a pointer as shown in figure.
Programming Basics
Declaration of Variables
In pseudocode, variable declarations are written as:
Assignment of Variables
In pseudocode, assignment statements are written as:
<identifier> ← <expression>
For example:
A ← 34
B←B+1
VB.NET allows you to initialize a variable as part of the declaration statement, for example:
Arithmetic Operators
OUTPUT <string>
OUTPUT <identifier(s)>
Data Types
A sequence of characters (a string) String (2 bytes per character) Use double (")
quotation marks to delimit a string.
Logical values: True (represented as 1) Boolean (2 bytes) possible values:
And False (represented as 0) True
False
Boolean Expressions
Selection
IF <Boolean expression>
THEN
<statement(s)>
ENDIF
Pseudocode example:
IF x < 0
THEN
OUTPUT "Negative"
ENDIF
IF...THEN...ELSE Statements
Nested IF Statements
CASE Statements
An alternative selection construct is the CASE statement. Each considered CASE condition can be:
• a single value
• single values separated by commas
• a range.
In pseudocode, the CASE statement is written as:
CASE OF <expression>
<value1> : <statement(s)>
<value2>,<value3> : <statement(s)>
<value4> TO <value5> : <statement(s)>
.
.
OTHERWISE <statement(s)>
ENDCASE
Iteration
Count-controlled (FOR) loops
FOR <control variable> ← s TO e STEP i // STEP is optional
<statement(s)>
NEXT <control variable>
FOR x ← 1 TO 5
OUTPUT x
NEXT x
FOR x = 2 TO 14 STEP 3
OUTPUT x
NEXT x
FOR x = 5 TO 1 STEP -1
OUTPUT x
NEXT x
Post-Condition Loops
In pseudocode, the post-condition loop is written as:
REPEAT
<statement(s)>
UNTIL <condition>
Pre-Condition Loops
In pseudocode the pre-condition loop is written as:
WHILE <condition> DO
<statement(s)>
ENDWHILE
Built-In Functions
Description VB.Net
Truncating Numbers
Instead of rounding, sometimes we just want the whole number part of a real number. This is
known as ‘truncation’.
Sometimes a whole number may be held as a string. To use such a number in a calculation, we
first need to convert it to an integer. For example, these functions return the integer value 5 from
the string "5":
Sometimes a number with a decimal point may be held as a string. To use such a number in a
calculation, we first need to convert it to a real (float). For example, these functions return the
real number 75.43 from the string "75.43":
Procedures
PROCEDURE <procedureIdentifier> // this is the procedure header
<statement(s)> // these statements are the procedure body
ENDPROCEDURE
Functions
In previous section we used built-in functions. These are useful subroutines written by other
programmers and made available in module libraries. The most-used ones are usually in the
system library, so are available without you having to import them. You can write your own
functions. Any function you have written can be used in another program if you build up your
own module library.
A function is used as part of an expression. When program execution gets to the statement that
includes a function call as part of the expression, the function is executed. The return value from
this function call is then used in the expression.
When writing your own function, ensure you always return a value as part of the statements that
make up the function (the function body). You can have more than one RETURN statement if
there are diff erent paths through the function body.
Return Value: The value replacing the function call used in the expression
When we define a subroutine that requires values to be passed to the subroutine body, we use
a parameter list in the subroutine header. When the subroutine is called, we supply the
arguments in brackets. The arguments supplied are assigned to the corresponding parameter of
the subroutine (note the order of the parameters in the parameter list must be the same as the
order in the list of arguments). This is known as the subroutine interface.
Argument: the actual input expression or value with which the subroutine is being called.
Parameter: the variable(s) used inside a subroutine which will take values passed into a
subroutine at call time.
Subroutine Interface: the parameters being passed between the subroutine and the calling
program.
Function / Procedure Header: the first line of a function or procedure definition showing
the identifier and parameter list.
By Value: the actual value is passed into the procedure.
By Reference: the address of the variable is passed into the procedure.
Any System Development Life Cycle should result in a high-quality system that meets or exceeds
customer expectations, is finished within time and cost limits, works effectively and efficiently
and is inexpensive to maintain and cost-effective to improve upon. For this chapter we are going
to look at how a computer games firm, 'Ele0ctronic Crafts', would look at making a new computer
game.
Cycle
As this is called the Systems Development Life Cycle, it's quite usual that a company will then go
back to the analysis once it has evaluated a product. Think about some of the software products
that you use, they probably have a version number or a year, and reuse code and designs from
previous years
• Windows 95 -> Windows 98 -> Windows ME -> Windows XP -> Windows Vista -> Windows 7
-> Windows 8 -> Windows 8.1 -> Windows 10
• FIFA International Soccer -> FIFA Soccer 95 -> FIFA Soccer 96 -> FIFA 97 -> FIFA Road to the
World Cup 98 -> FIFA 99 -> FIFA 2000 -> etc.
With the Systems Development Life Cycle, you never just quit, you are always looking at ways to
improve or surpass what you have created.
Analysis
When you are given any problem, you should start off by finding out about the problem and
getting an idea of what you will make to solve the problem by:
Electronic Crafts wants to create a game that will sell successfully, so it needs to see what the
market wants to buy and what their current interests are. It will gather data on:
Design
Once we have settled on what we are going to make and the objectives for the system, we need
to set about designing the components. Design is important as it allows you to start thinking
about how you will make things, and hopefully avoid making mistakes later.
The Process involved in the design of a product is looking at:
• User interface
• Processes
• Data storage requirements
Coding/Implementation
You might think that all implementation involves is creating the game. You'd be wrong, it involves
the following:
Testing
Once we have created our solution, we need to test that the whole system functions effectively.
To do this should be easy, as all we need to do is compare the finished product next to the
objectives that we set out in the Analysis. There are several ways of testing a system, you need
to know them all and the types of data that might be used.
1. Stub Testing: In this testing method we can write a ‘stub’ for each procedure. The
procedure body only contains an output statement to acknowledge that the call was
made. Each option the user chooses in the main program will call the relevant procedure.
2. Black-Box Testing: Consider the box to contain the program source code, you don't have
access to it and you don't have to be aware of how it works. All you do is input data and
test to see if the output is as expected. The internal workings are unknown, they are in a
black box. Examples of Black Box testing would be if you were working as a game’s tester
for a new console game. You wouldn't have been involved in the design or coding of the
system, and all you will be asked to do is to input commands to see if the desired results
are output.
3. White-Box Testing: With white box testing you understand the coding structure that makes
up the program. All the tests that you perform will exercise the different routes through the
program, checking to see that the correct results are output.
These testing methods are used early on in software development, for example when
individual modules are written. Sometimes programmers themselves use these testing
methods. In larger software development organizations, separate software testers will be
employed.
5. Integration Testing: Individually tested modules are joined into one program and tested
to ensure the modules interact correctly.
6. Alpha testing: testing of software in-house by dedicated testers.
7. Acceptance testing: Testing of software by customers before sign-off.
8. Beta testing: Testing of software by a limited number of chosen users before general
release.
There are three types of test data we can use. What are they? The answer lies mostly in their
name, let's take a look at this example where someone has created a secondary school
registration system which lets students register themselves. We don't want people who are too
young attending, and we don't want students who are too old. In fact, we are looking for students
11-16 years old.
Evaluation
The final thing you should do is evaluate how it all went. Remember we are talking about a
systems development life cycle here, so if you made any mistakes or things didn't go to plan it's
best to make a note of them. Then next time round you won't make the same mistake. However,
the main part of the evaluation is to reflect on how successful the operational system is:
The arrows going down represent the fact that the results from one stage are input into the next
stage. The arrows leading back up to an earlier stage reflect the fact that often more work is
required at an earlier stage to complete the current stage.
Benefits
Drawbacks
An iterative life cycle model does not attempt to start with a full specification of requirements.
Instead, development starts with the implementation of a small subset of the program
requirements. Repeated (iterative) reviews to identify further requirements eventually result in
the complete system.
Benefits
• There is a working model of the system at a very early stage of development, which makes it
easier to find functional or design flaws. Finding issues at an early stage of development means
corrective measures can be taken more quickly.
• Some working functionality can be developed quickly and early in the life cycle.
• Results are obtained early and periodically.
• Parallel development can be planned.
• Progress can be measured.
• Less costly to change the scope/requirements.
• Testing and debugging of a smaller subset of program is easy.
• Risks are identified and resolved during iteration.
• Easier to manage risk – high-risk part is done first.
• With every increment, operational product is delivered.
• Issues, challenges and risks identified from each increment can be utilised/applied to the next
increment.
• Better suited for large and mission-critical projects.
• During the life cycle, software is produced early, which facilitates customer evaluation an
feedback.
Drawbacks
• Only large software development projects can benefit because it is hard to break a small
software system into further small serviceable modules.
• More resources may be required.
• Design issues might arise because not all requirements are gathered at the beginning of
the entire life cycle.
• Defining increments may require definition of the complete system.
RAD is a software development methodology that uses minimal planning. Instead it uses
prototyping. A prototype is a working model of part of the solution. In the RAD model, the
modules are developed in parallel as prototypes and are integrated to make the complete
product for faster product delivery. There is no detailed preplanning.
Changes are made during the development process. The analysis, design, code and test phases
are incorporated into a series of short, iterative development cycles.
Benefits
• Changing requirements can be accommodated.
• Progress can be measured.
• Productivity increases with fewer people in a short time.
• Reduces development time.
• Increases reusability of components.
• Quick initial reviews occur.
• Encourages customer feedback.
• Integration from very beginning solves a lot of integration issues.
Drawbacks
• Only systems that can be modularized can be built using RAD.
• Requires highly skilled developers/designers.
• Suitable for systems that are component based and scalable.
• Requires user involvement throughout the life cycle.
• Suitable for projects requiring shorter development times.
Syntax Errors: These are errors in the use of the language. The rules have been broken. A
command word might be PRINT. If it was typed in as PLINT the translator program would not
recognize it and so would not be able to translate it. This is not a difficult error to spot because
when the programmer tells the translator to translate it, a message will be returned saying that
a mistake has been made and telling the programmer which word it cannot recognize. There
are other ways of breaking the rules, for instance a language might be set up to only accept a
mathematical formula if it is in the form of a variable followed by an equal sign and then a
collection of variables. So, X = 3*(2+A)would be accepted by the translator, but 3*(2+A) = X
would be rejected as an error even though, mathematically, it is identical.
Logic Errors: A logic error is a mistake in the way the program solution has been designed. For
example, an instruction in a program may tell the computer to jump to another part of the
program. This is fine as long as the instruction tells the computer to go to the right part of the
program. If it tells the computer to go to the wrong place, it is highly unlikely that the program
will produce the results that were expected. Unfortunately, such a mistake does not usually
make the program stop working; it just makes it produce wrong results. This makes it difficult
to spot that a mistake has been made, and even when the programmer realizes that something
has gone wrong, finding where the error is can be very difficult. Another example of a typical
logic error is when an incorrect formula is used e.g. Total_number = Previous_total –
New_number. There is nothing obviously wrong with the formula so it will work, but it won’t
produce the right answer because it should have been +. Notice that this is not an arithmetic
error, the computer will do the arithmetic perfectly, and it is the logic that is wrong.
Run Time Errors: This is sometimes thought of as a type of logic error but is rather different
because the computer is asked to do something that is impossible. A good example is when a
computer is asked to divide by 0, this is impossible and would cause the program to fail.
• Tried and tested design techniques such as structured programming or object-oriented design.
• Conventions such as identifier tables, data structures and standard algorithms.
• Tried and tested modules or objects from program libraries.
Corrective Maintenance
Corrective maintenance of a program refers to the work required when a program is not
working correctly due to a logic error or because of a run-time error. Sometimes program errors
don’t become apparent for a long time because it is only under very rare circumstances that
there is an unexpected result or the program crashes. These circumstances might arise because
part of the program is not used often or because the data on an occasion includes extreme
values. Earlier corrective maintenance may also introduce other errors.
Adaptive Maintenance
It is the action of making amendments to a program to enhance functionality or in response to
specification changes.
Perfective Maintenance
The program runs satisfactorily. However, there is still room for improvement. For example,
the program may run faster if the file handling is changed from sequential access to direct
access.
Finite state machine (FSM): A machine that consists of a fixed set of possible states with a set
an inputs that change the state and a set of possible outputs.
State-Transition Table: A table that gives information about the states of an FSM.
State-Transition Diagram: A diagram that describes the behavior of an FSM.
A state-transition diagram can be used to describe the behavior of an FSM. Below figure shows
the start state as S1 (denoted by ). If the FSM has a final state (also known as the halting
state), this is shown by a double-circled state (S1 in the example).
If an input causes an output this is shown by a vertical bar. For example, if the current state is
S1, an input of b produces output c and transforms the FSM to state S2.