PHP rating system - php

I have a table (review) which stores the values (1-5) for ratings. I will use the sum of these ratings for the overall score.
I have 5 stars on the page which will show on or off depending on the overall value.
I have the overall score by counting the total value of all the ratings divided by the number of reviews in the table. This give a value below 5 every time...great.
However I now have a problem where the value could either be 1.5 or 1.75 for instance. If the value is 1.5 I will show 1 and a half stars on and 3 and a half stars off. How should I determine if the value is 1.75 to show only the 1.5 value star.
Hope that makes sense.

That should be a simple math problem, since your resolution is 1/2, multiply by two, round it, then divide by 2:
round(x * 2) / 2
round((1.75) * 2) / 2 = 2
round((1.65) * 2) / 2 = 1.5

<?php
$tests = array(-1, 0, 0.25, 0.5, 1, 1.5, 1.75, 3, 4.22, 6);
foreach($tests as $test)
echo "Initial rate = ".$test.", adjusted rate = ".adjustRate($test)."\n";
function adjustRate($val)
{
if ($val < 0)
return 0;
if ($val > 5)
return 5;
return floor($val * 2) / 2;
}
Gives for example:
Initial rate = 1.75, adjusted rate = 1.5

Related

Calculate rating for 5 stars depending of reviews

I have good reviews, and I have bad reviews. I need calculate rating from this reviews for post.
Example:
Post 1 have 1 good reviews, and 2 bad reviews
Post 2 have 12 good reviews, and 5 bad reviews
Post 3 have 0 good reviews, and 0 bad reviews
How I can calculate rating? I need for post get 5 stars. I need score up to 5 stars or less. May be I need this formula?
$score = ($good_reviews * $bad_reviews) / 5; //get rating stars
But I don't get 5, or less number. How I can do it correctly?
Maybe you want this:
$rating = $good_reviews
? intval ( 5.4 * $good_reviews / ( $good_reviews + $bad_reviews))
: 0;
And now step by step:
SUM := $good_reviews + $bad_reviews is the sum of all reviews.
RATE := $good_reviews / SUM is the general rating of $good_reviews to the sum of reviews. The result is in the range 0.000 to 1.000 .
Multiplying it with 5.4 expands the range to 0.000 to 5.400. Its a little bit tricky to allow some bad votes for a 5 stars ranking. The factor can be every number between 5.000 and 5.9999999.
intval() reduces the number to an int from 0 to 5 (your stars).
The alternative by ?: avoids an division by zero error.
That formula will not give you what you need. It will only multiply good with bad and divide by 5. For example ((100 good * 20 bad) / 5) = 400. Way out of 5!
If you need score up to five stars you will need to use ranges.
Calculate percentage between good and bad and then do an if checks.
For example:
$percentage = (($good - $bad) / $good) * 100;
if($percentage => 100) {
//5 starts
} else if ($percentage < 100 && $percentage => 80) {
//4 stars
} else if ($percentage < 80 && $percentage => 60) {
//3 stars
} else if ($pecentage < 60 && $percentage => 40) {
//2 starts
} else {
//1 star
}
That's just a basic example. There are different ways to approach this. You need to adjust it to your needs and try if it works for you.
I did this really quick, so didn't test it. Please, check and see if it fits you. I just wanted to give you an idea.

Adding values of an array N times to reach a target

I have a target number (maximum capacity of more than one class room)
An array of department IDs .
$depts = array(1,2,3);
A function that returns the total number of students taking a particular course from a Department.
function noStudentsTakingCourse ($dept_id){
//Some expressions..
return $student_count;
}
An array of capacity of the available rooms, ie, the capacity of class rooms that are vacant
$available_room_capacities = array(50, 75, 40, 36, 100, 250);
What I want is:
From the department IDs, I want each available class room to be assigned a department in which the number of students taking that in the department is greater or equal to the room capacity.
I don't know if you get me, but am fairly new to programming and I've spent days trying to get this without any success.
$total_no_of_students_taking_course = 223;
$dept_ids_taking_course = array(1, 2, 3);
$available_room_capacities = array(50, 70, 35, 59, 95, 100);
function noOfStudentsTakingCourse($dept_id)
{
$r = 0;
if ($dept_id == 1) {
$r = 100;
} elseif ($dept_id == 2) {
$r = 56;
} elseif ($dept_id == 3) {
$r == 67;
}
return $r;
}
Hers's what i've been able to come up with. all it does is randomly sum values from the class_room array until they're greater than the total number of students taking the course. But, most times it sums more than 5 values when the department here is only 3. i want the case where by:
- Department 1 (with capacity of 100) would be allocated a room greater of equal to 100,
- Department 2 (with capacity of 56) would be allocated a room greater or equal to 56 and so on.
That means the final array would be of lenght 3 and its sum would not be less than 223 (according to the code above)
THANKS IN ADVANCE

How to equialy divide integer by 5

This is for an incremental webgame:
How can I split an integer in pieces of 5 and also keep the remaining value?
So lets say I got an integer who's value is 12, I want to substract 2x5 and the remaining would be 2.
basically to store my workers in houses, every house stores 5 workers so the first 2 houses would be 5/5 and the third 2/5.
You can use % which will give you the remaining
example:
$workers = 12;
$houseStorage = 5;
$fullHouses = (int) ($workers / $houseStorage);
$remainingWorkers = $workers % $houseStorage;
The $fullHouses will be 2 and the $remainingWorkers will be also 2
You can play with this example at https://3v4l.org/fi4d3
Edit
$fullHouses = (int) ($workers / $houseStorage);
Here I'm casting to (int) so that no float is given.

Voting percentage calculation error [duplicate]

