'How to calculate rating by percent score in python?

Let say, when student completed the course then he will get the percentage of his completion.
Then we implement the max ratings is 5 stars which following these rules:

  • 0%-4% of percent score, will get 0 star
  • 5%-19% of percent score, will get 1 star
  • 20%-39% of percent score, will get 2 stars
  • 40%-59% of percent score, will get 3 stars
  • 60%-79% of percent score, will get 4 stars
  • 80%-100% of percent score, will get 5 stars

So, based on student score:

  • 0% of percent score will get 0 rating star.
  • 19% of percent score will get 1 rating star.
  • But, in another conditionals when student get 30% percent of score, then he should get 2.5 of rating stars based on above range rules.

NOTE: The max 5 stars is dynamic value, it can be 10 stars.


So far, here is the code to achieve above problem:

rate_settings = {
    "1": 10,
    "2": 20,
    "3": 30,
    "4": 60,
    "5": 80
}
required_rate = ["1", "2", "3", "4", "5"]


def calculate_rating(percent):
    rate_settings_keys = list(rate_settings.keys())
    rate_settings_values = list(rate_settings.values())
    if not all(map(lambda rate: rate in required_rate, rate_settings_keys)) or len(required_rate) != len(rate_settings_keys):
        raise Exception("invalid rate config")
    if any(map(lambda rate: rate < 0 or rate > 100, rate_settings_values)):
        raise Exception("invalid rate value, must be between 0 - 100")
    if rate_settings_values != sorted(rate_settings_values):
        raise Exception("invalid rate value, must be sorted")
    for rate in reversed(rate_settings):
        passing_value = rate_settings[rate]
        if percent >= passing_value:
            return rate
    return 0

print(calculate_rating(0))  # 0
print(calculate_rating(10))  # 1
print(calculate_rating(15))  # 1
print(calculate_rating(30))  # 3
print(calculate_rating(100))  # 5

As you can see, above script only achieve integer of stars, but yet for this issues:

  • But, in another conditionals when student get 30% percent of score, then he should get 2.5 of rating stars based on above range rules.
  • NOTE: The max 5 stars is dynamic value, it can be 10 stars.

how we can accomplish this?

Solved

Bassed on @Eilonlif answer, finally we solve this problem:

import statistics
from typing import Union

# Ratings with 5 stars
# 0%-4% => 0 star
# 5%-19% => 1 star
# 20%-39% => 2 stars
# 40%-59% => 3 stars
# 60%-79% => 4 stars
# 80%-100% => 5 stars

NUM_OF_RATINGS = 5
RANGE_SCORES = [
    (0, 4),
    (5, 19),
    (20, 39),
    (40, 59),
    (60, 79),
    (80, 100),
]


def percent_to_stars(percentage: Union[int, float, None], ranges=None):
    if not percentage:
        return None
    if ranges is None:
        ranges = RANGE_SCORES
    for index, range_score in enumerate(ranges):
        if range_score[0] <= percentage <= range_score[1]:
            middle = statistics.median(range(*range_score))
            if percentage >= middle:
                sum_rating = index + 0.5
                if sum_rating < NUM_OF_RATINGS:
                    return sum_rating
            return index
    return -1


print(percent_to_stars(11))  # 1
print(percent_to_stars(99))  # 5
print(percent_to_stars(30))  # 2.5


Solution 1:[1]

Here is the new code:

def percent_to_stars(percentage: int, ranges=None, decimal=False):
    if ranges is None:
        ranges = [(0, 4), (5, 20), (20, 40), (40, 60), (60, 80), (80, 101)]
    for i, r in enumerate(ranges):
        if r[0] <= percentage < r[1]:
            if decimal and percentage >= sum(r)//2:
                return min(i + 0.5, len(ranges) - 1)
            return i
    return -1


print(percent_to_stars(30, decimal=True))
print(percent_to_stars(30))

The answer is edited to meet the requirements.

Personally, I feel your code is a bit hard to read, however, you don't have to use my implementation.

Solution 2:[2]

Here is what I would do:

For perfect star calculations

while True:
    students_score = int(input("Enter the students score as a percentage: "))

    if students_score >= 0 and students_score <= 4:
        print("This student got 0 stars")
        print("")

    if students_score >= 5 and students_score <= 19:
        print("This student got 1 star")
        print("")

    if students_score >= 20 and students_score <= 39:
        print("This student got 2 stars")
        print("")

    if students_score >= 40 and students_score <= 59:
        print("This student got 3 stars")
        print("")
        
    if students_score >= 60 and students_score <= 79:
        print("This student got 4 stars")
        print("")

    if students_score >= 80 and students_score <= 100:
        print("This student got 5 stars")
        print("")

For decimal star calculations

while True:
    students_score = int(input("Enter the students score as a percentage: "))
    star_score = 5/100 * students_score
    print("This student got ",star_score," stars")
    print("")

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 James Fuller