user100051
user100051

Reputation:

How can I make the following code dry?

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

Answers (5)

Stephen Hoffman
Stephen Hoffman

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

Talljoe
Talljoe

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

Jon Hess
Jon Hess

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

Erik
Erik

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

hhafez
hhafez

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

Related Questions