PHP calculator with words as operators - php

I am stuck in resolving a PHP script.
I want to calculate a result from a set of instructions. Instructions comprise of a keyword and a number that are separated by a space per line. Instructions are loaded from file and results are output to the screen. Any number of Instructions can be specified. Instructions are operators (add, divide, subtract, multiply). The instructions will ignore mathematical precedence. The last instruction should be “apply” and a number (e.g., “apply 3”). The calculator is then initialised with that number and the previous instructions are applied to that number.
[Input]
add 2
multiply 3
apply 3
[Output]
15
[Explanation]
(3 + 2) * 3 = 15
example
[Input]
multiply 9
apply 5
[Output]
45
Can anyone help with some example logic or code ?
This is what I have tried so far:
class calculator {
public
function calculate($expression) {
$expression = str_replace(' ', '', $expression);
return $this - > exec($expression);
}
private
function exec($expression) {
switch ($expression['op']) {
case 'add':
$r = $expression[0] + $expression[1];
break;
case 'subtract':
$r = $expression[0] - $expression[1];
break;
case 'multiply':
$r = $expression[0] * $expression[1];
break;
case 'divide':
$r = $expression[0] / $expression[1];
break;
}
return $r;
}
private
function parseExpression($expression) {
$blankspace = preg_match('/\s/', $expression);
$counter = count($expression);
}
}

I would go this way:
class Calculator {
public $result = 0;
public $queue = Array();
public parseString($text) {
// parse input string
$cmds = explode(" ", $text);
foreach($cmds as $cmd) {
$cmd = trim($cmd);
if(!$cmd) continue; // blank or space, ignoring
$this->queue[] = $cmd;
}
// lets process commands
$command = false;
foreach($this->queue as $index => $cmd) {
if(is_number($cmd)) {
// if it's number fire previous command if exists
if(!$command || !method_exists($this, $command)) {
throw new Exception("Unknown command $command");
}
$this->$command($index, $cmd);
}else{
$command = $cmd;
}
}
}
public function apply($index, $number) {
// manipulate $result, $queue, $number
}
public function add($index, $number) {
// manipulate $result, $queue, $number
}
public function substract($index, $number) {
// manipulate $result, $queue, $number
}
}
$calculator = new Calculator();
$calculator->parseString('...');
It's just example how you can do it, but it's your job to do it :)
You gonna need to add some methods like clearQueue, clearResult, setResult etc...

Related

Best way to search misspelled words in MYSQL [duplicate]

