brandy
brandy

Reputation: 3

Using multiple key values for dictionary

Trying to make program output a grade for a percentage entered:

percentage=90
grades={percentage>=80:'A',
        percentage>=60:'B',
        percentage>=40:'C',
        percentage<39:'Fail'}
print(grades[percentage])

Initially want the program to print 'A'


Instead I get an error :

Traceback (most recent call last):
line 10, in <module>
print(grades[percentage])
KeyError: 90

Any help is appreciated, thanks.

Upvotes: 0

Views: 154

Answers (5)

CodeCollector
CodeCollector

Reputation: 476

If you only want to use dictionary.. this is one dirty way to use it.

percentage=70
grades={80:'A',
        60:'B',
        40:'C',
        39:'Fail'}

grade_vals = grades.keys()
obtained_grade = 'NONE'
# Sorting is super necessary
grade_vals.sort(reverse = True)
for grade in grade_vals:
    if percentage > grade:
        obtained_grade = grades[grade]
        break

print(obtained_grade)

Upvotes: 0

Shaun Taylor
Shaun Taylor

Reputation: 326

This relates to the order in which Python evaluates expressions.

You've used boolean expressions as keys in the grades dictionary. When the grades dictionary is being evaluated, first the booleans will be evaluated, then the dictionary will be instantiated.

So we start with

grades={percentage>=80:'A',
        percentage>=60:'B',
        percentage>=40:'C',
        percentage<39:'Fail'}

Since percentage has been set to 90, the first three conditions are True and the last one is False, so the dictionary becomes:

grades={True:'A',
        True:'B',
        True:'C',
        False:'Fail'}

I expect if you tried doing print(grades[False]) you would get 'Fail'.

Instead, I suggest you key the dictionary on the lower grade boundary:

grades={80: 'A',
        60: 'B',
        40: 'C',
        0: 'Fail'}

Then iterate over the dictionary and select the grade that is nearest to precentage, but not greater than it:

grade_boundary = min([x for x in grades.keys() if percentage > x])
grade = grades[grade_boundary]

Upvotes: 0

Manuel
Manuel

Reputation: 706

You can use a function

def grade(percentage):
    if percentage >= 80:
        return 'A'
    elif percentage >= 60:
        return 'B'
    elif percentage >= 40:
        return 'C'
    else:
        return 'Fail'

Upvotes: 2

andrew_reece
andrew_reece

Reputation: 21264

You're treating a dict like a function which returns values by evaluating keys as logical statements. A dict is a store of fixed key-value pairs; it doesn't work the way you're expecting it to.

You can either write a function to evaluate a given grade, or, you can create a dict that contains every possible score-grade pair, and look up grades by score.

It seems like the second approach is more what you're going for, but the problem is that calling grades[percentage] requires there be an exact percentage stored in the grades dict. I'd recommend building a function instead.

This looks like it might be part of some kind of homework assignment, so I'll leave a starting point that you can build off of. Something like this:

def compute_grade(p):
    if grade >= 80:
        return 'A'
    elif grade >= 60:
        ...

Upvotes: 2

Ajax1234
Ajax1234

Reputation: 71451

You are creating a dictionary where each key is a boolean value based on the results of the each comparison.

percentage=90
grades={percentage>=80:'A',
    percentage>=60:'B',
    percentage>=40:'C',
    percentage<39:'Fail'}

Thus, dictionary is actually:

{False: 'Fail', True: 'C'}

Instead, create a structure that utilizes range:

class Data:
   def __init__(self):
      self.grades = {tuple(range(80, 101)):'A', tuple(range(60, 80)):'B', tuple(range(40, 60)):'C'}
   def __getitem__(self, val):
      return "Fail" if not [b for a, b in self.grades.items() if val in a] else [b for a, b in self.grades.items() if val in a][0]
d = Data()
print(d[90])

Output:

'A'

Upvotes: 0

Related Questions