0

I wrote the following piece of code to perform a custom rating of some movies in accordance to their IMDb rating (I'm scraping the rating field off of IMDb using a class I found on github).

Anyway, this worked fine for 643 movies in my DB, but for 12 specific movies it fails to recognize the correct range the IMDb rating corresponds to... It's not that those 12 have any special number instead of a rating... I wrote down the values of those 12 movies, and they are normal floats (OK, except for one that is a very old, foreign movie and it returns n/A - but even that when floatval()'ed turns to 0)... For statistical reasons, the values that can't be recognized along with the times they appear are these:

1x time 0 [it's the unrated one]
2x times a rating of 3.4
2x times a rating of 3.8
4x times a rating of 3.9
1x time a rating of 4.1
2x times a rating of 4.6

The code that performs this custom rating is this (very simple and straight-forward):

$rating = floatval($imdb->getRating());

switch (true) {
    case in_array($rating, range(1, 4.9, 0.1)):
        $return['movie_rating'] = 1;
        break;
    case in_array($rating, range(5, 5.9, 0.1)):
        $return['movie_rating'] = 2;
        break;
    case in_array($rating, range(6, 6.9, 0.1)):
        $return['movie_rating'] = 3;
        break;
    case in_array($rating, range(7, 7.9, 0.1)):
        $return['movie_rating'] = 4;
        break;
    case in_array($rating, range(8, 10, 0.1)):
        $return['movie_rating'] = 5;
        break;
    default:
        $return['movie_rating'] = 'n/A';
}

Guys, honestly, this is driving me crazy. Any suggestion will be very much appreciated! TIA.

Faye D.
  • 833
  • 1
  • 3
  • 16
  • the is the slowest solution for the problem I can imagine, just convert it into several if else - will work much much better (in terms of correctness and speed) – Iłya Bursov Jun 23 '21 at 00:13

1 Answers1

1

problem happens because of floating point math is not precise

to avoid it I suggest to rewrite this code this way:

if ($rating >= 8) $return['movie_rating'] = 5;
elseif ($rating >= 7) $return['movie_rating'] = 4;
elseif ($rating >= 6) $return['movie_rating'] = 3;
elseif ($rating >= 5) $return['movie_rating'] = 2;
elseif ($rating >= 1) $return['movie_rating'] = 1;
else  $return['movie_rating'] = 'n/A';
Iłya Bursov
  • 23,342
  • 4
  • 33
  • 57
  • Your answer is the reason why this community is so invaluable! Honestly, I'd never think of that on my own, or even accidentally happen to stumble upon the answer... I was wasting time reading and re-reading my code (as if it was something complicated) in an attempt to find where is the hidden bug... Anyway, I can't thank you enough for this! Cheers my friend! – Faye D. Jun 23 '21 at 01:14