bookmark_borderUnderstanding Octal

Why would we need to understand Octal?

The most relevant reason I can come up with right now is that looking back at some of the interview question challenges I’ve posted, there is one that deals with an Octal number. That question does not ask you to actually convert the number, but there is a variation of that problem which does. The last thing you want is to have to tell your interviewer that although you recognize that it’s an Octal number, and you know what the answer is *not* going to be, you don’t know what it *will* be.  This might pass in some interviews, particularly if they’re only trying to assess that you know it’s an Octal number. But if that’s the case, I would expect them to be using the example that does not require you to actually convert the number.

So, here’s the problem:

$i = 020;
echo $i / 2;

If you don’t know that you’re looking at an Octal number, you’ll answer 10. But let’s take a look at how Octal works so we can actually answer the problem and not just recognize that it’s an Octal number.

Here is the way you would go about solving this:

20 (octal)

(2 x 8^1)  + (2 x 8^0)

From right to left, multiply the digit times 8 to the power of the place. The right-most digit is the zero place, the next one is the first power, then second, etc…

(2 x 8) + (2 x 1)

16 + 2

18

So, 20 in octal is 18 decimal.

Here is one with three digits:

475 (octal)

(4 x 8^2) + (7 x 8^1) + (5 x 8^0)

(4 x 64) + (7 x 8) + (5 x 1)

256 + 56 + 5

317

 

I realize that my way of explaining it is likely to be unclear to some. The best recommendation I can offer if you are struggling with it is to visit the Wikipedia page. That’s where I started. Then just work through some problems on paper till it sinks in.

bookmark_borderforeach vs array_filter

The problem:

Given an array of numbers, create a new array containing only the odd numbers from the original.

$original_array = [1,2,3,4,5,6,7,8,9,10];

There are two ways you can approach this problem. Let’s look at a foreach loop first:

$original_array = [1,2,3,4,5,6,7,8,9,10];

$odd_array = array();

foreach($original_array as $this_number){
   if(!$this_number % 2){
       $odd_array[] = $this_number;
   }
}
  1. Set up a variable to hold the new array of odd numbers.
  2. Loop over the original array
  3. Test each value – if it is not evenly divisible, push it onto the odd number array

This way of approaching the problem works, and there is nothing wrong with doing it this way. However, there is another way.

$original_array = [1,2,3,4,5,6,7,8,9,10];

$odd_array = array_filter($original_array, function($number){
     return !($number % 2);
});

The array_filter function automatically iterates over all the elements of the array. One by one, each item in the array is passed to the callback function. The array_filter function will return an array, and expects the callback to return true or false for each item. True means that item will be placed into the array that array_filter returns. False means that item won’t be in the returned array.

Inside the callback in this example, each item is tested to see if it is even, and then that result is negated because we actually want to test for odd.

The callback does not have to be inline.  You can call an external function, like this:

$original_array = [1,2,3,4,5,6,7,8,9,10];

$odd_array = array_filter($original_array, "isOdd");

function isOdd($number){
     return !($number % 2);
}

This is nice because you can separate concerns. You can now refactor the isOdd method if you want to, and it will still work.

$original_array = [1,2,3,4,5,6,7,8,9,10];

$odd_array = array_filter($original_array, "isOdd");

function isOdd($number){
     return ($number & 1);
}

Sample output: (note that array keys are preserved)

Array
(
    [0] => 1
    [2] => 3
    [4] => 5
    [6] => 7
    [8] => 9
)

 

So, what about associative arrays?

Let’s first adapt the original foreach solution:

$original_array = [

    'Cars' => ['Chevy','Ford','Toyota','Honda'],
    'Colors' => ['Blue','Red','Green','Yellow'],
    'Animals' => ['Dog','Cat','Cow','Coyote']

];

$color_array = array();

foreach($original_array as $this_key => $this_value){
   if($this_key == 'Colors'){
       $color_array[] = $this_value;
   }
}
print_r($color_array);

This will output:

Array
(
    [0] => Array
        (
            [0] => Blue
            [1] => Red
            [2] => Green
            [3] => Yellow
        )

)

