Section 9 - Algorithm Design and Problem Solving 9.1.1 - Using Abstraction Abstraction: it is the process of extracting information that is essential, and ignoring anything irrelevant, for a solution What is Abstraction? It is a part of computational thinking that enables computer scientists to develop clear models for a complex problem. It encourages the development of simple models for a specific purpose by removing unnecessary characteristics from the model. Benefits of removing unnecessary characteristics: 1. Time required to develop and send a program to the customer is reduced 2. A smaller program means shorter download times and less space taken up in memory 3. Greater customer satisfaction Stages of Abstraction: ● Stage 1: identify the purpose of the model of the situation that is to be built ● Stage 2: source of information needs to be identified, for example, observations, views of users and etc ● Stage 3: use information gathered from sources to identify what: ○ details need to be included in the model ○ how the details should be presented ○ what details need to be removed 9.1.2 - Using Decomposition What is Decomposition? It is a part of computational thinking that enables computer scientists to break a complex problem into smaller parts which can be further broken What is Pattern Recognition? Used to identify parts that are similar and could use the same solution. This leads to the development of reusable program code, such as subroutines 9.2.1 - Writing Algorithms that Provide Solutions to Problems Methods of Writing Algorithms: 1. Structured English: it is a method of showing the logical steps in an algorithm using straightforward English words and numbered step 2. Flowchart: shows diagrammatically the steps required for a task and in which order they’re executed using a set of symbols linked together with flow lines 3. Pseudocode: a method of showing the detailed logical steps in a algorithm using identifiers and math operators to represent a solution 9.2.2 - Writing Simple Algorithms using Pseudocode Identifiers: Each line of pseudocode is usually a single step in an algorithm. Identifier names used in pseudocode should be meaningful, and are usually case insensitive. Tip 1: it is a good practice to keep track of identifiers in an identifier table Identifier Name Description StudentName Store a student name Counter Store a loop counter StudentMark Store a student mark Pseudocode Statements for Writing Algorithms: Tip 2: to input a value INPUT StudentName Tip 3: to output a message, value or both OUTPUT “You have made an error” OUTPUT StudentName OUTPUT “Student name is “, StudentName Tip 3: to assign a value to a variable Counter ← 1 Counter ← Counter + 1 MyChar ← “A” LetterValue ← ASC(MyChar) StudentMark ← 40 Percentage ← (StudentMark / 80 * 100) Oldstring ← “Your mark is” Newstring ← Oldstring & “ ninety-seven’ Tip 4: operators used in pseudocode assignment statements + Addition * Multiplication & String Concatenation - Subtraction / Division ← Assignment Performing selection using IF and CASE statements: Relational Operators used in Pseudocode Selection Statements: = Equal to <> Not equal to > Greater than < Less than >= Greater than or equal to <= Less than or equal to Note: programming languages may not have the same selection constructs as pseudocode, so it’s important to be able to write a program that performs the same task as the solution in pseudocode To perform iteration using FOR, Repeat Until, and WHILE loops: Total ← 0 FOR Counter ← 1 to 10 OUTPUT “Enter a number” INPUT Number Total ← Total + Number NEXT Counter OUTPUT “The total is “, Total FOR Counter ← 1 to 10 STEP 2 OUTPUT Counter NEXT Counter A FOR loop have a fixed number of repetitions, the STEP increment is an optional expression that must be a whole number REPEAT OUTPUT “Please enter a positive number” INPUT Number UNTIL Number > 0 Statements in a REPEAT loop are always executed at least once Number ← 0 WHILE Number >= 0 DO OUTPUT “Please enter a negative number” INPUT Number ENDWHILE Note: statements in a WHILE loop may sometimes not be executed WHILE, REPEAT and IF statements make use of comparisons to decide whether statements within a loop are repeated. The comparisons make use of relational and logical operators (AND, OR, NOT). - The outcome of the comparisons are either TRUE or FALSE REPEAT OUTPUT “Please enter a positive number less than fifty” INPUT Number UNTIL (Number > 0) AND (Number < 50) A simple algorithm can be clearly documented using statements. A more realistic algorithm to find the average of a number of integers input would include: - Checks that all the values input are whole numbers - The number input to determine how many integers are input are positive This can be written in pseudocode: Total ← 0 REPEAT PRINT “Enter the number of values to average” INPUT Number UNTIL (Number > 0) AND (Number = INT(Number)) FOR Counter ← 1 TO Number REPEAT PRINT “Enter an integer value” INPUT Value UNTIL Value = INT(Value) Total ← Total + Value NEXT Counter Average ← Total / Number PRINT “The average of “, Number, “values is” , Average The identifier table for the algorithm: Identifier Name Description Total Running total of integer values entered Number Number of integer values to enter Value Integer value input Average Average of all the integer values entered 9.2.3 - Writing Pseudocode from a Structured English Description For writing in structured English, the wording needs to be unambiguous and easy to understand. Difference between Pseudocode and Structured English: Pseudocode is more precise and follows an agreed set of rules How to Write in Structured English: ● Variables that are used need to be identified and put in a identifier table ● Input and Output can be identified from the wording used ○ Enter, Read, Print, Write ● Any iteration required can be identified from the wording used ○ Loop, Repeat ● Selection can be identified from the wording used ○ If, Then, Choose ● Processed needed can be identified from the wording used ○ Set, Calculate For Example: Structured English 1 Enter time taken to run marathon in hours, minutes and seconds 2 Calculate and store the marathon time in seconds 3 Output marathon time in seconds Identifier Table Identifier Name Description MarathonHours The hours part of the marathon time Marathon Minutes The minutes part of the marathon time MarathonSeconds The seconds part of the marathon time TotalMarathonTimeSeconds Total marathon time in seconds Converting from Structured English to Pseudocode: 9.2.4 - Writing Pseudocode from a Flowchart Flowcharts are diagrams showing the structure of an algorithm using an agreed set of symbols Flowcharts can be used to identify any variables required. Each flowchart symbol can be used to identify and write one or more pseudocode statements. For Example: This is an example of a flowchart of an algorithm that can be used to check an exam grade 9.2.5 - Stepwise Refinement When an algorithm is written to solve a more complex problem, decomposition is used to break the problem down into smaller and manageable parts. - This is called stepwise refinement Stepwise Refinement: the practice of dividing each part of a larger problem into a series of smaller parts and so on How Step-Wise Refinement is done: Take a look at the first step of the Structured English program: The first step can be further broken down: Each of the steps can be further broken down: Section 10 - Data Types and Structures 10.1.1 - Data Types What is the importance of data types? Data types allow programming languages to provide classifications for items of data, so that they can be used for different purposes The data types: Data Type Boolean Definition Logical values, True (1) and False (2) Pseudocode Python BOOLEAN bool Char Single alphanumeric character CHAR not used Date Value to represent a date DATE class datetime INTEGER int REAL float STRING str Integer Whole number, positive or negative Real Positive or negative number with a decimal point String Sequence of alphanumeric characters Declaring data types: Before data can be used, the type needs to be decided. It is done by declaring the data type for each item to be used. - The data item is identified by a unique name called an identifier Declaring data type in pseudocode: ● Format: DECLARE <identifier> : <data type> ● Example: DECLARE myBirthday : DATE 10.1.2 - Records Composite Data Type: a data type constructed using several of the basic data types available in a programming language Record: it is a composite data type formed by the inclusion of several related item of different data types Note: a record contains a fixed number of items Record data type in pseudocode: Format Example TYPE <Typename> DECLARE <identifier> : <data type> DECLARE <identifier> : <data type> DECLARE <identifier> : <data type> ENDTYPE TYPE TbookRecord DECLARE title : STRING DECLARE author : STRING DECLARE publisher : STRING DECLARE noPages : INTEGER DECLARE fiction : BOOLEAN ENDTYPE 10.2.1 - 1D Arrays Array: it is a data structure containing several elements of the same data type. The elements can be accessed using the same identifier name - Lower Bound: the index of the first element in an array Upper Bound: the index of the last element in an array What is a 1D Array? It can be referred to as a list Declaring 1D Array in pseudocode: ● Format: DECLARE <identifier> : ARRAY [LB:UB] OF <data type> ● Example: DECLARE myList : ARRAY [0:8] OF INTEGER ● Process: myList[7] ← 16 10.2.2 - 2D Arrays What is a 2D Array? It can be referred to as a table, with rows and columns Declaring 2D Arrays in pseudocode: The lower bound for rows (LBR) and upper bound for rows (UBR), the lower bound for columns (LBC) and upper bound for columns (UBC) and data type is included. ● Format: DECLARE <identifier> : ARRAY [LBR:UBR , LBC:UBC] OF <data type> ● Example: DECLARE myArray : ARRAY [0:8 , 0:2] OF INTEGER ● Process: myArray [7,0] ← 16 10.2.3 - Using a Linear Search Linear Search: it is a method for finding items stored in an array. Each element of the array is checked from lower to upper bound until the item is found. Example of Linear Search: The search algorithm to find if an item is in the populated 1D array myList could be written in pseudocode as: Algorithm Explained: - The variables upper and lower bound is used to adapt for different lengths of a list - A repeat-until loop is used so that the algorithm is efficient 10.2.4 - Using a bubble sort Bubble Sort: a method of sorting data in an array into alphabetical/numerical order by comparing items and swapping them if they’re in the wrong order Example of Bubble Sort: The bubble sort algorithm to sort the populated 1D array myList could be written in pseudocode as: 10.3 - Files Computer programs store data in a file. Every file is identified by its filename Handling text files in Pseudocode Pseudocode for opening a file: OPEN <file identifier> FOR <file mode> 3 modes for opening files: ● READ - reads data from the file ● WRITE - writes data to the file and can overwrite existing data ● APPEND - adds data to the end of the file Pseudocode for READ mode: READFILE <file identifier> , <variable> Pseudocode for WRITE/APPEND mode: WRITEFILE <file identifier> , <variable> Note: variable must be of data type string The EOF Function: This function is used to test for the end of a file. The TRUE value is returned if the end of the file is reached, or FALSE otherwise. - Pseudocode for EOF function: EOF (<file identifier>) Pseudocode for closing a file: CLOSEFILE <file identifier> Example pseudocode for editing a text file → 10.4.0 - Abstract Data Types (ADTs) What is an Abstract Data Type (ADT)? It is a collection of data and a set of operations on that data. There are three ADT’s, stack, queue and linked list - Uses of Stacks: memory management, expression evaluation, backtracking in recursion Uses of Queues: management of files sent to a printer, buffers used in keyboards, scheduling Linked Lists: using arrays to implement a stack, queue and binary tree What is a Stack, Queue and Linked List? Stack Queue Linked List It is a list containing items operating on the last in, first out (LIFO) principle. It is a list containing items operating on the first in, first out (FIFO) principle. it is a list containing items where each item in the list points to the next item in the list. The first item added to a stack is the last item removed The first item added to a queue is the first item removed A new item is always added to the start of the list Note: - Items can be added to the stack (push) and removed (pop) - Items can be added to the queue (enqueue) and removed (dequeue) Use of Pointers: Stacks, queues and linked lists make use of pointers to manage their operations. Items in stacks and queues are added at the end. Linked lists use an ordering algorithm to order them in ascending or descending order. Pointers used by a Stack Pointers used by a Queue Front Pointer: points to the first item in the stack Front Pointer: points to the first item in the queue Top Pointer: points to the last item in the stack Rear Pointer: points to the last item in the queue The pointers are equal when there’s only one item The pointers are equal where there’s only one in the stack item in the queue Pointers used by a Linked List: A start pointer points to the first item in the linked list. Every item is stored together with a pointer to the next item. This is a node. The last item in the linked list has a null pointer. 10.4.1 - Stack Operations The value of the base pointer remains the same during stack operations. A stack can be implemented using an array and a set of pointers Pseudocode for Stack Operations: 10.4.2 - Queue Operations The value of the frontPointer changes after dequeue, but the value of the rearPointer changes after enqueue. How is a queue used? A queue is implemented using an array and a set of pointers. The queue should be managed as a circular queue to avoid moving the position of items in an array every time an item is removed. Pseudocode for Queue Operations: 10.4.3 - Linked List Operations A linked list is implemented using two 1D arrays: - One for items in the linked list, - And another for the pointers to the next item in the list, and a set of pointers Items can be removed from any position in the linked list, the empty positions in the array must be managed as a empty linked list, called the heap For Example The startPointer = –1, as the list has no elements. The heap is set up as a linked list ready for use. The startPointer is set to the element pointed to by the heapPointer where 37 is inserted. The heapPointer is set to point to the next element in the heap by using the value stored in the element with the same index in the pointer list. Since this is also the last element in the list the node pointer for it is reset to –1. The startPointer is changed to the heapPointer and 45 is stored in the element indexed by the heapPointer. The node pointer for this element is set to the old startPointer. The node pointer for the heapPointer is reset to point to the next element in the heap by using the value stored in the element with the same index in the pointer list. Section 11 - Programming 11.1.1 - Constants and Variables Constant: it is a named value that can’t change during the execution of a program Variable: it is a named value that can’t change during the execution of a program Note: all variables and constants should be declared before use. Constants will always be assigned a value when declared Good Practices: 1. Assigning values to any variables that are used 2. Creating a identifier list and check that every variable has been declared and assigned a value Question: write an algorithm using pseudocode to calculate and output the volume and surface area of a sphere for any radius that is input Solution: Table 11.1 shows the declaration of some of the constants and variables Table 11.2 shows examples of input statements Table 11.3 shows how to check the value of the radius Table 11.4 shows how to calculate the volume and surface area Table 11.5 shows how to output the results Complete Program: 11.1.2 - Library Routines Library Routines: a tested and ready-to-use routine available in the development system of a programming language that can be incorporated into a program A programming language IDE includes a standard library of function and procedures as well as an interpreter/compiler 11.2.1 - CASE and IF The diagram above shows that choices can be made using a condition based on: - The value of the identifier being considered, for example <10 A range of values that the identifier can take, for example 1:10 The exact value that the identifier can take, for example 10 If an identifier meets none of the conditions given, there is OTHERWISE An Example: 11.2.2 - Loops Loops: enables sections of code to be repeated as required. There are different types of loops: - A count-controlled loop for…next - A post condition loop repeat…until - A precondition loop while…do…endwhile Table 11.8 shows postcondition loops in VB and Java Table 11.9 shows precondition loops in 3 programming languages 11.3.1 - Procedures Procedure: a small section of a program that performs a specific task. It is defined once and can be called many times Defining a procedure using pseudocode: Format PROCEDURE <identifier> <statement> ENDPROCEDURE CALL <identifier> Example PROCEDURE stars (Number: INTEGER) FOR Counter 1 TO Number OUTPUT “*” NEXT Counter ENDPROCEDURE CALL stars Table 11.10 shows how to define this procedure in 3 programming languages Table 11.11 shows hows to call the procedure Defining a procedure with parameters using pseudocode: ● Format: PROCEDURE <identifier> (<parameter 1> : <datatype>, <parameter 2 : <datatype> <statements> CALL <identifier> (Value 1, Value 2) ● Example: PROCEDURE stars (Number: INTEGER) OUTPUT “************” ENDPROCEDURE CALL stars(7) Table 11.12 shows how to define a procedure with a parameter in 3 programming languages Methods of passing a parameter to a procedure: 1. By Value: if a variable is used, the value of the variable can’t be changed within the procedure 2. By reference: the value of the variable passed as the parameter can be changed by the procedure Defining a procedure with parameters passed by reference in pseudocode: ● Format: PROCEDURE <identifier> (BYREF <parameter 1> : <datatype> <statements> ENDPROCEDURE ● Example: PROCEDURE celsius (BYREF temperature : REAL) Temperature ← (temperature - 32) / 1.8 ENDPROCEDURE CALL celsius(myTemp) Table 11.13 shows how to pass parameters in 3 programming languages 11.3.2 - Functions Functions: it is a block of organized, reusable code that is used to perform a single, related action Defining a function without parameters in pseudocode FUNCTION <identifier> RETURNS <data type> <statements> ENDFUNCTION Defining a function with parameters in pseudocode FUNCTION <identifier> (<parameter 1> : <datatype>) RETURNS <data type> <statements> ENDFUNCTION Note: RETURN is used as one of the statements in a function to specify the value to be returned. It is usually the last statement in the function Section 12 - Software Development 12.1.1 - The purpose of a Program Development Life Cycle Program Development Life Cycle: the process of developing a program set out in the 5 stages of analysis, design, coding, testing and maintenance What is the purpose of a program development life cycle? A program that’s being developed may require changes at any time in order to deal with new errors that are found, hence, the stages are referred to as a life cycle until the program is no longer used 12.1.2 - Stages in the Program Development Life Cycle The stages of the Program Development Life Cycle: 1. Analysis 2. Design 3. Coding 4. Testing 5. Maintenance Analysis: the problem needs to be clearly defined so that the solution can be found (requirements specification). This stage involved a feasibility study, investigation and fact finding Design: this stage requires the programmer to know what to do, tasks to be completed, how each task is performed and work together. This is documented using structure charts and etc Coding: this stage involves writing the program using a programming language Testing: this stage involves testing the program using different sets of data to test if the program works the way it is intended Maintenance: this stage involves maintaining the program, which can be done by correcting any errors or improving the functionality 12.1.3 - Different Development Life Cycles The 3 models of program development life cycle: 1. The waterfall model 2. The iterative model 3. Rapid Action Development (RAD) The Waterfall Model: this model works by making sure each stage is completed before moving to the next one. - Used for small projects, which have known requirements Principles ● ● ● Benefits Linear (each stage completed) Full documentation Low customer involvement ● ● ● Easy to manage No stage overlap Works well for small programs Drawbacks ● ● ● Difficult to change requirements later Working program produced late Not suitable for big projects The Iterative Model: this model works by developing a simple subset of the requirements, then enhances the model and runs the cycle again. The cycle is repeated until the full system is developed. - Used for projects which have major requirements but some details change Principles ● ● ● Benefis Incremental development Working programs produced High customer involvement ● ● ● Easier to test and debug small programs More flexible Customers involved at each iteration Drawbacks ● ● ● Not suitable for short projects Needs good planning Whole system needs to be defined at the start Rapid Application Development (RAD): it is a development cycle that develops different parts of requirements in a parallel manner, using different teams. - Used for complex projects that need to be developed in a short time Prototyping is used to show customers for early feedback Principles ● ● ● Minimal planning Reuses code where possible High customer involvement Benefis ● ● ● Reduced development time Frequent customer feedback Flexible as requirements evolve from feedback Drawbacks ● ● ● System needs to be modular Requires strong team of skilled developers Not suitable for simple projects 12.2.1 - Purpose and Use of Structure Charts Structure Chart: it is a modelling tool in program design used to decompose a problem into a set of sub-tasks - It shows the hierarchy of different modules and how they connect/interact How to draw a structure chart? ● Each module is represented by a box and parameters are passed between modules using arrows pointing towards the module receiving the parameter ● ● A diamond shaped box is used for a condition Repetition is shown by adding a semi-circular arrow on the module to be completed Figure 12.5 - A structure chart for converting from Farenheit to Celsius Figure 12.6 - A structure chart for converting from Fahrenheit to Celsius using selection Figure 12.7 - A structure chart for converting from Farenheit to Celsius using iteration Converting from Structure Chart to Pseudocode: Figure 12.8 - A structure chart for calculating volume and surface area Step 1: create a identifier table Step 2: declare constants and variables Step 3: the “calculate volume” and “calculate surface area” modules needs to be defined as functions Step 4: the input and output modules are defined as procedures Step 5: the combined pseudocode, including selection and repetition 12.2.2 - Purpose and Use of State-Transition Diagrams to Document Algorithms Finite State Machine (FSM): it is a mathematical model of a machine that can be in one of a fixed set of possible states. One state is changed to another by an external input (transition) State Transition Diagram: a diagram showing the behavior of a finite state machine Characteristics of a State Transition Diagram ● ● ● ● ● ● States are represented as nodes (circles) Transitions are represented as interconnected arrows Events are represented as labels on arrows Conditions can be specified in square brackets after the event label The initial state is indicated by an arrow with a black dot A stopped state is indicated by a double circle State Transition Table for unlocking a door: State Transition Diagram for unlocking a door 1. 2. 3. 4. Locked and waiting for the input of the first digit Waiting for the input of the second digit Waiting for the input of the third digit Unlocked 12.3.1 - Ways of avoiding and exposing faults in programs How to avoid faults in a program: - Having the provision of a comprehensive and rigorous program specification at the end of the analysis phase - Use of methods such as structure charts, state-transition diagrams and pseudocode at the design stage - Use of programming disciplines such as information hiding, encapsulation and exception handling at the coding stage - Exposing faults or bugs in a program at the testing stage - Fixing future faults that may arise at the maintenance stage 12.3.2 - Location, Identification and Correction of Errors Syntax Errors; they are errors in the grammar of a source program. Syntax errors need to be corrected before they are executed Logic Errors: they are errors in the logic of a program, meaning the program doesn’t do what it is supposed to do. They are found when the program is tested How are trace tables used to find errors in programs? Trace tables show the process of dry-running a program with columns showing the values of each variable as it changes Run-Time Errors: occurs when the program is executed. The program may halt or go into infinite loop, which has to be stopped by brute force 12.3.3 - Program Testing Steps for Program Testing in Analysis Stage: ● Step 1: a test strategy is required to show an overview of the testing required to meet the requirements ● Step 2: a test plan is drawn showing all the stages of testing and every test that will be performed Note: there are several formal methods of testing used to ensure that a program is robust and works to the required standard Program Testing in Design Stage: Pseudocode is written, which can be tested using a dry-run, where the developer works through a program and documents the results using a trace table Procedure to perform a calculation: Truth Table for procedure: Walkthrough: it is a formal version of a dry run using predefined test cases. It is where another member of the development team dry-runs the pseudocode During the program development and testing, each module is tested. Test plans are set out as a table: Types of Test Data: ● ● ● ● Normal Test Data: data that is accepted by a program Abnormal Test Data: data that should be rejected by a program Extreme Test Data: data that is on the limit of that accepted by a program Boundary Test Data: data that is on the limit of that accepted by a program or data that is just outside the limit of that rejected by a program Example of Extreme Test Data: number >=12 AND number <=32 extreme test data: 12, 32 Example of Boundary Test Data: number >=12 and number <=32 boundary test data: 11, 12 and 32, 33 Types of Testing: - Whitebox Testing: testing of how each procedure works including testing the structure and logic of every program module Blackbox Testing: testing a module’s inputs and outputs - Integration Testing: testing of separate modules to ensure that they work together Stub Testing: use of dummy modules for testing purposes Testing a Program as a whole: 1. Alpha Testing: program is tested in-house by the development team 2. Beta Testing: program is tested by a small group of users before being released 3. Acceptance Testing: used for the completed program to show to the customer it works as required 12.3.4 - Program Maintenance 3 categories of Program Maintenance: ➢ Corrective Maintenance: used to correct any errors that appear during use ➢ Perfective Maintenance: used to improve the performance of a program during its use ➢ Adaptive Maintenance: used to alter a program so it can perform any new tasks required by the user