Computational Thinking, Programming and PHP PHP PHP is what is called a server side programming language. This means it resides on servers and allows web pages to communicate with the databases on these servers. It is used by sites like YouTube and Facebook to generate pages that look different for different users. It is a bit easier to get to grips with than Java for example. There are less rules and structures to abide by and you can get going pretty quickly. The key thing about learning to program is that it is a transferable skill, the language is almost irrelevant. The skill of programming is about a way of thinking and using the tools at your disposal to solve problems and achieve goals. The programming constructs that you will learn in this course can be found in virtually all other programming languages. So it is safe to say, that if you learn to program, you should be able to move to any language you want as you have understood “how” to program. Link to course document (Use of Programming languages) 4.3.6 Define the terms: variable, constant, operator Variables Every program needs to give the programmer access to variables. Variables are the storage space that the programmer can use to store values required in a program, for example a person’s name or age. Here is how a variable is declared and assigned a value in PHP:
$first_name = ‘Alfred’;
This means that the storage location called $first_name contains the word ‘Alfred’. If the programmer then references that storage location then the word ‘Alfred’ would be substituted for the variable name $name. For example:
print $first_name;
Would not see ‘$first_name’ printed to the screen, but instead the contents of that storage location, in this case ‘Alfred’. Naming Variables Most programming languages have conventions around how variables should be named. It goes without saying that the variable name should be meaningful and make sense to someone else who might look at your code, for example $age is more meaningful than $a.
It may be that you want to use more than one word to create a meaningful variable name. If this is the case then you have 2 options. Option 1: use capital letter to delimit your words e.g $firstName or $ageInDays Option 2: use an underscore as the delimiter e.g. $first_name or $age_in_days PHP restricts the characters that can be used as part of a variable name to letters and numbers, so things like ‘!’ or ‘@’ are unacceptable characters to use as part of a variable name. Variable types PHP does not require the user to specify the variable type, it is able to work this out from what is stored inside. You will find that this flexibility does not exist in other languages. It is important to know what type of variable you are dealing with, as this will have implications as to what you can do with that variable. $firstName = ‘Alfred’; (PHP knows that this is what is called a String) $age = 56; (PHP knows that this is a numeric value) $activeClubMember = TRUE; (PHP recognises this as a Boolean value) Strings A string is a variable type that can store combinations of letters, numbers and symbols. So could be used to store things like an address or an ID number. The operations that you might perform on a string will be distinctly different from that of a number. For example you might ask PHP to capitalise the string, this operation would not work with a number and might generate an error. Similarly, you would be unlikely to try to add to strings in an arithmetic fashion, e.g. $name1 = ‘Alfred’; $name2 = ‘Batman’; $newName= $name1 + $name2; The outcome of this operation is nothing, PHP won’t do it. However, if we had the following scenario: $name1 = “12mup”; $num1 = 45; $newValue = $name1 + $num1; In this case, the value in $newValue is actually 57, PHP can see the 2 numbers at the beginning of our string and quietly converts them to be able to take part in the addition.
Concatenating Strings Concatenation is just another word for joining two or more items together to make a new longer item. It might be necessary to join strings and numbers together to store new values or print them to the screen. To do this we use the ‘.’ symbol: $name = ‘Alfred’; $age = 45; echo “Welcome to the Tax Calculator “.$name; (what would this print?) echo “You look very young for “.$age; (how about this?)
or $name = ‘Alfred’; $age = 45; $password = $name.$age; (would create the password Alfred45 ) String Functions A function groups a number of program statements into a unit and gives it a name, it is reusable i.e. it can be executed from as many different points in a program as required. There are a number of functions that can be performed using strings. ucfirst($String variable) – makes the first letter uppercase $var1 = ‘leona’; $var2 = ucfirst($var1); will store ‘Leona’ in var2
strtolower($string variable) – convert all letters to lowercase $var1 = ‘AlEsSANDRo’; $var2 = strtolower($var1); will store ‘alessandro’ in var2
strtoupper($string variable) – convert all letters to uppercase $var1 = ‘chris’; $var2 = strtoupper($var1); will store CHRIS in var2
trim($string variable) – remove any blanks at the beginning or end of the string $var1 = ‘ pedro ‘; $var2 = trim($var1); stores ‘pedro’ in var2
ucwords($string variable) – capitalises the first letter of each word $var1 = ‘hiu chun’; $var2 = ucwords($var1); stores Hiu Chun in var2
strlen($string variable) – gives the length of the string $var1 = ‘Hong Kong’; $var2 = strlen($var2); stores the number 9 in var2, the space is counted as well These are not all of the possibilities, just some useful ones. If you need any other functions you can find them here http://php.net/manual/en/ref.strings.php
Numbers Some programming languages have different types of number variables, mostly related to precision. For example Java would require 2 different types of number variables to store 34 and 34.2. The whole number is termed an integer and the number with the fractional part of type double. There is no such need to do this in PHP. So this is acceptable: $a = 3; $b = 4; $a = $a/$b; (the answer to this is of course 0.75, which can be stored in $a)
Boolean Types Boolean variables can only have 2 values, TRUE or FALSE. $check = TRUE; $check = FALSE; Boolean types can be used to make decisions in programs and are usually used in conjunction with comparisons and If statements. Constants A constant is a reference to a value in a program that cannot be changed during the program’s execution. Programming languages often make syntactic distinction between constants and variables. A constant is defined once but can be referenced as many times as necessary in a program. There is an obvious advantage to this in many instances. Let’s say we wanted to use Pi in a program to 4 decimal places (3.1415). We could set it as a constant and refer to it in the knowledge that it won’t have changed. This will help in the maintenance of your program as well. Let’s say that your client wishes more precision and wants to extend the number of decimal places in Pi. You would need to search through your program and identify all of the places where you used 3.1415 and add 2 more digits on. If you had defined it as a constant, you only need to change it in one place to affect change throughout the program. Constants are defined in PHP like so: –
define(“NAME”, “value”);
–
for example: define (“PI”, “3.1415”);
We could then use Pi like so: $area = PI * $r * $r; Note how a constant is syntactically different from a variable. Link to course document – 4.3.7 Define the operators =,≠, <,<=,>,>=, mod, div Operators The usual numerical operators can be used with regard to numbers in PHP. $a = 4; (= is the assignment symbol in most languages) $b = 5; $c = $a + $b; (adds 4 and 5 and assigns the value to $c)
$d = $a - $b; (takes 5 away from 4) $e = $a/$b; (divides 4 by 5) $f = $a*$b; (multiplies 4 by 5) $g = $a % $b;
(called modulo division where the answer is the remainder of the division, in this case 4, because 4/5 is 0 remainder 4)
There are some shorthand ways to write the same operations, only if you are storing the answer in one of the variables involved: $a = 3; $b = 2; $a += $b; (add a and b together and store the answer in a) $a -= $b: (take b away from a and store the answer in a) $a /= $b; (divide a by b and store the answer in a) $a *= $b; (multiply a by b and store in a); $a %= $b; (modulo division of a by b, storing the answer in a)
Numbers can also be concatenated using the same method as strings. $a = 4; $b = 5; $c = $a.$b; (will store the number 45 in the variable c) More on operators Not every school will use PHP, so the exam questions that involve programming are far more generic and will use symbols for operators as follows: Operation assignment Comparison to see if equal Does not equal Less than Less than or equal to More than More than or equal to Modulo division Division
Symbol = == â&#x2030; < <= > >= mod /
Links to course document 4.3.9 Construct algorithms using loops, branching 4.1.7 Explain the relationship between the decisions and conditions of a system If Statement An â&#x20AC;&#x2DC;Ifâ&#x20AC;&#x2122; statement is used to create different pathways in a program. To represent this visually we could use a flowchart.
In PHP an If statement is used as follows: If ( comparison to be made){ Code to be executed if comparison is true; } Else { Code to be executed if comparison is false; } Note the curly brackets(parenthesis) enclosing the code to be executed. There might be any number of lines of code to be executed, it is not restricted to only one.
The previous example will only work if we only have two options to choose between. If we need three outcomes then we can use a variation of the ‘If’ statement. If (comparison) { Code if comparison is true; } Else if( second comparison) { Code if second comparison is true; } Else { Code if none of the comparisons are true; } We can continue to add ‘Else If’s and Else’s as necessary, depending on the number of outcomes we need. However, after a while, it gets difficult to keep track of the different clauses and conditions. A more readable structure to solve this problem is the ‘Switch’ statement. Switch The Switch structure is used to overcome the problem of choosing between many alternatives. Have a look at the example below: switch($state){ case "CA": $tax = 0.09; break; case "NY": $tax = 0.11; break; case "WA": $tax = 0.12; break; case "PA": $tax = 0.05; break; default: }
$tax = 0.10;
In the switch($variable) part, we include the variable we want to check the value of, in this case a state. Each possibility then becomes a ‘case’. So if it is the ‘case’ that the state is ‘NY’ then the tax value is set to 0.11. The break statement is included so that as soon as one case is true, no others are checked, the program leaves the switch statement when one of the ‘cases’ becomes true. The default value is added in the possibility that none of the ‘cases’ are true, it is a bit like the Else section of the If structure. It should be noted that the Switch construct will only work for values matching the cases exactly. Comparisons In many programs it will necessary to compare values so that it can be decided what next course of action is. For example Lionel will provide different access rights to users who have a staff log-in compared to those who have student usernames. It is important at this point to talk about assigning a value and a potential pitfall of confusing this with a comparison. Assigning a value looks like this: $var1 = 23; (the value 23 is assigned to the variable var1, note that there is a single = sign used here) Comparing 2 values is similar but has one crucial difference $var1 == 23; (does $var1 equal 23?) this would normally be included alongside an if statement or even a while statement e.g. If($var1 == 23){ Code if true;} Else{ Code if false;}
Other operators that could be substituted for the == could be: === is identical(including type e.g. string) > greater than < less than >= greater than or equal to <= less than or equal to != not equal to <> Not equal to
These comparisons generate a boolean value, a comparison can either be true or false. Course document link: 4.1.5 Identify the decisions required for the solution to a specified problem, 4.1.6 Identify the condition associated with a given decision in a specified problem Logical Operators: Complex Comparisons On occasion it will be necessary to build more complex conditions to be used in the ‘if’ statement or while loop. For example you may want to execute certain code when 2 values are true e.g $x==6 AND $y==7, but how would we code this? If($x==6 && $y==7){ …;}
Alternatively If($x==6 AND $y==7){ …;}
It may also be the case that you need to have 1 of 2 conditions be true rather than both. E.g If($x==6 OR $y==7){ Code to be executed if one of the conditions is true;} Else{…;} An alternative notation for OR is ||. It is possible to combine ANDs and ORs to build increasingly complex conditions to satisfy the needs of the code you are writing. If($city == “Springfield” AND ($state = “MA” OR $state= “VT”)){ This condition would be true if the city was equal to Springfield and the state was either MA or VT. It should also be pointed out that there is operator precedence. The symbols &&/|| are more important in terms of precedence than AND/OR so should not be mixed otherwise you could get unexpected results. Repetition So far we have only written programs that we could call ‘linear’. They go through the instructions sequentially from start to finish. We need some way of ensuring repetition can take place and there are a couple of ways to do this.
Conditional loop A conditional loop is one that uses a condition to decide whether to continue or not. While($userInput != “Stop”){ Code to be executed; } The loop above would continue until the variable $userInput became equal to stop. Therefore, as a programmer you cannot be sure how long this loop might repeat. It might be once it could be 100 time. The condition above is simple, but you can use the comparison and logical operators to build a condition that suits your requirements. There is a variant of the while loop that behaves in a slightly different manner. Look at this example: Do{ Code to be executed; }while($userInput != “stop”); This loop, like the previous example, continues to execute until the variable $userInput becomes equal to ‘stop’. However, there is a subtle difference here. The loop above will execute the code at least once every time. The comparison below explains this difference: Example 1 $num = 15; While($num <10){ //the condition is false, so the loop doesn’t get started Echo $num; //won’t get executed }
Example 2 $num = 15; Do{ Echo $num; //gets executed the first time through } while($num<10); // condition is false so loop stops
Fixed Loop The second type of loop is sometimes referred to as a fixed loop. This is because the programmer can control how many times it repeats. In most programming languages this is called a For loop, and PHP is no different. For($counter = 0; $counter < 10; $counter++){ Echo $counter; } This code would generate a list of numbers from 0-9. Let’s break the parts of the ‘for statement’ down: $counter=0 – sets up a variable to be used to count the number of times the loop has been executed, initialise it to zero. $counter < 10 – the check to see whether the loop should continue. In this example the loop should stop when $counter is 10 or more e.g. it continues whilst $counter is less than 10. $counter++ - adding to the counter that takes place at the end of each time round the loop. In this example, only 1 is added each time but any value could be used.
Comments Commentary allows us to make programs readable. There are a number of reasons as to why it is necessary to make a program readable. As novice programmers, you can use comments to explain complex sections of your code, to help you understand it better when you return to it. In industry comments are used for similar reasons. Very often there will be more than one person involved in the creation of a piece of software and comments can be used again to explain complex sections of code to your colleagues. Adding comments is very simple: /* this section of code is used to work out a grade from a raw score * Raw score is compared with the cut off scores * And an appropriate grade is printed */ $rawScore = 63; If($rawScore >= 70 ) { echo “A”;} Else if ($rawScore >= 60 AND <70) { Echo”B”;} Else{ Echo “C”} ?> The example above shows how to make a block comment, if you simply want to explain a line of code the syntax is slightly different: If($rawScore >=60 AND $rawScore <=69) { // check to see if the raw score is between 60 and 69 Link to course document 4.3.13 Construct algorithms using pre-defined sub-programmes, onedimensional arrays and/or collections One Dimensional Arrays So far the programs we have written have relied on a few variables to operate successfully. These variables are stored as separate entities and can cause some headaches with regard to the amount of code needed to manipulate them. A data structure that can overcome some of these problems is an array. An array can be visualised like so: [0] “Pete”
[1] [2] “Vivian” “Sahil”
[3] [4] “Bessie” “Alan”
[5] “Leia”
The diagram attempts to show that an array would hold consecutive space in memory, each with an index (the number in square brackets). This means the array can be treated as a whole and as individual elements giving it a lot of flexibility. It should also be noted that the first index in the array is 0, meaning that even though there are 6 elements in the array the last index is 5. The is always the case, if the array had n items in it, the index of the last element is n-1. It is also worth noting at this stage that strings can sometimes exhibit the behaviour of an array. Each of the individual characters can be thought of as taking up a position in an array like so: 0 C
1 A
2 L
3 I
4 F
5 O
6 R
7 N
8 I
9 A
Creating an array is very straightforward. $employees = array(“Pete”, “Vivian”, “Sahil”, “Bessie”, “Alan”, “Leia”); This line of code would create the array illustrated above. To demonstrate how an array behaves we will look at how you might print the contents of an array. for($counter = 0; $counter<count($employees); $counter++){ echo $employees[$counter]."\r"; } In this example we work out the number of elements in the array using the “count” function and then print each array element using $counter as an index. In other programming languages this would be the typical way to run through an array and use each element individually, the index appearing in square brackets. PHP affords another way to move through an array: foreach ($employees as $value){ echo $value."\n"; } In this loop $value becomes the substitute for each of the elements in the array. This loop achieves the exact same outcome as the previous example. These examples use a small dataset but the ability to cycle through the array using 3 lines of code is unchanged no matter how big the data set becomes. This is very useful and time saving.
Higher Level Only Link to course document (5.1.4 Describe the characteristics of a 2D array, 5.1.5 Construct algorithms using 2D arrays) 2D Arrays Let’s imagine that as well as the employee names we wanted to also store their position in the organisation. We could use the array as follows: $employees = array(“Pete”, “Treasurer”, “Trevor”, “President”, “Sally”, “CEO”, “Raghav”, “Director”) We would simply need to remember that every second element of the array contained a position and not a name. This is not an ideal situation as it would a layer of complexity to any code we wrote. We can make it easier for ourselves by using an associative array. In many other programming languages this type of array is called a 2D array. They can be visualised like so: [0] [1]
[0] “Pete” “Treasurer”
[1] “Trevor” “President”
[2] “Sally” “CEO”
[3] “Raghav” “Director”
To access an individual element we would use the 2 indices: employees[0][1] is the word “Treasurer” for example. In this area PHP is slightly different. We have already established that they are called associative arrays in PHP. We declare them in a similar way to the declaration of a regular array. An associative array can be thought of as an array of arrays: $employees = array(array(name=> “Pete”, position=> “Treasurer), array(name=> “Trevor”, position=> “President”), array(name=>”Sally”, position=>”CEO”), array(name=>”Raghav”, position=>”Director”)); So in PHP it would actually look more like this: name position
[0] “Pete” “Treasurer”
[1] “Trevor” “President”
[2] “Sally” “CEO”
[3] “Raghav” “Director”
To access an individual element of the associative array we would use the following: $employees [1][‘position’]; This would give us access to the word “President”. We could loop through the array using a similar method to before having a $counter variable to move through each array within the array. However, as the row indices are now text, this becomes difficult. Fortunately, PHP offers a solution to this.
foreach($employees as $person){ echo ($person['name']." , ".$person['position']); } $person becomes a substitute for each individual array. We can use the “row” indices to access each individual element of the arrays within the array. Finally, a useful function to know about is the print_r( ) function. You can use it as follows: print_r( $employees); //$employees should be an array or associative array It will print the entire contents of $employees which may be useful for debugging purposes, to understand the structure of the array and whether you have implemented it the way you thought you had. The following is not associated with any particular part of the course but will make programming in PHP far more interesting Getting User Input Up until now our programs have relied upon you the programmer “hard-coding” the variable values into the program. This does not offer the flexibility that programs require to be of any use. PHP is a scripting language, more specifically a server side scripting language. This means the code communicates with database servers and is usually woven into the HTML of the web pages we use. We can use this HTML to gather the input of the user. There are many ways to do this but we are going to use a simple(if slightly out-dated) method called a form. The reason for this is that we want to concentrate on the PHP side of things for the time being. Forms can be easily created in Dreamweaver, using drag and drop. If you do not have Dreamweaver then you can access an example html version of a form on the coursepage. You can edit it in notepad and save it as html.
Forms A form has a number of different elements. They are explained below. <form id="tax" name="tax" method="get" action="firstformtax.php"> The form has an ID and a name so that it can be referenced from other parts of the page or our PHP code. The method type refers to how the data is collected and processed and is explained below. The action section refers to where the data is sent, for example, you may want your data to be sent to a different page from the one that contains the form. All of the items used to collect data in the form should be included within the<form> html code. Using the method “get” produces the following result:
As you can see from the URL, when the form is submitted using the get method, the data submitted is appended to the URL of the page that it is sent to. This makes it very unsecure, as the data is visible publically. The second method associated with the submission of the form is the “post” method. It does the opposite of the “get” method. The data is collected and then hidden from view. In both cases, the data submitted is essentially added to an associative array given the name of the method. It is is “get”: $_GET[‘state’]; //would access the value stored for state in the example above. The syntax is exactly the same if the method has been collected using “post”: $_POST[‘state’]; Some additional requirements We do not want to collect any information until the user clicks on the submit button, so in PHP we need to program for this. if(isset($_GET['taxForm'] )== "Submit") //checks to see if the user clicks the Submit button within the taxForm
Link to course document 4.3.13 Construct algorithms using pre-defined sub-programmes, 4.1.1 Identify the procedure appropriate to solving a problem Functions Functions are very useful and flexible tool in programming. We have already used functions in the course such as count and substr. These are pre-written functions(pre-defined sub-programmes) that carry out a particular task for us and give us a result. If we take substr as an example: $state = ‘California’; $short_code = substr($state, 0,2); // removes ‘Ca’ from the string and stores it in our variable This code would copy the first 2 letters of the string and store them in the $short_code variable. Let’s look more closely at how the substr function can do this. Some functions need what we call parameters to perform their tasks. Substr needs 3 parameters: Substr(a string, start value, end value) Substr needs a string to take a ‘chunk’ from, an index of where to begin the ‘chunk’ and then a value for the length of it. Remember that strings can exhibit behaviours of arrays and this is one of those instances. You can find lots more pre-written functions in php here: http://php.net/manual/en/language.functions.php As long as you know the name of a function, the parameters it requires and what the outcome of the executing the function is you can use any of them. User Defined Functions This knowledge also helps when you want to create your own functions. This is where the real power and flexibility lies. You can write a function that does anything and re-use it any of your programs. Let’s say we wanted a function that will calculate the amount of sales tax on an item. We need to use a sensible name for our function, salesTax will do fine here. We also need to think what parameters will be needed for the function to do it’s job. In this case we need to know the value of the item being sold and the rate of tax being used. Here is how we might go about creating this function: Function salesTax($value, $rate){ $tax = $value * $rate; } You can see we have used the name salesTax and then allocated the 2 parameters for value and tax.
To call the function we need to use its name and ensure we pass it 2 parameters in the order shown above: salesTax(5.99, 0.1);// would set the variable $tax to 0.59
Functions: Passing Parameters â&#x20AC;&#x201C; By Value or By Reference There are 2 ways to pass a parameter, by value or by reference. The situation will dictate what method is used. When you pass by value, a copy is sent to the function to be used and then discarded when the function completes its execution. For example: $par = 0; byValDemo($par); Function byValDemo($par){ $par = $par +20; Echo $par; //prints 20 } Echo $par; //would print 0 as the changes made in the function do not affect the original variable as it was only a copy passed to the function. This is passing by value and is the default position in php. If you want to use by value then you do not have to include any additional symbols. By Reference, in contrast, sends a link or reference to the original variable. In essence it passes the memory address of the variable to the function so the original value of the variable can be manipulated. Some additional symbols are needed to pass by reference. $par = 0; byValDemo($par); Function byValDemo(&$par){//note the ampersand at the beginning of the parameter $par = $par +20; Echo $par; //prints 20 } Echo $par;// prints 20 this time as the variable was passed by reference and the function was given access to the original.
Getting variables out of functions We have seen how to pass variables into functions, and by using by reference we can affect the value of variables outside of the function. However, what if we generate an entirely new variable in the function and then want to make it available outside of the function? We need to use the ability of functions to return variables. Function salesTax($value, $rate){ $tax = $value * $rate; Return $tax;//sends the variable tax outside of the function for use in the rest of the program } Scope Following on from the idea of returning a variable from a function to be used in the rest of the program it is now a good time to think about scope. Scope refers to where variables can be seen. salesTax(5.99,0.1); Function salesTax($value, $rate){ $tax = $value * $rate; Return $tax;//sends the variable tax outside of the function for use in the rest of the program } Echo $tax; No problem with the example above, $tax has been sent outside of the function, so it’s scope has gone beyond the function it was created in
salesTax(5.99,0.1); Function salesTax($value, $rate){ $tax = $value * $rate; } Echo $tax; This would generate an error. The scope of tax is within the function only. It was created there and only exists there.
We would similarly encounter errors should we refer to variables inside functions that have not been passed as parameters: salesTax(5.99,0.1); $govAddedTax = 0.5; Function salesTax($value, $rate){ $tax = $value * $rate; $tax =$tax + $govAddedTax; // would cause an error as $govAddedTax was created outside the function and was not passed in, therefore it cannot be “seen” inside the function }
Local or Global The proper terms for the different types of scope are local and global. A variable can be local: salesTax(5.99,0.1); Function salesTax($value, $rate){ $tax = $value * $rate } Echo $tax; // cause an error because $tax is LOCAL to the salesTax function We can define a variable as global by doing the following: global $tax; It should be said that the process of making variables global is a treacherous one and the best practice is to pass variables by value or reference. Course document link: 4.2.5 Analyse an algorithm presented as pseudocode. 4.2.6 Construct pseudocode to represent an algorithm Pseudocode As we write increasingly complex programs, we need to spend some time thinking about the design of the program. One way to do this is with the use of pseudocode. By writing pseudocode we can think about the logic of the program without actually writing the program. An algorithm is defined as: a process or set of rules to be followed in calculations or other problemsolving operations. So really, any program could also be considered an algorithm. Pseudo means false or fake, so what we are writing is “fake-code”. This means pseudocode is a bit of a hybrid of programming code and regular English. The IB specifies their expected style of pseudocode, laid out below. •
Variable names are all capitals, for example, CITY
•
Pseudocode keywords are lower case, for example, loop, if …
•
Function/Method names are mixed case, for example, getRecord
•
Functions/Methods are invoked using the “dot notation” used in Java, C++, C#, and similar languages, for example, BIGARRAY.binarySearch( 27 ), the PHP equivalent of this would be BIGARRAY->binarySearch(27) Variables will be provided in exams and comments // used, for example: • N = 5 // the number of items in the array • SCOREHISTORY,getExam( NUM ) // get the student’s score on exam NUM When assigning values to variables = will be used: • N = 5 // indicates the array has 5 data items
•
•
•
• VALUE[0] = 7 // assigns the first data item in the array a value of 7 Output—this term is sufficient to indicate the data is output to a printer, screen, for example: • output COUNT // display the count on the screen
For example if you were writing pseudocode for a small program that looped from 0 to 5 and added added the counter to a variable called SUM it would look something like this: loop COUNT from 0 to 5 SUM = SUM + COUNT end loop Course document link: 4.2.4 Analyse an algorithm presented as a flowchart Flowcharts Flowcharts are another possible design method. They are a more visual representation of the solution. Again, there are some conventions that are specified by IB. For sequential instructions:
Conditional Statements:
While loop:
For loop:
Input/Output: Get user input
Print score
Additional to the IB specification but has been seen in specimen papers is the symbol for pre-defined process: Activate or deactivate the fan as needed
HL Only Course document link: 5.1.1 Identify a situation that requires the use of recursive thinking, 5.1.2 Identify recursive thinking in a specified problem solution, 5.1.3 Trace a recursive algorithm to express a solution to a problem Thinking Recursively A recursive problem in computer science is one where the solution depends on solutions to smaller instances of the same problem. In a programming sense, this is implemented by creating functions that then call themselves, almost like a snake swallowing its own tail.
A common programming tactic is to take the problem and to divide it into smaller versions of the original problem and combine the results, often called the divide and conquer approach. Letâ&#x20AC;&#x2122;s take the example of factorials: 4! The conventional way of writing a solution to this problem would be: 4*3*2*1 However, remember a recursive solution defines the smaller instances of the same problem. The problem we started with is 4! How can we define a solution to this problem with a smaller instance of itself? 4*3! Now we have a partial solution that if we further divide using the same process we can arrive at an entire solution: 4 * 3! = 4 * 3 * 2! = 4 * 3 * 2 * 1! = 4 * 3 * 2 * 1 We need to think about the recursive element to this solution. What are we doing? If we were asked to define this for any number(n) what is the solution? n! = n * n-1! The last thing we need in a recursive solution is a BASE CASE, when should the recursion stop and unwind? This is the situation where the problem cannot be divided any further. In the case of the factorial problem, when we reach 1 then we cannot divide any more. So the base case for this problem is 1. Programmed version of the factorial problem <?php echo factorial(10); function factorial ($n){ if($n == 1){ return 1;//base case } else{ return $n * factorial($n-1);//recursive case } } ?>
Tracing Tracing is the process of executing a program on paper. This might sound rather strange but it is useful to help both understand a programs execution and also to identify where and why bugs occur. To help demonstrate both tracing and the execution of the recursive factorial solution above here is a trace of the call factorial(4) above.
Factorial(4) N = 4, 4 * factorial(3) â&#x20AC;&#x201C; 4 * 6= 24 N= 3, 3* factorial(2) â&#x20AC;&#x201C; 3*2 = 6 return 6 to factorial(3) above N=2, 2 * factorial(1) - 2 * 1 = 2 return 2 to factorial(2) above N= 1, return 1 to factorial(1) above To begin with the recursive calls move down the way until we hit the base case. When we arrive at the base case we can unwind and each recursive call is replaced by the value returned by that call to eventually arrive at 4* 6 = 24. HL Only Abstract Data Structures/Types (ADTs) So far we have looked at 2 variations to store data in our programs: variables (String, numbers, Boolean) and then combining those in arrays or 2D arrays. These are fairly simplistic and there might be occasions where we want something more complex. Abstract data structures offer this possibility. Abstract data structures are mathematical models for data structures that have similar behaviour. These data structures can be defined indirectly by the operations that can be performed on it and by the mathematical constraints on the effects and possibly the cost of the operations. Cost refers to the efficiency of the operation in terms of resource usage such as processor time. This can also be referred to as complexity which we will look at as we go. By being abstract, these data structures are not specific to one programming language. Link to course document: 5.1.6 Describe the characteristics and applications of a stack, 5.1.7 Construct algorithms using the access methods of a stack The Stack The stack ADT can be defined by only 2 operations: the ability to add something to the stack(push) and the ability to remove something(pop). It should be made clear at this stage that the stack is Last-in-First-Out (LIFO), imagine the plate stack in canteen plates are added to the top and removed from the same place. The diagram below illustrates this:
So as you can see these operations take place at the same end of the stack, considered to be the top. In some cases the stack may be bounded. In other words, the amount stored in the stack will be limited and any attempt to add any more data would result in an error. Although the stack is only defined by the need to push and pop at the top there are some other methods that can make the stack even more useful. Peek() – look at the top item in the stack without removing it topOfStack() – to determine where the top is in relation to the upper boundary stackEmpty() – helpful if a pop() operation is performed on an empty stack stackFull() – helpful if a push() operation is performed on a full stack These methods are inessential as essentially they can be built into the push() and pop() methods. Stacks and Recursion The stack is central to the carrying out of recursion. As the recursive calls are made, they are placed on the stack so that they can be dealt with in the correct order as the recursion unwinds. Link to course document: 5.1.8 Describe the characteristics and applications of a queue, 5.1.9 Construct algorithms using the access methods of a queue Queue The queue is another ADT. It is defined by the ability to add items to the head(enqueue) and remove items from the head (dequeue). It operates much like a queue in McDonald’s: the person at the front of the queue is the next to be served and if you would like to join the queue you would do so at the back.
tail
head
This demonstrates that a queue is a First-in-First-Out(FIFO) structure. Theoretically queues are unlimited in their size, meaning that no matter how many items they already contain, there is always room for more. They can also be empty, at which point something must be added before something is removed again. One of the most common ways to implement a queue is using an array. This necessitates keeping track of where the head and tail are to ensure the enqueue and dequeue operations take place at the correct locations.
Other queue methods that can provide inessential functionality could be: Clear() - empty the queue of all of its contents Peek() â&#x20AC;&#x201C; same as that suggested for the stack, return the item at the head without removing it
Linked Lists In Computer Science a linked list is a sequence of nodes each of which contains some data and a reference (pointer) to the next array in the sequence. There are some variations where there are additional links. This structure allows for insertion and removal at any point in the sequence unlike the queue and stack. Here is a diagram of a linked list with single pointers(singly linked list). head
The head keeps track of where the first node in the list is, the last node points to a null node or the tail. Inserting a node Inserting a node is not as simple as breaking pointers and pointing them elsewhere. Sequencing is required, otherwise the whole linked list could be lost as it relies on the pointers to keep it together. To insert a node:
The creation of pointers should be done in this order: Pointer from B to C created and then Pointer from A to B created. Removing a node Removing a node is as simple as altering a pointer to â&#x20AC;&#x2DC;skipâ&#x20AC;&#x2122; a node.
Link to course document – 4.3.6 Define the terms: variable, constant, operator, object. Classes and Objects Object oriented(OO) programming is a technique that has pervaded all aspects of Computer Science for almost the last 20 years. Object-oriented ways of thinking have been applied to software design, operating systems, programming languages and database systems. We will look at the basic concepts of object orientation. Many people say that OO is a natural way of thinking about things. In the world we live, we are surrounded by objects. Once a problem has been clearly stated, it should be possible to identify an object involved in the problem and the actions we can perform on that object as well as actions it may ask of other objects. Additionally, we might be able to define some state that an object should have. If we think of an MP3 player as an object, we can list the actions we would like the MP3 to be able to perform: •
play, pause, seek a track, fast forward, rewind, skip
The MP3 would also have some state, for example, does it have any songs loaded? The answer to this has an impact on how the player responds to user requests, will it do nothing or report an error? The screen/control panel of the player will give output to the user about the state, such as the track playing, how long it is and how long of the track is left. This control panel only gives the information to the user that they need, it won’t tell you how it does what it does, but as users we don’t really care. How does this relate to object-oriented programming? • • •
The idea that an object provides a set of operations that the user may invoke. These operations are known as methods An object has an internal state. Some of that state may be available to the user, either directly or through methods An object is a “black box”. Some of its state is hidden from the user. Moreover, how the methods actually work is also hidden, as is how they manipulate the internal state
Let’s try to put this more into a programming context. Creating a class allows us to define both the state and behaviour of something. For example, we might create a class about a person. In that class
we might want some state such as first name, surname, date of birth. We could also then define methods/functions that provide the behaviour of that person. This state and behaviour is generic and flexible enough to represent any person. What does a class look like? class person { // the name of the class private $name; private $surname; private $dateOfBirth; //the items that give the class state Public function setName($x){ // a function that can be used to set/change the name $this->name = $x;} // the word “$this” refers to this instance of the class, as you may create several of them when the program starts running Public function surname($y){ $this->surname = $y;} // similar to the last function only it sets/changes the surname public function getName(){ return $this-> name; // a function that returns the value of the name variable from this class } public function getSurname(){ return $this-> surname; //function that returns the value of the surname variable from this class } } We can then use this class to create objects. Objects are classes that have been instantiated, given specific data. An object is described as an instance of a class. We can create an instance of the class using the following: $person1 = new Person(); $person1->setName(“Javier”); //setting the name of person1 $person1->setSurname(“Bardem”); //setting the surname of person1 This is not as efficient as it could be. Whilst the functions are useful for adding data at a later point, what if we already knew the data/state we wanted to create as we instantiate the object? To do this we need to alter the class slightly.
Person Class with a Constructor class person { // the name of the class private $name; private $surname; private $dateOfBirth; //the items that give the class state public function __construct($name, $sname, $dob){ //this is a special function called a constructor $this->name = $name; $this->surname = $sname; $this->dateOfBirth = $dob; } Public function setName($x){ // a function that can be used to set/change the name $this->name = $x;} // the word “$this” refers to this instance of the class, as you may create several of them when the program starts running Public function surname($y){ $this->surname = $y;} // similar to the last function only it sets/changes the surname public function getName(){ return $this-> name; // a function that returns the value of the name variable from this class } public function getSurname(){ return $this-> surname; //function that returns the value of the surname variable from this class } } As a result of adding this extra function, called a constructor, we can now provide the state at the point of instantiation: $person1 = new Person(“Javier”, “Bardem”, “10/08/69”); This creates a person with the name Javier Bardem and a date of birth of 10/08/69.
Link to course document – 4.3.10 Describe the characteristics and applications of a collection Collections Collections are simply objects that group multiple elements into a single unit. Of course this might sound almost like an array, but a collection has an advantage, it is flexible and can grow and shrink to suit the needs of the data/application. Arrays are static and of a fixed size. For some collections it is possible to assign a key to any object that is in the collection so that it can be quickly retrieved. Collections would be used to store, retrieve, manipulate and communicate aggregate data. Some examples might be a poker hand(collection of cards), a mail folder(a collection of letters) or a telephone directory(a mapping of names to phone numbers). Collections can be ordered but this is not a requirement. It can also be possible to store duplicate elements in a collection. Example of collection in use: Here is the data we would like to store in our collection called MYCONTACTS. Name Luke Skywalker Darth Vader Han Solo Obi Wan Kenobi
Phone Number 5553 9922 5550 8998 5567 7866 3456 1242
Collections usually provide you with what are called access methods. These methods allow you to go through the data. An example might be .getNext() to tell you what the next piece of data in the collection is. Link to course document – 4.3.11 Construct algorithms using the access methods of a collection Collections and Access methods The nature of a collection necessitates that the creator provide methods to access data in the collection as they are not already written into the programming language library. This will be illustrated using an example of air quality health index, where air quality is measured hourly in Mong Kok. The air quality is measured on the hour at a location in Mong Kok. The value is converted to a number between 1 and 10(the air quality health indicator – AQHI) . This value is stored in a collection, called POLLUTION, ready to be retrieved and stored in an archive, in this case a 1D array called LEVELS. The collection has been created with 2 methods – isEmpty() – returns true or false depending on whether the collection is empty or not, and getNext(), returns the next value stored in the collection.
We need to then construct an algorithm(for more on algorithms, see the next section of these notes) in pseudocode to retrieve all of the AQHIs and store them in the array. It might look something like this: HOURS = 0 Loop while not POLLUTION.isEmpty LEVELS[HOURS] = POLLUTION.getNext HOURS = HOURS + 1 End loop This is a very simple example, but demonstrates how you might use the methods provided with a collection to access itâ&#x20AC;&#x2122;s data and determine whether it is empty or not.
Algorithms To put it simply, an algorithm is a step-by-step procedure for performing some task in a finite amount of time. This principle is central to computer science. There is no generally accepted formal definition of what an algorithm is. So in fact, the word algorithm could refer to all computer programs. For some people though, a computer program is only an algorithm if it stops eventually. You will be expected to construct, analyse and interpret algorithms using the approved Pseudocode notation mentioned earlier in these notes. Link to course document 4.2.1 Describe the characteristics of standard algorithms on linear arrays. Standard Algorithms The programs you write will each have their own unique challenges and features. However, the same old subproblems will keep recurring. At some point in your programming experience, you will need to search for a value in an ordered collection, or sort a data sequence. These problems have been beaten to death by computer scientists for generations. The best approaches are now known and defined by standard algorithms.
Linear/Sequential Search The linear/sequential search is the simplest of search algorithms. It simply looks through the data set in sequence, and one at a time, and only stops when it finds the piece of data being sought, or the end of the sequence is met. This has a few implications in terms of what we might call the cost of this algorithm. Each of the items is equally likely to be searched for, therefore the worst case cost is proportional to the size of the data set, this is also the expected cost. Here is the pseudocode: SEARCH_ITEM = input item to be searched FOUND = -1 //set to this as if we donâ&#x20AC;&#x2122;t find the item, this will be returned loop for length of data set if CURRENT_ITEM = = SEARCH_ITEM FOUND = CURRENT_ITEM_INDEX end loop return FOUND So if the data set that is being searched is of size n, the worst case cost for this search is n. Binary Search The cost of the sequential sort is proportional to the size of the data set, meaning that as the data set gets bigger, if the piece of data being searched for is in the second half of the data the search can be slow. Binary search overcomes many of the drawbacks of the sequential search but is reliant on the data set being in order. If the data set is in order we can check single pieces of data and find out a lot about the rest of the data set. 0 10
1 15
2 18
3 29
4 30
5 35
6 41
7 58
8 65
9 68
The computer can only look at one number at a time so it cannot easily look at this data set and say that it doesnâ&#x20AC;&#x2122;t contain the number 16. However, if it looks at the middle number and compares it, it is possible to say that 16 might exist in the lower half of the data as the number we are looking for is less than the mid-point. The mid-point is calculated by taking the indices of the array and dividing by 2( (0+9)/2)). Because we now know that 16 cannot possibly be in the right half of the data, we can ignore it and are left with the data below. 0 10
1 15
2 18
3 29
To find out whether 16 is the data set still, we simply check the middle item again, in this case it would be item 1 as we would round down ((0+3)/2). The number we are searching for is larger than this value, so we can now ignore the left half of the data and are left with the following: 2 18
3 29
We calculate the mid-point once more ((2+3)/2), rounded down would give us 2. 18 is bigger than 16 so the natural thing to do here would be to ignore 18 and everything to its left. However, there is no data to the left, so we can stop the search and say that the number 16 is not contained within the data set. The cost of this algorithm is much less than the sequential search. We started off with a data set of 10 and only had to make 4 comparisons to reach a conclusion. This is the absolute worst case scenario. The worst case scenario in a sequential search is n. The difference between the 2 algorithms only increases as the data set gets even bigger: Data Set Size 100 200 400 800
Sequential Search Worst Case Average 100 50 200 100 400 200 800 400
Worst Case 7 8 9 10
Binary Search Average 7 8 9 10
As you can see from the table above, as the data set doubles, the binary search only requires one more comparison as this extra comparison essentially halves the data set to the previous size. The cost of the Binary search can be given as log2 n, where n is the size of the data set. Another way to look at this is 2x = n, where n is the size of the data set. If we make n=100, then 2x = 100.
Pseudocode for the Binary Search LEFT = 0 //pointer to keep track of where the left side of our data starts RIGHT = length of data set //pointer to keep track of the right side of our data ends MID = 0 //used to store our mid-point FOUND = -1 //when we find a value we need to store its index, otherwise this will remain -1 Loop while LEFT< RIGHT //if the left pointer goes past the right we can stop MID = LEFT+RIGHT /2 //calculate the mid-point, should be rounded down if SEARCH_ITEM < DATA[MID] then RIGHT = MID //if what we are looking for is less than mid, the right side of the data becomes the midpoint else if SEARCH_ITEM > DATA[MID] then LEFT = MID //if what we are looking for is more than mid, the left side of the data becomes the midpoint else FOUND = MID //if the mid is equal to our search, store its index End loop Return FOUND //this will be -1 if the item is not found Sorting Sorting is another common endeavour for computers. There are many situations where things are sorted in some kind of order. Whether it is the contacts in your mobile phone ordered alphabetically or your emails ordered by the date they were received. In this course, you need to know about two sorting algorithms. Selection Sort Selection sort is a very simple algorithm. The selection sort effectively divides the data into 2 sets, one set being that data which is already sorted and that which has yet to be sorted. The algorithm looks through set of unsorted data to find the smallest number in that set and it then places it at the end of the sorted set. It does this until the unsorted set is empty. Initially, the sorted subset is empty and the unsorted set is the entire data set.
Here is an example of how this would play out in a linear array of unsorted data: 0 98
1 6
2 34
3 90
4 4
5 23
6 12
Looking through the original data set we can see that the smallest number is 4, so we place it to the left most position like so, swapping it with the number that was there: 0 4
1 6
2 34
3 90
4 98
5 23
6 12
The grey box indicates the set of data that is sorted. Looking at the data above, 6 is the smallest unsorted piece of data, so we add it to the sorted set. 0 4
1 6
2 34
3 90
4 98
5 23
6 12
We can then repeat this process: 0 4
1 6
2 12
3 90
4 98
5 23
6 34
0 4
1 6
2 12
3 23
4 98
5 90
6 34
0 4
1 6
2 12
3 23
4 34
5 90
6 98
0 4
1 6
2 12
3 23
4 34
5 90
6 98
0 4
1 6
2 12
3 23
4 34
5 90
6 98
Before we talk about the cost of this algorithm, it is worth looking at the pseudocode as it explains the cost
Pseudocode for Selection Sort MIN = 0 //set a min value loop for length of array loop for unsorted subset//we only need to loop for the relevant portion of the data if current item < MIN then MIN = current item end loop Swap the MIN with the value in the left most item in the unsorted subset End loop
If we look closely at this pseudocode, you can see that it contains two loops. One of the loops is inside the other, this is called a nested loop. The effect this has is that for each time round the outside loop, the inner loop goes from start to end. So if we had a data set of 9 items, the outer loop would loop 9 times. For each of those times, the inner loop would repeat 9 times. So the total number of times each loop repeats is 9 * 9 = 81. If we applied this to a data set of size n, then we would get n * n = n2. We can therefore say that the cost of the selection sort algorithm is n2. This is the best case scenario, the worst and also the average. This makes it very slow for large data sets. Bubble Sort Bubble sort is another simple sorting algorithm, although it requires a bit more effort than the selection sort. Like the selection sort, it is also incremental in its approach. The bubble sort compares the first 2 items and if they are not in order, they are swapped. It then moves on to item 2 and 3, again swapping them if they are not in order and repeats this until the n-1th and nth items have been compared. This is called a pass. To get the data sorted will normally require more than one pass unless the data is already partially sorted. The next pass only need to compare the numbers up to the n-1th item as the nth item is already in the correct place as it should have â&#x20AC;&#x2DC;bubbledâ&#x20AC;&#x2122; to the top of the list during the first pass. The second pass will ensure the n-1th item is in the correct place. The third pass the n-2nd and so on until the data is sorted entirely. As you will see from the pattern in the data set being sorted it is almost the opposite of the selection sort. The bubble sort does have the ability to stop if the data becomes sorted before the nth pass.
We will use the same data as used in the selection sort: 0 98
1 6
2 34
3 90
4 4
5 23
6 12
4 4
5 23
6 12
4 4
5 23
6 12
The numbers at 0 and 1 are compared (98 > 6, so they need to swap) 0 6
1 98
2 34
3 90
The numbers at 1 and 2 are then compared (98>34 so swap) 0 6
1 34
2 98
3 90
The numbers at 2 and 3 are then compared (98>90, so swap) 0 6
1 34
2 90
3 98
4 4
5 23
6 12
2 90
3 4
4 98
5 23
6 12
3 4
4 23
5 98
6 12
3 4
4 23
5 12
6 98
And then 3 and 4 (98> 4, so swap) 0 6
1 34
And then 4 and 5(98 >23, so swap) 0 6
1 34
2 90
And then 5 and 6 (98 > 12, so swap) 0 6
1 34
2 90
This is the end of the first pass, and the number at 6 is now in the correct place, indicated by the grey colour. The next pass need only look at the numbers from 0-5. The sequence of swaps is as follows: 6< 34, no swap 0 6
1 34
2 90
3 4
4 23
5 12
6 98
34<90, no swap 0 6
1 34
2 90
3 4
4 23
5 12
6 98
1 34
2 4
3 90
4 23
5 12
6 98
1 34
2 4
3 23
4 90
5 12
6 98
1 34
2 4
3 23
4 12
5 90
6 98
90 > 4, so swap 0 6 90> 23, so swap 0 6 90>12, so swap 0 6
This is the end of the second pass and 90 is now in the correct place. The sequence of swaps for pass 3 is as follows 0 6
1 34
2 4
3 23
4 12
5 90
6 98
0 6
1 4
2 34
3 23
4 12
5 90
6 98
0 6
1 4
2 23
3 34
4 12
5 90
6 98
0 6
1 4
2 23
3 12
4 34
5 90
6 98
0 4
1 6
2 23
3 12
4 34
5 90
6 98
0 4
1 6
2 23
3 12
4 34
5 90
6 98
And pass 4:
0 4
1 6
2 12
3 23
4 34
5 90
6 98
Pass 5 would establish that no swaps were necessary as the last 3 numbers are in order anyway. The algorithm would be able to stop at this point. This is where the bubble sort has a slight advantage over the selection sort. As you will see from the pseudocode, the worst-case cost of the bubble sort is n2 as is the average. The best case for it is n, but this relies on the data set being already sorted. Pseudocode for Bubble Sort SWAPS = true //a Boolean to determine if swaps are made, if there are no swaps made. The algorithm can stop loop while SWAPS SWAPS = false loop from X = 0 to X < length of data set compare X and X+1 if X > X+1 TEMP = value at X+1 X+1=X X = TEMP SWAPS = true; end for loop End while loop