Senior PHP Role Test

Hi all,

I just did a PHP test for a senior developer role for a pretty big company. I have already submitted it but I thought that I would share it with all of you. If you spot anything that can be improved please have a say.

Cheers…


<?php
$list = array(
	1 => 'one',
	2 => 'two',
	3 => array(
		31 => 'thirty-one',
		32 => 'thirty-two'
	),
	4 => 'four',
	5 => 'five',
	6 => array(
		61 => 'sixty-one',
		62 => array(
			621 => 'six hundred and twenty-one',
			622 => 'six hundred and twenty-two',
			623 => array(
				6231 => 'six thousand two hundred and thirty-one',
				6233 => array(
					62331 => 'sixty-two thousand three hundred and thirty-one'
				)
			)
		)
	),
	7 => 'seven'
);

// 1. Write a function to generate an unordered list. The function should accept an array in a similar format to the $list array above. Write any tests you think might be relevant.

function recursiveList($data,&$output){
	$output.='<ul>';
	foreach ($data as $key => $value) {
		$output.='<li>';
		$output.= $key;
		if(is_array($value)) recursiveList($value,&$output);
		else $output.=' = '.$value;
		$output.='</li>';		
	}
	$output.='</ul>';
}
recursiveList($list,$output);
echo $output;

//2. Write a function to add up all the key integers in an array. For example passing in the $list array will result in 76875.

function recursiveKeyCount($data,&$output){
	foreach ($data as $key => $value) {
		$output+= $key;
		if(is_array($value)) recursiveKeyCount($value,&$output);	
	}
}

$keyCount=0;
recursiveKeyCount($list,$keyCount);
echo $keyCount.'<br/>'.'<br/>';

//3. Write a class to convert integers into words.

class IntegersToWords{
	
	private $one_to_twenty = array("one", "two", "three", "four","five", "six", "seven", "eight", "nine", "ten", "eleven","twelve", "thirteen", "fourteen", "fifteen", "sixteen","seventeen", "eighteen", "nineteen");
	private $twenty_to_ninety = array("twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty","ninety");
	private $hundred  = "hundred";
	private $thousand = "thousand";
	private $million  = "million";
	private $billion  = "billion";
	private $trillion = "trillion";
	private $output='';
	
	public function get($int){
		$this->output='';
		$this->getNumber($int);
		return $this->output;
	}
	
	private function getNumber($int){
		$this->integers=str_split($int);		
		$count=0;
			
		foreach ($this->integers as $key => $value) {
			
			$position=count($this->integers)-$count;
			
			if($position % 3==0){	
				$this->hundreds($position,$key,$value);			
			}
			
			if($position % 3==2){		
				$this->tens($position,$key,$value);					
			}			
			
			if(($position % 3==1) && !isset($this->integers[$key-1])){							
				$this->output.=$this->one_to_twenty[$value-1];				
			}
							
			if(($position==4  || $position==10 || $position==17)){
				if($this->hasWord($value,$key,3)){
					$this->output.=' '.$this->thousand.' ';
				}				
			}
			
			if($position==7){
				if($this->hasWord($value,$key,6)){
					$this->output.=' '.$this->million.' ';
				}				
			}
			
			if($position==13){
				if($this->hasWord($value,$key,9)){
					$this->output.=' '.$this->billion.' ';
				}
			}
			
			if($position==19){
				if($this->hasWord($value,$key,3)){
					$this->output.=' '.$this->trillion.' ';
				}
			} 																
			$count++;
		}		
	}
	
	private function tens($position,$key,$value){
				
		$number=$this->integers[$key].$this->integers[$key+1];				
		$last=$this->integers[$key+1];
		$doLastDigit=true;
		
		if($value==1 && $number<=19){			
			$this->output.=$this->one_to_twenty[$number-1];
			$doLastDigit=false;
		}
		
		elseif($value > 1){
			$this->output.=$this->twenty_to_ninety[$value-2];
			if($last!=0) $this->output.='-';
		}
		
		if($last!=0 && $doLastDigit){		
			$this->output.=$this->one_to_twenty[$last-1].' ';
		}
	}
	
	private function hundreds($position,$key,$value){
		
		$number=$this->integers[$key].$this->integers[$key+1].$this->integers[$key+2];
		
		if($this->integers[$key]!=0){
			$this->output.=$this->one_to_twenty[$value-1].' '.$this->hundred.' ';
		}
		
		if($this->integers[$key+1]+$this->integers[$key+2]!=0){
			$this->output.=' and ';
		}	
			
	}	
	
	private function hasWord($value,$key,$iterations){
		$hasWord=false;
		for ($i=1; $i < $iterations; $i++) {
			if(isset($this->integers[$key-$i]) && $this->integers[$key-$i]!=0){
				$hasWord=true;
			}
		}
		if($value!=0) $hasWord=true;		
		return $hasWord;		
	}
}

$int2Words= new IntegersToWords();
echo $int2Words->get(1800962);

?>

Was it stipulated that you cannot use something which does not already exist?

words to numbers

PEAR numbers_words

… anyhow there might be clues amongst those function/classes.

No it wasn’t, but the instructions clearly say “Write a class” so I take it you’re not meant to use someone else’s code.

I take it you were able to do this in your own time from home?

While these are relatively interesting questions, they still don’t really determine how good a programmer you are in my opinion. In my opinion, so many technical tests miss a really big factor - that is: how good are you at organising your code, and can you write code that can scale over time?

When we have people come in for interviews, I give them a test I wrote that involves taking some code that produces the expected output to the screen, but is particularly poorly written, and asking them to refactor it. First guy to take the test could barely tell me what was wrong with it. He didn’t get the job. One guy came in and scoffed when I showed him the code - he looked genuinely annoyed by how bad it was. He then highlighted each crappy part and told me how he’d refactor it to make his code tidy - he got the job.

Still quite interesting, but I reckon a refactoring challenge will tell you more about the kind of code quality you should expect from the programmer.

Thanks aaarrrggh,

definitely interesting views. Yes I did this from home.

Cheers

If you wanted to test the accuracy of the output of your class vs the others I linked to I guess you could set up some unit-tests (or even string comparisons) which compared the output of the 3 of them against some randomly generated numbers.