Let’s try it with the array_filter function:

$original_array = [

    'Cars' => ['Chevy','Ford','Toyota','Honda'],
    'Colors' => ['Blue','Red','Green','Yellow'],
    'Animals' => ['Dog','Cat','Cow','Coyote']

];

$color_array = array_filter($original_array, function($value, $key){
     return $key === 'Colors';
}, ARRAY_FILTER_USE_BOTH);

print_r($color_array);

This will be the output:

Array
(
    [Colors] => Array
        (
            [0] => Blue
            [1] => Red
            [2] => Green
            [3] => Yellow
        )

Notice how it returns an associative array. This is different than the previous way, which had a key of [0], and may be more useful in some situations.

bookmark_borderFactor Finder

// Number to factor
$num = 60;

// Loop from the number to factor down to 1
for($i=$num; $i>=1; $i--){
    // If it divides evenly
    if($num % $i === 0 ){
        // Output result of division, which is a factor
        echo $num / $i . '<br />';
    }
}

Output:

1
2
3
4
5
6
10
12
15
20
30
60

*To find a factor, divide by a number, and if the result is a whole number, then both the answer, and the number you divided by are factors.*

bookmark_borderChanging the color of the first word

The question/problem is:

Write a PHP script, which changes the color of the first character of a word.

This challenge tests your knowledge of preg_replace, and regular expressions.


$text = 'PHP Tutorial';
$text = preg_replace('/(\b[a-z])/i','<span style="color: red;">\1',$text);
echo $text;
?>

Let’s break this down.

preg_replace takes the following parameters:

  1. pattern
  2. replacement
  3. subject
  4. optional limit
  5. optional count

The pattern in this case is ‘/(\b[a-z])/i’

Let’s break that down:

It opens with '/ and ends with /i'

All regular expressions in PHP are going to be enclosed in quotes and a delimiter like the forward slash – like this: '/ /'  – but what’s the i all about? It simply means “case insensitive”.

Moving inward we have a pair of parenthesis. Parenthesis are used for grouping, but also for something called numbered capturing.

Numbered Capturing 

Think of numbered capturing as a way to grab groups of matching patterns and store them for later reference numerically.

Moving further in, we see \b on the left, followed by [a-z]

\b means Word Boundary. It will force the pattern that follows to start at the beginning of a word. (Think of it as setting a virtual cursor, or start point, before the word.)

[a-z] matches any one character in that set. (Remember we used \i to make it case insensitive)

So the pattern will match the first character of a word, but remember that regular expressions are greedy by default, so that means it won’t stop just because it found a match. So it matches the first letter of both words in our example.

If you look further to the right in the regex function you’ll notice that the second parameter contains \1, which is referring to the first captured item in the capture group. In our case it’s the P and the – the first letter of each word.

So you can see how it will replace the matched text with the modified code which adds the span tag, but it will only affect one character for each word.

Bonus:

For an easy way to make it only affect the first word, just add a 1 as the 4th parameter to the preg_replace. Recall that is the optional “limit” parameter.

bookmark_borderReference challenge

This one tests your knowledge of how reference variables work:

$a = 'P';
$b = &$a;
$b = "PH$b";

What will $a and $b be after these three lines of code run?

First, $a is set to ‘P’. Then, $b gets a reference to the variable $a.

Next, $b is set to ‘PH’ followed by the value of $b, which is a reference to $a, so it becomes “PHP”.

However, keep in mind that it works both ways. Now that we set $b to “PHP”, $a will also the same because $b is a reference to $a.

This means that a reference variable is a two way street. Change either and they are both affected.

It just so happened that the initial value of $a was pulled into the assignment on the third line first, and then the entire value ended up in $a afterward. But how?

Remember that $b is a pointer to the address of the contents of $a. So, when we assign $b, we are actually affecting the memory location that $a sits at.

So it first read the value of $a, then overwrite it with the new string. The first letter of the  new string is sitting in the same memory location that contained the original “P”, and now has two more letters following it.

Technically, the contents of $b is still just an address internally – the address of $a.