I was wondering if anyone knows of any library, script, or service that can spell check a string and return a suggestion of the properly spelled word or suggestions if more that one properly spelled word that it could be written in PHP.
I would prefer if there wasn't a limit on the amount of queries I could do, so not like Google's APIs.
It would be great if it could function like this:
// string to be spell checked stored in variable
$misspelledString = "The quick brown lama jumped over the lazy dog.";
//pass that variable to function
//function returns suggestion or suggestions as an array of string or strings
$suggestion = spellCheck($misspelledString);
echo "Did you mean ".$suggestion[0];
You can try the included Pspell functions:
http://php.net/manual/en/ref.pspell.php
Or an external plugin, like this one:
http://www.phpspellcheck.com/
Check this SO question for an example.
Not quite as nice an API as in your example, but Pspell would be an option. It may already be included with your system copy of PHP. You'll need aspell libraries for each language you want to check.
http://php.net/manual/en/book.pspell.php
On my debian based machine, it's included in the system repositories as a separate package, php5-pspell.
You need to have "pspell" PHP extension, you can install it on Linux using CLI:
sudo apt-get install php-pspell;
sudo service apache2 restart;
The code is very simple:
if ($word = $_GET['word']) {
$spellLink = pspell_new("en");
if (!pspell_check($spellLink, $word)) {
$suggestions = pspell_suggest($spellLink, $word);
echo '<p>Did you mean: <i>"'.$suggestions[0].'"</i>?</p>';
}
}
I attempted to create a class that takes a list of phrases and compares that to the user inputs. What I was trying to do is get things like Porshre Ceyman to correct to Porsche Cayman for example.
This class requires an array of correct terms $this->full_model_list , and an array of the user input $search_terms. I took out the contruct so you will need to pass in the full_model_list. Note, this didn't fully work so I decided to scrap it, it was adapted from someone looking to correct large sentences ...
You would call it like so:
$sth = new SearchTermHelper;
$resArr = $sth->spellCheckModelKeywords($search_terms)
Code (VERY BETA) :
<?php
/*
// ---------------------------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------------------------
//
// FUNCTION: Search Term Helper Class
// PURPOSE: Handles finding matches and such with search terms for keyword searching.
// DETAILS: Functions below build search combinations, find matches, look for spelling issues in words etc.
//
// ---------------------------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------------------------
*/
class SearchTermHelper
{
public $full_model_list;
private $inv;
// --------------------------------------------------------------------------------------------------------------
// -- return an array of metaphones for each word in a string
// --------------------------------------------------------------------------------------------------------------
private function getMetaPhone($phrase)
{
$metaphones = array();
$words = str_word_count($phrase, 1);
foreach ($words as $word) {
$metaphones[] = metaphone($word);
}
return $metaphones;
}
// --------------------------------------------------------------------------------------------------------------
// -- return the closest matching string found in $this->searchAgainst when compared to $this->input
// --------------------------------------------------------------------------------------------------------------
public function findBestMatchReturnString($searchAgainst, $input, $max_tolerance = 200, $max_length_diff = 200, $min_str = 3, $lower_case = true, $search_in_phrases = true)
{
if (empty($searchAgainst) || empty($input)) return "";
//weed out strings we thing are too small for this
if (strlen($input) <= $min_str) return $input;
$foundbestmatch = -1;
if ($lower_case) $input = strtolower($input);
//sort list or else not best matches may be found first
$counts = array();
foreach ($searchAgainst as $s) {
$counts[] = strlen($s);
}
array_multisort($counts, $searchAgainst);
//get the metaphone equivalent for the input phrase
$tempInput = implode(" ", $this->getMetaPhone($input));
$list = array();
foreach ($searchAgainst as $phrase) {
if ($lower_case) $phrase = strtolower($phrase);
if ($search_in_phrases) $phraseArr = explode(" ",$phrase);
foreach ($phraseArr as $word) {
//get the metaphone equivalent for each phrase we're searching against
$tempSearchAgainst = implode(' ', $this->getMetaPhone($word));
$similarity = levenshtein($tempInput, $tempSearchAgainst);
if ($similarity == 0) // we found an exact match
{
$closest = $word;
$foundbestmatch = 0;
echo "" . $closest . "(" . $foundbestmatch . ") <br>";
break;
}
if ($similarity <= $foundbestmatch || $foundbestmatch < 0) {
$closest = $word;
$foundbestmatch = $similarity;
//keep score
if (array_key_exists($closest, $list)) {
//echo "" . $closest . "(" . $foundbestmatch . ") <br>";
$list[$closest] += 1;
} else {
$list[$closest] = 1;
}
}
}
if ($similarity == 0 || $similarity <= $max_tolerance) break;
}
// if we find a bunch of a value, assume it to be what we wanted
if (!empty($list)) {
if ($most_occuring = array_keys($list, max($list)) && max($list) > 10) {
return $closest;
}
}
//echo "input:".$input."(".$foundbestmatch.") match: ".$closest."\n";
// disallow results to be all that much different in char length (if you want)
if (abs(strlen($closest) - strlen($input)) > $max_length_diff) return "";
// based on tolerance of difference, return if match meets this requirement (0 = exact only 1 = close, 20+ = far)
return ((int)$foundbestmatch <= (int)$max_tolerance) ? $closest : "";
}
// --------------------------------------------------------------------------------------------------------------
// -- Handles passing arrays instead of a string above ( could have done this in the func above )
// --------------------------------------------------------------------------------------------------------------
public function findBestMatchReturnArray($searchAgainst, $inputArray, $max_tolerance = 200, $max_length_diff = 200, $min_str = 3)
{
$results = array();
$tempStr = '';
foreach ($inputArray as $item) {
if ($tmpStr = $this->findBestMatchReturnString($searchAgainst, $item, $max_tolerance, $max_length_diff, $min_str))
$results[] = $tmpStr;
}
return (!empty($results)) ? $results : $results = array();
}
// --------------------------------------------------------------------------------------------------------------
// -- Build combos of search terms -- So we can check Cayman S or S Cayman etc.
// careful, this is very labor intensive ( O(n^k) )
// --------------------------------------------------------------------------------------------------------------
public function buildSearchCombinations(&$set, &$results)
{
for ($i = 0; $i < count($set); $i++) {
$results[] = $set[$i];
$tempset = $set;
array_splice($tempset, $i, 1);
$tempresults = array();
$this->buildSearchCombinations($tempset, $tempresults);
foreach ($tempresults as $res) {
$results[] = trim($set[$i]) . " " . trim($res);
}
}
}
// --------------------------------------------------------------------------------------------------------------
// -- Model match function -- Get best model match from user input.
// --------------------------------------------------------------------------------------------------------------
public function findBestSearchMatches($model_type, $search_terms, $models_list)
{
$partial_search_phrases = array();
if (count($search_terms) > 1) {
$this->buildSearchCombinations($search_terms, $partial_search_phrases); // careful, this is very labor intensive ( O(n^k) )
$partial_search_phrases = array_diff($partial_search_phrases, $search_terms);
for ($i = 0; $i < count($search_terms); $i++) $partial_search_phrases[] = $search_terms[$i];
$partial_search_phrases = array_values($partial_search_phrases);
} else {
$partial_search_phrases = $search_terms;
}
//sort list or else not best matches may be found first
$counts = array();
foreach ($models_list as $m) {
$counts[] = strlen($m);
}
array_multisort($counts,SORT_DESC,$models_list);
unset($counts);
//sort list or else not best matches may be found first
foreach ($partial_search_phrases as $p) {
$counts[] = strlen($p);
}
array_multisort($counts,SORT_DESC,$partial_search_phrases);
$results = array("exact_match" => '', "partial_match" => '');
foreach ($partial_search_phrases as $term) {
foreach ($models_list as $model) {
foreach ($model_type as $mt) {
if (strpos(strtolower($model), strtolower($mt)) !== false) {
if ((strtolower($model) == strtolower($term) || strtolower($model) == strtolower($mt . " " . $term))
) {
// echo " " . $model . " === " . $term . " <br>";
if (strlen($model) > strlen($results['exact_match']) /*|| strtolower($term) != strtolower($mt)*/
) {
$results['exact_match'] = strtolower($model);
return $results;
}
} else if (strpos(strtolower($model), strtolower($term)) !== false) {
if (strlen($term) > strlen($results['partial_match'])
|| strtolower($term) != strtolower($mt)
) {
$results['partial_match'] = $term;
//return $results;
}
}
}
}
}
}
return $results;
}
// --------------------------------------------------------------------------------------------------------------
// -- Get all models in DB for Make (e.g. porsche) (could include multiple makes)
// --------------------------------------------------------------------------------------------------------------
public function initializeFullModelList($make) {
$this->full_model_list = array();
$modelsDB = $this->inv->getAllModelsForMakeAndCounts($make);
foreach ($modelsDB as $m) {
$this->full_model_list[] = $m['model'];
}
}
// --------------------------------------------------------------------------------------------------------------
// -- spell checker -- use algorithm to check model spelling (could expand to include english words)
// --------------------------------------------------------------------------------------------------------------
public function spellCheckModelKeywords($search_terms)
{
// INPUTS: findBestMatchReturnArray($searchList, $inputArray,$tolerance,$differenceLenTolerance,$ignoreStringsOfLengthX,$useLowerCase);
//
// $searchList, - The list of items you want to get a match from
// $inputArray, - The user input value or value array
// $tolerance, - How close do we want the match to be 0 = exact, 1 = close, 2 = less close, etc. 20 = find a match 100% of the time
// $lenTolerance, - the number of characters between input and match allowed, ie. 3 would mean match can be +- 3 in length diff
// $ignoreStrLessEq, - min number of chars that must be before checking (i.e. if 3 ignore anything 3 in length to check)
// $useLowerCase - puts the phrases in lower case for easier matching ( not needed per se )
// $searchInPhrases - compare against every word in searchList (which could be groups of words per array item (so search every word past to function
$tolerance = 0; // 1-2 recommended
$lenTolerance = 1; // 1-3 recommended
$ignoreStrLessEq = 3; // may not want to correct tiny words, 3-4 recommended
$useLowercase = true; // convert to lowercase matching = true
$searchInPhrases = true; //match words not phrases, true recommended
$spell_checked_search_terms = $this->findBestMatchReturnArray($this->full_model_list, $search_terms, $tolerance, $lenTolerance, $ignoreStrLessEq, $useLowercase,$searchInPhrases);
$spell_checked_search_terms = array_values($spell_checked_search_terms);
// return spell checked terms
if (!empty($spell_checked_search_terms)) {
if (strpos(strtolower(implode(" ", $spell_checked_search_terms)), strtolower(implode(" ", $search_terms))) === false //&&
// strlen(implode(" ", $spell_checked_search_terms)) > 4
) {
return $spell_checked_search_terms;
}
}
// or just return search terms as is
return $search_terms;
}
}
?>

