I have a function which contains a query and a percentile calculation (below) on the query's results/collection.
This function is needed in the following way:
I have an Athlete model, with many Tests. Each Test also has many Results. For every result (displayed in a table), I need to display a calculated percentile (which is not stored). It's at this point (the table view) where I need the function to calculate the percentile for every result.
I have detailed the models here. The answer of that post also shows the query used.
If I stick that function in the Result model, it allows me easy access to it from the view in this manner
If I put it in a Controller, I would need some dynamic and complex way to call a route for each specific Result in the table. Not even sure how to do this.
Question: Is it correct to have this query and calculation in the Result model?
An earlier post here, seems to also go with model.
The calculation performed on the query collection:
for ($i = 1; $i < 100; $i++ ){
$rank = 0.0;
$p = 0.0;
$rank = $i/100 * ($count + 1);
$p = $rank;
//get integer and decimal for interpolation http://onlinestatbook.com/lms/introduction/percentiles.html
$intpart = floor($p);
$fraction = $p - $intpart;
//dd($intpart . ' '.$fraction);
if($fraction > 0){ //part of percentile formula - see article
//test for min array index to not be out of bound. Test negative, most used case.
if($intpart != 0){
$scoreLow = $all_scores[$intpart - 1];
if($intpart == $count){ //test for max array index to not go over bound
$scoreHigh = $all_scores[$intpart - 1];
} else{
$scoreHigh = $all_scores[$intpart];
}
} else{
$scoreLow = $all_scores[0];
$scoreHigh = $all_scores[$intpart];
}
//scoreLow and scoreHigh has been determined, now final step for decimal rank
$scoreHigh = $scoreHigh * 1.0;
$scoreLow = $scoreLow * 1.0;
$rank = ($fraction * ($scoreHigh - $scoreLow)) + $scoreLow;
} else{
$rank = ($all_scores[$intpart - 1] * 1.0);//no decimal rank, plain rank calculation
}
if($sortorder == 'asc'){
$rankings[$i.'th %'] = $rank;
}else{
$rankings[100 - $i.'th %'] = $rank;
}
//$rankings->add(['rank'.$i => $rank]);
}
//dd($rankings);
//reverse rankings
$rev_rankings = array_reverse($rankings);
if ($battery == 111){
dd($rev_rankings);
}
$view_rank = null;
foreach($rev_rankings as $key => $rank){
if($athlete_score == $rank){
$view_rank = $key;
break;
}
if($athlete_score > $rank){
$view_rank = $key;
break;
}
}
return($view_rank);
}
else{
return ('Not available');
}
via louisav