Math isn't one of my strong points, and I would like to know how to do this properly (I could hack somthing together, but it would be a mess):
Example figures:
Thanks guys.
Integrated solution
this is what I went with :
private const int NUMSTARS = 3;
public int starsFor(int pScore, int pPassMark)
{
if(pScore < pPassMark)
{
return 0;
}
else if (pScore == pPassMark)
{
return 1;
}
else
{
return (int)Math.Ceiling(NUMSTARS * ((pScore - pPassMark) / (double)(100 - pPassMark)));
}
}
This is a Java implementation; C# translation should be straightforward. This assumes linear interpolation:
public static int starsFor(int mark, int passMark, int numStars) {
if (mark < passMark)
return 0;
else if (mark == passMark)
return 1;
else
return (int) Math.ceil(
numStars * (
(mark - passMark) / (double) (100 - passMark)
)
);
}
Then we have (as seen on ideone.com):
System.out.println(starsFor(70, 75, 5)); // 0
System.out.println(starsFor(75, 75, 5)); // 1
System.out.println(starsFor(80, 75, 5)); // 1
System.out.println(starsFor(81, 75, 5)); // 2
System.out.println(starsFor(93, 75, 5)); // 4
System.out.println(starsFor(99, 75, 5)); // 5
System.out.println(starsFor(100, 75, 5)); // 5
Here's a slight variation that handles extra points as well. It uses integer division, without requiring double
cast and Math.ceil
. Ternary/conditional ?:
operator is used (for style!).
static int starsFor(int mark, int passMark, int maxMark, int numStars) {
return
(mark >= maxMark) ?
numStars
:
(mark < passMark) ?
0
:
1 + numStars * (mark - passMark) / (maxMark - passMark);
}
Then we have (as seen on ideone.com):
Console.WriteLine(starsFor(50, 75, 100, 5)); // 0
Console.WriteLine(starsFor(75, 75, 100, 5)); // 1
Console.WriteLine(starsFor(79, 75, 100, 5)); // 1
Console.WriteLine(starsFor(80, 75, 100, 5)); // 2
Console.WriteLine(starsFor(93, 75, 100, 5)); // 4
Console.WriteLine(starsFor(100, 75, 100, 5)); // 5
Console.WriteLine(starsFor(110, 75, 100, 5)); // 5 no extra stars!
Following function may give you the expected result.
Logic I used:
- If passing marks are 75%, then 75%=1 star
- and you want to give max 5 stars to the user
- then divide remaining marks into 5 equal parts (75 to 80, 81 to 85, 86 to 90, 91 to 95 and 96 100)
- Apply the stars depending on this range.
public int RateMyUser(int MaxStars, int MinThreshold, int MarksObtained)
{
int division = 0;
int stars = 0;
// this will give division of remaining score greater than passing percentage<br>
division = (100 - MinThreshold) / MaxStars;
if (MarksObtained >= MinThreshold)
{
// obtain the stars to be given
stars = (MarksObtained - MinThreshold) / division; // integer representing stars
return stars + 1;
}
return stars;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With