PHP Love Calculator task

I’ve been meaning to write this one up for ages! This is an idea that grew to encompass more and more things that I realised fit in to it from the OCR Computing AS F452 syllabus.

The premise


I expect you’ve seen the TV adverts promising that if you text your name and your crush’s name to some premium rate number, it will tell you how compatible you are. This is an online version. Obviously a load of rubbish in the love stakes, but as far as appealing programming tasks for sixth formers go…well, it’s a hit! It’s also a sneaky way of introducing all sorts of boring concepts that they really need to know, such as ASCII character conversion, writing and reading from files, using common functions such as round() and devising algorithms.

You will need

– A central web server running PHP which students are able to write to

– OR a local installation of XAMPP for each student (see this post for more info). Apparently you can now even run a web server with PHP on a Raspberry Pi, although I haven’t tried it!

– Some students who have already done a fair bit of programming, although this doesn’t have to be in PHP. Mine had done about 1 week of PHP before doing this task, but had previously been working on Python for about 5 months.


Page one – typing in the names

 
This is your basic love calculator, we will add the bells and whistles later. You are going to need two PHP pages to accomplish your goal, and the first of those doesn’t even have any PHP on it – it’s just a basic HTML form. Call your page index.php. You can style the page however you like, but the essential part you will need is the form part:

  <form action="calculate.php" method="post">
    Your name: <input type="text" name="name1" /> 
    Boyfriend/girlfriend's name: <input type="text" name="name2" /> 
    <input type="submit" value="Calculate compatibility!" />
  </form> 

There are three interesting things to note here.

1. The action of the form tag is calculate.php. This means that when we press the button, the script will send the data typed into the form to the page calculate.php

2. We used the method post, which means that the data arrives on calculate.php, it is in an array called $_POST

3. Each field (in this case, both are text boxes) has its own index of the post array. So the “your name” box has the index name1 because that’s the name we gave it in the form.

 Your name: <input type="text" name="name1" />

…so we can refer to it on calculate.php as

<?php print $_POST['name1']; ?>

Page two – calculating the love!

 
I’m sorry to disappoint you, but I don’t know the secret of compatibility – if I did I’d probably be sunning it up in the Bahamas instead of writing blog posts getting a monitor tan. However, I do know that it’s rather fun to try to devise an algorithm that will produce the same result every time (i.e. is not random), produces different outputs depending on the input, and is sufficiently complex to not be easily guessable by the casual user. The beauty of this part is that you can let the students loose – it really does not matter what algorithm they come up with, and it may be fun for them to do some testing of each others algorithms to see if they really always come up with a number between 1 and 10!

Purely as an example, you could do something like this:

// Calculate the length of each of the names
$length1 = strlen($_POST['name1']);
$length2 = strlen($_POST['name2']);

// Add the two together
$calculate = $length1 + $length2;

// If 1 is longer than 2, take off 5, otherwise add 3
if($length1 > $length2){
  $calculate = $calculate - 5;
}
else {
  $calculate = $calculate + 3;
}
// Multiply by 42 (the meaning of life!)
$calculate = $calculate * 42;
// Divide by 100+ length of 2
$calculate = $calculate / (100 + $length2);

if($calculate > 10){
  $calculate = 10;
} else {
  $calculate = round($calculate, 0);
}


I have used two common functions here – strlen() takes a string as an argument and returns the number of characters in the string, i.e. the length, and round() takes a decimal as a first argument, and rounds it to a given number of places (in this case 0). As you can see, my algorithm sucks a little so I had to cheat and say that if the result was greater than 10, make it 10 😉

Now we need to do the cool bit. We have calculated the compatibility between these two lucky people, so we need to print it on the screen. Time for a bit of concatenation and a loop!

Put this code on calculate.php just below your algorithm, to display the levels of love!

// Print your compatibility score
print $_POST['name1']." and ".$_POST['name2'].
" score ".$calculate." out of 10<br>";

// Print out the love hearts
for($i=$calculate; $i>0; $i--){
  print '<img src="loveheart.png" width="20" height="20">';
}
// Meta refresh back to the previous page
print '<meta http-equiv="refresh" content="5; url=index.php">';

In the first part where we are printing the names, I have introduced concatenation which uses the full stop instead of the + in PHP.

The point of the loop is to print out a “love heart” graphic a given number of times depending on the score. So if they scored 8/10, it will print 8 hearts.

We don’t want to be stuck on this page, so I have used the meta refresh to return to the first page – index.php – in 5 seconds. Change the number to change the length of time.


Adding cool stuff

 
So I promised other cool stuff in the intro! When I was about to set this task, I took a look at my progress sheet to see which topics we still had left to cover on the syllabus. One topic was ASCII and the conversion between the ASCII code and the actual character, a topic I’d done as a theory lesson last year. Here is the perfect opportunity to actually use the functions provided in PHP to convert from a letter to the ASCII – ord() – and back to the character – chr().

In your algorithm on calculate.php you could include some code along the following lines:

// Initialise two variables
$ascii_value_1 = 0;
$ascii_value_2 = 0;

// Split both strings into arrays
$name1 = str_split($_POST['name1']);
$name2 = str_split($_POST['name2']);

// Calculate the ASCII value of each string
for( $i=0; $i < strlen($_POST['name1']); $i++){
  $ascii_value_1 += ord($name1[$i]);
}

for( $j=0; $j < strlen($_POST['name2']); $j++){
  $ascii_value_2 += ord($name2[$j]);
}
// Calculate compatibility (just made up, of course!)
$calculate = ($ascii_value_1 - $ascii_value_2)/100;

This is a bit complex. I have decided to find the ASCII value of each character in the name, and add them all up to be stored in the variable $ascii_value_1. The function ord() can only convert one character into ASCII at a time. So we can’t plonk the whole lot in as an argument like this:

// This doesn't work
$ascii_value_1 = ord($_POST['name1']);

Instead, we have to go through each of the names, character by character, and keep adding the values to the variable $ascii_value_1.

I have split both name strings into arrays $name1 and $name2, so that I can then reference each individual character of the string, i.e. the first character of the first name is $name1[0] and so on.
(Note: I realise I could treat the string itself as an array anyway which is more efficient, but that would result in two indexes of the array $_POST or a horrible variable rename, which I think would confuse the issue!)

I then calculate the ASCII value of that character using ord() and add it to the total. My calculation of compatibility also has a very obvious flaw in that if the first ASCII value is smaller than the second, it will result in a minus number – it’s very easy to overcome that, I leave it as an exercise!

What about writing to files?

Another modification you could try is writing to files – suggested by one of my enterprising female students who wished to send the love calculator to her friends and figure out who had a crush on who based on which names were written in. (Sneaky!) After computing the compatibility, you could write both names and the score to a text file (or even a database). I suggest using some of the code from my shoutbox task in order to accomplish this. I bet a student a packet of Haribo that he could do this in the 5 minutes between finishing the above and the end of the lesson, and I am now sadly lacking in gummy sweets – so it is possible!

5 thoughts on “PHP Love Calculator task

Leave a comment