Finding all possible sequences

Hi I'm trying to build a function which will walk through all possible number sequences and pass the sequence through a function and if it return true stops.
Here is the markup:
function sequences($smallest, $biggest, $long, $func) {
$seq = array(); // Will have $long values
/*
* generates the sequence
*/
if (call_user_func($functions[$func])) {
return $seq;
} else {
//generate next sequence.
}
}
The generated sequence will have $long unique values between $smallest integer to $biggest integer and must be sorted example:
/* $long = 4; $smallest = 5, $biggest = 10;
*
* 5,6,7,8
* 5,6,7,9
* 5,6,7,10
* 5,6,8,9
* 5,6,8,10
* ...
* 7,8,9,10
*
*
* $long = 4; $smallest = 15, $biggest = 60;
*
* ...
* 15,41,49,56
* ...
* 37,39,53,60
* ...
*/
I haven’t been able to wrap my head around it, so far the only way I achieve that was to generate numbers randomly and than sorting the array each time.
That's clearly not the best way.
Other programming languages will be great too (c++, C#, js, java).
NOTES
Its not an odometer duplicate numbers in the sequence are not allowed and the values of each index can be bigger than 9.
The function that tests the sequence against a some conditions and will return True or False it doesn't matter what it does the actual problem is generating the sequences one by one without duplicates.
This was a fun challenge to generate the sequences as you specified.
This code below should do what you want (I think). Or at least you should be able to modify it to suit your needs. I wasn't exactly sure if you wanted the sequences() function to return only the first sequence for which the test function $functions[$func] returns true, or all the sequences so far. In this example only the first "match" is returned (or null if no match was found).
This code requires PHP 5.5+ as it uses a generator function (and also short array syntax available in PHP 5.4+). I tested this on PHP 5.5.12 and it seems to work as intended. The code can probably be modified to work on older PHP versions if needed (just avoid using generators/yields). Actually this is the first time I've written a PHP generator function.
sequenceGenerator() is a recursive generator function that you can iterate over using foreach.
I also wrote an echoSequences() function for testing the sequence generation which just outputs all of the generated sequences in order using echo.
function sequenceGenerator(array $items, $long = null, $level = 1, $path = null) {
$itemCount = count($items);
if (empty($long)) $long = $itemCount;
if ($path == null) $path = [];
if ($itemCount > 1) {
foreach ($items as $item) {
$subPath = $path;
$subPath[] = $item;
if ($level == $long) {
yield $subPath;
continue;
}
if (count($subPath) + count($items) > $long) {
$items = array_values(array_diff($items, [$item]));
$iteration = sequenceGenerator($items, $long, $level + 1, $subPath);
foreach ($iteration as $value) yield $value;
}
}
} elseif ($itemCount == 1) {
$path[] = $items[0];
yield $path;
}
}
// Function for testing sequence generation
function echoSequences($smallest, $biggest, $long) {
$items = range($smallest, $biggest);
foreach (sequenceGenerator($items, $long) as $sequence) {
echo implode(',', $sequence)."<br>\n";
}
}
function sequences($smallest, $biggest, $long, $func) {
global $functions;
$items = range($smallest, $biggest);
foreach (sequenceGenerator($items, $long) as $sequence) {
if (call_user_func($functions[$func], $sequence)) {
return $sequence;
}
}
return null; // Return null when $func didn't return true for any sequence
}
//echoSequences(5, 10, 4); // Test sequence generation
$functions = array(
// This test function returns true only for the sequence [5,6,8,10]
'testfunc' => function($sequence) { return ($sequence == [5,6,8,10]); }
);
$sequence = sequences(5, 10, 4, 'testfunc'); // Find the first sequence that 'testfunc' will return true for (or null)
if (!empty($sequence)) {
echo 'Found match: '.implode(',', $sequence);
} else {
echo 'Match not found';
}

Optimize my Modx snippet with getresources call inside my snippet instead of outside?

SO I have a getResources call giving me an integer value with this call:
[[!getResources? &parents=`[[*id]]` &totalVar=`totalLinks`]]
That outputs to [[+totalLinks]] and I use that to input in to my snippet
[[!ChangeNumberToWord? &input=`[[+totalLinks]]`]]
My Snippet:
$input = '';
function converttoword($total){
if ($total=="1"){
$word = "one";
} elseif($total=="2") {
$word = "two";
} elseif($total=="3") {
$word = "three";
} elseif($total=="4") {
$word = "four";
} elseif($total=="5") {
$word = "five";
} elseif($total=="6") {
$word= "six";
} elseif($total=="7") {
$word ="seven";
} elseif($total=="8") {
$word = "eight";
} else{
$word = "$total";
}
return $word;
}
$output = converttoword($input);
return $output;
My question is how I glue these 2 together so I only need to call my snippet?
Get rid of the getResources call altogether, use: getChildIds in your snippet:
http://rtfm.modx.com/revolution/2.x/developing-in-modx/other-development-resources/class-reference/modx/modx.getchildids
something like:
<?php
// current resource ID
$id = $modx->resource->get('id');
// get all child ids
$array_child_ids = $modx->getChildIds($id);
//so you would count that array
$num_children = count($array_child_ids);
// get rid of the ifs to find the word
$words = array('zero','one','two','three','four','five','six');
// do something if no results
if ($num_children + 1 > count($words)){
return 'out of range';
}
// return the string
return $words[$num_children];
so you have other problems you might need to look at depending on your application:
what if there are zero children?
what about resource status or type [published vs. unpublished, symlinks etc]
what happens if the number of children is 3033 [Three thousand, three hundred and thirty-three]?
[hint: you can google "php convert a number to it's string name" and come up with several options]

Spell check and suggest proper word in PHP

I was wondering if anyone knows of any library, script, or service that can spell check a string and return a suggestion of the properly spelled word or suggestions if more that one properly spelled word that it could be written in PHP.
I would prefer if there wasn't a limit on the amount of queries I could do, so not like Google's APIs.
It would be great if it could function like this:
// string to be spell checked stored in variable
$misspelledString = "The quick brown lama jumped over the lazy dog.";
//pass that variable to function
//function returns suggestion or suggestions as an array of string or strings
$suggestion = spellCheck($misspelledString);
echo "Did you mean ".$suggestion[0];
You can try the included Pspell functions:
http://php.net/manual/en/ref.pspell.php
Or an external plugin, like this one:
http://www.phpspellcheck.com/
Check this SO question for an example.
Not quite as nice an API as in your example, but Pspell would be an option. It may already be included with your system copy of PHP. You'll need aspell libraries for each language you want to check.
http://php.net/manual/en/book.pspell.php
On my debian based machine, it's included in the system repositories as a separate package, php5-pspell.
You need to have "pspell" PHP extension, you can install it on Linux using CLI:
sudo apt-get install php-pspell;
sudo service apache2 restart;
The code is very simple:
if ($word = $_GET['word']) {
$spellLink = pspell_new("en");
if (!pspell_check($spellLink, $word)) {
$suggestions = pspell_suggest($spellLink, $word);
echo '<p>Did you mean: <i>"'.$suggestions[0].'"</i>?</p>';
}
}
I attempted to create a class that takes a list of phrases and compares that to the user inputs. What I was trying to do is get things like Porshre Ceyman to correct to Porsche Cayman for example.
This class requires an array of correct terms $this->full_model_list , and an array of the user input $search_terms. I took out the contruct so you will need to pass in the full_model_list. Note, this didn't fully work so I decided to scrap it, it was adapted from someone looking to correct large sentences ...
You would call it like so:
$sth = new SearchTermHelper;
$resArr = $sth->spellCheckModelKeywords($search_terms)
Code (VERY BETA) :
<?php
/*
// ---------------------------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------------------------
//
// FUNCTION: Search Term Helper Class
// PURPOSE: Handles finding matches and such with search terms for keyword searching.
// DETAILS: Functions below build search combinations, find matches, look for spelling issues in words etc.
//
// ---------------------------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------------------------
*/
class SearchTermHelper
{
public $full_model_list;
private $inv;
// --------------------------------------------------------------------------------------------------------------
// -- return an array of metaphones for each word in a string
// --------------------------------------------------------------------------------------------------------------
private function getMetaPhone($phrase)
{
$metaphones = array();
$words = str_word_count($phrase, 1);
foreach ($words as $word) {
$metaphones[] = metaphone($word);
}
return $metaphones;
}
// --------------------------------------------------------------------------------------------------------------
// -- return the closest matching string found in $this->searchAgainst when compared to $this->input
// --------------------------------------------------------------------------------------------------------------
public function findBestMatchReturnString($searchAgainst, $input, $max_tolerance = 200, $max_length_diff = 200, $min_str = 3, $lower_case = true, $search_in_phrases = true)
{
if (empty($searchAgainst) || empty($input)) return "";
//weed out strings we thing are too small for this
if (strlen($input) <= $min_str) return $input;
$foundbestmatch = -1;
if ($lower_case) $input = strtolower($input);
//sort list or else not best matches may be found first
$counts = array();
foreach ($searchAgainst as $s) {
$counts[] = strlen($s);
}
array_multisort($counts, $searchAgainst);
//get the metaphone equivalent for the input phrase
$tempInput = implode(" ", $this->getMetaPhone($input));
$list = array();
foreach ($searchAgainst as $phrase) {
if ($lower_case) $phrase = strtolower($phrase);
if ($search_in_phrases) $phraseArr = explode(" ",$phrase);
foreach ($phraseArr as $word) {
//get the metaphone equivalent for each phrase we're searching against
$tempSearchAgainst = implode(' ', $this->getMetaPhone($word));
$similarity = levenshtein($tempInput, $tempSearchAgainst);
if ($similarity == 0) // we found an exact match
{
$closest = $word;
$foundbestmatch = 0;
echo "" . $closest . "(" . $foundbestmatch . ") <br>";
break;
}
if ($similarity <= $foundbestmatch || $foundbestmatch < 0) {
$closest = $word;
$foundbestmatch = $similarity;
//keep score
if (array_key_exists($closest, $list)) {
//echo "" . $closest . "(" . $foundbestmatch . ") <br>";
$list[$closest] += 1;
} else {
$list[$closest] = 1;
}
}
}
if ($similarity == 0 || $similarity <= $max_tolerance) break;
}
// if we find a bunch of a value, assume it to be what we wanted
if (!empty($list)) {
if ($most_occuring = array_keys($list, max($list)) && max($list) > 10) {
return $closest;
}
}
//echo "input:".$input."(".$foundbestmatch.") match: ".$closest."\n";
// disallow results to be all that much different in char length (if you want)
if (abs(strlen($closest) - strlen($input)) > $max_length_diff) return "";
// based on tolerance of difference, return if match meets this requirement (0 = exact only 1 = close, 20+ = far)
return ((int)$foundbestmatch <= (int)$max_tolerance) ? $closest : "";
}
// --------------------------------------------------------------------------------------------------------------
// -- Handles passing arrays instead of a string above ( could have done this in the func above )
// --------------------------------------------------------------------------------------------------------------
public function findBestMatchReturnArray($searchAgainst, $inputArray, $max_tolerance = 200, $max_length_diff = 200, $min_str = 3)
{
$results = array();
$tempStr = '';
foreach ($inputArray as $item) {
if ($tmpStr = $this->findBestMatchReturnString($searchAgainst, $item, $max_tolerance, $max_length_diff, $min_str))
$results[] = $tmpStr;
}
return (!empty($results)) ? $results : $results = array();
}
// --------------------------------------------------------------------------------------------------------------
// -- Build combos of search terms -- So we can check Cayman S or S Cayman etc.
// careful, this is very labor intensive ( O(n^k) )
// --------------------------------------------------------------------------------------------------------------
public function buildSearchCombinations(&$set, &$results)
{
for ($i = 0; $i < count($set); $i++) {
$results[] = $set[$i];
$tempset = $set;
array_splice($tempset, $i, 1);
$tempresults = array();
$this->buildSearchCombinations($tempset, $tempresults);
foreach ($tempresults as $res) {
$results[] = trim($set[$i]) . " " . trim($res);
}
}
}
// --------------------------------------------------------------------------------------------------------------
// -- Model match function -- Get best model match from user input.
// --------------------------------------------------------------------------------------------------------------
public function findBestSearchMatches($model_type, $search_terms, $models_list)
{
$partial_search_phrases = array();
if (count($search_terms) > 1) {
$this->buildSearchCombinations($search_terms, $partial_search_phrases); // careful, this is very labor intensive ( O(n^k) )
$partial_search_phrases = array_diff($partial_search_phrases, $search_terms);
for ($i = 0; $i < count($search_terms); $i++) $partial_search_phrases[] = $search_terms[$i];
$partial_search_phrases = array_values($partial_search_phrases);
} else {
$partial_search_phrases = $search_terms;
}
//sort list or else not best matches may be found first
$counts = array();
foreach ($models_list as $m) {
$counts[] = strlen($m);
}
array_multisort($counts,SORT_DESC,$models_list);
unset($counts);
//sort list or else not best matches may be found first
foreach ($partial_search_phrases as $p) {
$counts[] = strlen($p);
}
array_multisort($counts,SORT_DESC,$partial_search_phrases);
$results = array("exact_match" => '', "partial_match" => '');
foreach ($partial_search_phrases as $term) {
foreach ($models_list as $model) {
foreach ($model_type as $mt) {
if (strpos(strtolower($model), strtolower($mt)) !== false) {
if ((strtolower($model) == strtolower($term) || strtolower($model) == strtolower($mt . " " . $term))
) {
// echo " " . $model . " === " . $term . " <br>";
if (strlen($model) > strlen($results['exact_match']) /*|| strtolower($term) != strtolower($mt)*/
) {
$results['exact_match'] = strtolower($model);
return $results;
}
} else if (strpos(strtolower($model), strtolower($term)) !== false) {
if (strlen($term) > strlen($results['partial_match'])
|| strtolower($term) != strtolower($mt)
) {
$results['partial_match'] = $term;
//return $results;
}
}
}
}
}
}
return $results;
}
// --------------------------------------------------------------------------------------------------------------
// -- Get all models in DB for Make (e.g. porsche) (could include multiple makes)
// --------------------------------------------------------------------------------------------------------------
public function initializeFullModelList($make) {
$this->full_model_list = array();
$modelsDB = $this->inv->getAllModelsForMakeAndCounts($make);
foreach ($modelsDB as $m) {
$this->full_model_list[] = $m['model'];
}
}
// --------------------------------------------------------------------------------------------------------------
// -- spell checker -- use algorithm to check model spelling (could expand to include english words)
// --------------------------------------------------------------------------------------------------------------
public function spellCheckModelKeywords($search_terms)
{
// INPUTS: findBestMatchReturnArray($searchList, $inputArray,$tolerance,$differenceLenTolerance,$ignoreStringsOfLengthX,$useLowerCase);
//
// $searchList, - The list of items you want to get a match from
// $inputArray, - The user input value or value array
// $tolerance, - How close do we want the match to be 0 = exact, 1 = close, 2 = less close, etc. 20 = find a match 100% of the time
// $lenTolerance, - the number of characters between input and match allowed, ie. 3 would mean match can be +- 3 in length diff
// $ignoreStrLessEq, - min number of chars that must be before checking (i.e. if 3 ignore anything 3 in length to check)
// $useLowerCase - puts the phrases in lower case for easier matching ( not needed per se )
// $searchInPhrases - compare against every word in searchList (which could be groups of words per array item (so search every word past to function
$tolerance = 0; // 1-2 recommended
$lenTolerance = 1; // 1-3 recommended
$ignoreStrLessEq = 3; // may not want to correct tiny words, 3-4 recommended
$useLowercase = true; // convert to lowercase matching = true
$searchInPhrases = true; //match words not phrases, true recommended
$spell_checked_search_terms = $this->findBestMatchReturnArray($this->full_model_list, $search_terms, $tolerance, $lenTolerance, $ignoreStrLessEq, $useLowercase,$searchInPhrases);
$spell_checked_search_terms = array_values($spell_checked_search_terms);
// return spell checked terms
if (!empty($spell_checked_search_terms)) {
if (strpos(strtolower(implode(" ", $spell_checked_search_terms)), strtolower(implode(" ", $search_terms))) === false //&&
// strlen(implode(" ", $spell_checked_search_terms)) > 4
) {
return $spell_checked_search_terms;
}
}
// or just return search terms as is
return $search_terms;
}
}
?>

Giving text labels to integer ranges in PHP

I am attempting to take simple number ranges (in the example of this project, I am working with different increments of money for each user. FAKE money, by the way...) and group them into classes that can be displayed publicly instead of the absolute number.
Here is a rough sample of code for the long way to write this function as an example:
<?
$money=500001;
if($money > 0 AND $money < 5000) {
$class = 'Poor';
} elseif ($money >= 5000 AND $money < 25000) {
$class = 'Lower Class';
} elseif ($money >= 25000 AND $money < 100000) {
$class = 'Middle Class';
} elseif ($money >= 100000) {
$class = 'Upper Class';
}
echo $class;
exit();
?>
Now, I know this function will work, but it seems like an absolutely awful way in going about writing it, since if more $class' are added, it becomes far too long.
Now my question is: Is there a shorter way to write this? Possibly using range() and/or an array of values?
I would go for something like this:
function getClass($sal){
$classes = array(5000=>"poor", 25000=>"Lower Class", 100000=>"Middle Class");
foreach ($classes as $key => $value) {
if($sal < $key){
return $value;
}
}
return "Upper Class";
}
$salary = 90000;
$sal_class = getClass($salary);
echo "salary class = $sal_class\n";
Output:
sal = Middle Class
A bit similar to above answer, but a better one. I will suggest using OO approach.
Class Foo {
protected $class = array(
array("poor", 0, 5000),
array("medium", 5000, 25000)
);
function get_class($amount) {
foreach ($this -> class as $key => $value) {
if($amount > $value[1] && $amount < $value[2]) {
return $value[0];
}
}
return null;
}
function add_class(array $arr) {
$this -> class[] = $arr;
}
}
Usage:
$obj = new Foo();
$obj -> get_class(6000); //Outputs: medium
$obj -> add_class(array("rich", 25000, 50000)); //Add a new class
$obj -> get_class(35000); //Outputs: rich

Categories