I have a rating system that uses the following equation to generate the rating average:
((Old Rating*Old Times Amount)+New Rating)/New Rating amount
However, if the current rating is 3, and it's been rated once, when I rate it three, it says the new rating is 2.5
What is the error here? Here's the full code.
<?php
session_start();
include("lib/db.php");
$db = new DBConnect;
if(isset($_POST['rating']) && is_numeric($_POST['rating']) && is_numeric($_POST['story']))
{
if($_POST['rating'] > 5 || $_POST['rating'] < 1){die("INVALID RATING");}
$rating = mysql_real_escape_string($_POST['rating']);
$story = mysql_real_escape_string($_POST['story']);
$c = $db->query("SELECT * FROM cdb_stories WHERE id=$story");
$c = mysql_fetch_array($c);
$u_name = mysql_real_escape_string($_SESSION['logged_in']);
$uid = $db->query("SELECT id FROM cdb_users WHERE username='{$u_name}'");
if(mysql_num_rows($uid) < 1){die("NOT LOGGED IN");}
$uid = mysql_fetch_array($uid);
$ratingd = $db->query("SELECT * FROM cdb_ratings WHERE userid='{$uid['id']}'");
if(mysql_num_rows($ratingd) > 0)
{
$ratingd = mysql_fetch_array($ratingd);
$new_rate = (($c['rating']*$c['rating_amt'])-$ratingd['rating']+$rating)/$c['rating_amt'];
$db->query("UPDATE cdb_stories SET rating={$new_rate} WHERE id={$story}");
$db->query("UPDATE cdb_ratings SET rating={$rating} WHERE userid='{$uid['id']}'");
die();
}
$new_num = $c['rating_amt']+1;
$new_rate = (($c['rating']*$c['rating_amt'])+$rating)/$new_num;
$db->query("UPDATE cdb_stories SET rating_amt={$new_num}, rating={$new_rate} WHERE id={$story}");
$db->query("INSERT INTO cdb_ratings VALUES({$uid['id']},{$rating},{$story})");
}
else
{
die("INVALID FIELDS");
}
?>
((Rating * Times) + New) / (Times + 1)
For your values:
((3 * 1) + 3) / (1 + 1)
= ( 3 + 3) / 2
= 6 / 2
= 3
So the procedure looks mathematically correct.
I suggest you put the calculation into a function of it's own with parameters, so you don't get irritated so much by the rest of the code you have in that batch. This will make it easier to debug for you:
function new_rate($rating, $times, $new)
{
return (($rating * $times) + $new) / ($times + 1);
}
You can then use that more easily within your code. Additionally if something else is the cause of the error, you can simply find out by testing the bare function. If it acts correct, you know that the error is placed somewhere else.
Hope this helps.