This question already has answers here:
How to deal with the sum of rounded percentage not being 100?
(5 answers)
Closed 9 years ago.
I have created a php program where user can can vote on polls and after that, the poll result will displayed with only percentage, however I am facing an error in my program. Code which I am using for percentage calculation is <?php echo round(($num_votes / $total_votes) * 100) ?>
Now If we talk about a sample poll result, assume we have five options
option A - 4 votes
option B - 2 votes
option C - 4 votes
option D - 1 votes
option E - 0 votes
Total votes = 11
In this scenario the percentage result generating is
option A - 36%
option B - 18%
option C - 36%
option D - 9%
option E - 0%But the total of percentage is 99% instead of 100%. What I want is total should always be 100% Any help would be appreciated
Thanks.
If you are working with rounded numbers, you can indeed end up with...rounded numbers. And the sum of those rounded numbers will be different from the regular sum. There's little you can do to change that. If you insist, you'd have to:
calculate the rounded numbers
calculate the sum, and if not 100%,
loop through the rounded numbers and decide which one should get the missing percent.
But you're messing with the data. You may think you're cleaning it, but you're messing it up.
This way lead to ~100%, 'number_format' is nice thing
$a = 4;
$b = 2;
$c = 4;
$d = 1;
$e = 0;
$total = $a + $b + $c + $d + $e;
$arr = array(
'a' => number_format(($a / $total) * 100, 3),
'b' => number_format(($b / $total) * 100, 3),
'c' => number_format(($c / $total) * 100, 3),
'd' => number_format(($d / $total) * 100, 3),
'e' => number_format(($e / $total) * 100, 3)
);
foreach ($arr as $answer => $percentage) {
echo $answer .': '. $percentage . '<br />';
}
// this will be 100.001 so we format is
echo 'total: '. number_format(array_sum($arr), 2);
You can specify number of digits after decimal places in round.
ex:round(number,2);
There's nothing out-of-the-box you can do about it, if you floor() everything you'll miss one point, if you ceil() you'll gain one point.
You could floor() everything then if then calculate the array_sum(), if not 100 then find min() and ceil() it.

Rounding in PHP to achieve 100%

I need to total the number of clicks over 10 links on my page and then figure out the percentage of people that clicked each. This is easy division, but how do I make sure that I get a round 100% at the end.
I want to use the below code, but am worried that a situation could arise where the percentages do not tally to 100% as this function simply removes the numbers after the period.
function percent($num_amount, $num_total) {
$count1 = $num_amount / $num_total;
$count2 = $count1 * 100;
$count = number_format($count2, 0);
echo $count;
}
Any advice would be much appreciated.
Instead of calculating one percentage in your function you could pass all your results as an array and process it as a whole. After calculating all the percentages and rounding them make a check to see if they total 100. If not, then adjust the largest value to force them all to total 100. Adjusting the largest value will make sure your results are skewed as little as possible.
The array in my example would total 100.02 before making the adjustment.
function percent(array $numbers)
{
$result = array();
$total = array_sum($numbers);
foreach($numbers as $key => $number){
$result[$key] = round(($number/$total) * 100, 2);
}
$sum = array_sum($result);//This is 100.02 with my example array.
if(100 !== $sum){
$maxKeys = array_keys($result, max($result));
$result[$maxKeys[0]] = 100 - ($sum - max($result));
}
return $result;
}
$numbers = array(10.2, 22.36, 50.10, 27.9, 95.67, 3.71, 9.733, 4.6, 33.33, 33.33);
$percentages = percent($numbers);
var_dump($percentages);
var_dump(array_sum($percentages));
Output:-
array (size=10)
0 => float 3.51
1 => float 7.69
2 => float 17.22
3 => float 9.59
4 => float 32.86
5 => float 1.28
6 => float 3.35
7 => float 1.58
8 => float 11.46
9 => float 11.46
float 100
This will also work with an associative array as the function parameter. The keys will be preserved.
These figures could now be presented in a table, graph or chart and will always give you a total of 100%;
What you want to do is this.
Total the number of clicks across the board, then divide each number by the total.
For example:
1134
5391
2374
2887
In this case, four buttons, with a total of 11786 clicks, so:
1134 / 11786 = 0.09621....
5391 / 11786 = 0.45740....
2374 / 11786 = 0.20142....
2887 / 11786 = 0.24495....
Then for each division, round the result to 'two decimal points', so the first result:
0.09621.... becomes 0.10
because the 3rd point is 5 or above, it would remain at 0.09 if the 3rd point was below 5.
Once you have all of the results rounded, multiply each by 100 then add them up.
The ending result will always be 100.
Should warn you however that depending on how you use each individual percentage, when you round them, any result less that 0.05 will become 0%, unless you keep the value before you round it so you can declare it as a percentage less than 1.
I think you want to use ceil() or round() .
Since these are floating point numbers, there is room for error. Be careful how you round, and be sure that you don't independently calculate the last remaining percentages. Simply subtract the total of what you have from 1 or 100.
Make sure you dont calculate separate sides of the equation, sum one side, then subtract the other from 1 or 100 or however you are handling your percentages.
I run into this quite a bit and have a hack for it.
$percentages = array(
'1' => 87.5,
'2' => 12.5,
'3' => 0,
'4' => 0,
'5' => 0
);
If you round those percentages for output, you will end up with 88% and 13% (101%)
round($percentages['1']);
round($percentages['2']);
// 88
// 13
So here is the code I use to fix it.
$checkTotal = array_sum($percentages);
$max = max(array_keys($percentages));
if ($checkTotal > 100) {
$percentages[$max] = $percentages[$max] - 1;
}
if ($checkTotal < 100) {
$percentages[$max] = $percentages[$max] + 1;
}
If it is 100, do nothing.
If it is less than 100, add 1 to equal 100
If it is over 100, subtract 1 to equal 100

Categories