Reputation:
How can I make my following code "DRY" (Dont Repeat Yourself)
- (void)updateLetterScore { // NOT DRY... Must fix
if (percentScore < 60.0)
letterLabel.text = [NSString stringWithFormat:@"F"];
if (percentScore > 59.0 && percentScore < 64.0)
letterLabel.text = [NSString stringWithFormat:@"D-"];
if (percentScore > 64.0 && percentScore < 67.0)
letterLabel.text = [NSString stringWithFormat:@"D"];
if (percentScore > 66.0 && percentScore < 70.0)
letterLabel.text = [NSString stringWithFormat:@"D+"];
if (percentScore > 69.0 && percentScore < 74.0)
letterLabel.text = [NSString stringWithFormat:@"C-"];
if (percentScore > 73.0 && percentScore < 76.0)
letterLabel.text = [NSString stringWithFormat:@"C"];
if (percentScore > 76.0 && percentScore < 80.0)
letterLabel.text = [NSString stringWithFormat:@"C+"];
if (percentScore > 79.0 && percentScore < 84.0)
letterLabel.text = [NSString stringWithFormat:@"B-"];
if (percentScore > 83.0 && percentScore < 86.0)
letterLabel.text = [NSString stringWithFormat:@"B"];
if (percentScore > 85.0 && percentScore < 90.0)
letterLabel.text = [NSString stringWithFormat:@"B+"];
if (percentScore > 89.0 && percentScore < 94.0)
letterLabel.text = [NSString stringWithFormat:@"A-"];
if (percentScore > 93.0 && percentScore < 100.0)
letterLabel.text = [NSString stringWithFormat:@"A"];
if (percentScore == 100)
letterLabel.text = [NSString stringWithFormat:@"A+"];
}
Thanks for the tips. I just wanna know what you guys think because this little snippit looks HORRENDOUS in my code.
Upvotes: 1
Views: 489
Reputation: 312
With all of one hundred entries involved here, use an array containing the grade letter code and [array objectAtIndex: i] offset into the array based on the integer grade value. Done.
With Cocoa, you can either build this array directly in the code, or load the array from backing store (arrayWithContentsOfFile:) and allow Cocoa to sort out the storage.
You can one-plus this particular design by permitting the user to adjust the grade ranges by rewriting the saved grade array, and the code itself doesn't change.
Upvotes: 0
Reputation: 14827
One way (pseudo-code since I don't know objective C):
grades = ["F", "D-", "D", ...]
scores = [60.0, 64.0, 67.0, ...]
for(i = 0; i < grades.count; i = i + 1)
{
if(score < scores[i])
{
letterLabel.text = [NSString stringWithFormat:@"%@", grades[i]]
break;
}
}
Upvotes: 10
Reputation: 14247
Like others, I would put the values into a table, and then scan the table. The table is small, it probably isn't worth making some more O() efficent structure like a tree.
typedef struct {
float minPercent;
NSString *letterGrade;
} GradeRange
- (NSString *)letterGradeForPercentage:(float)percentage {
GradeRange ranges[] = {{.minPercent = 100, .letterGrade = @"A+"},
...
{.minPercent = 66.0, .letterGrade = @"D+"},
{.minPercent = 64.0, .letterGrade = @"D"}};
NSString *grade = nil;
for(NSInteger i = 0; !grade && i < (sizeof(ranges) / sizeof(ranges[0])); i += 1) {
if (percentage >= ranges[i].minPercent) {
grade = ranges[i].letterGrade;
}
}
return grade;
}
Upvotes: 4
Reputation: 898
If this abomination was in my care, I would extract all the magic values and place them in a table and iterate through the table checking to see which range your percentScore falls in. You might want to recheck all your ranges, they don't seem to address all the values that percentScore could assume.
Upvotes: 1
Reputation: 39780
Talljoe showed one way to do it, but the idea is simply store all the scores in some sort of lookup table
Upvotes: 2