Home > Mobile >  My loop keeps on multiplying by the number of values
My loop keeps on multiplying by the number of values

Time:07-13

Say I have these students with their corresponding grades and weights:

grades = {'terri': [55,90,10], 'kerry': [88,66,77], 'sherry': [70, 90,10], 'jerry': [90, 60, 90], 'hari': [0, 100, 97]}

weights = [20,40,40]

I then want to create a function that finds the weighted average

def final_grade(gr,wghts):
    """
    input: A dict (with students as keys & a list of length n) and a set of weights for each assignment (length n)
    output: list of pairs (stu_nam/grade)
    """
    its=range(len(wghts))
    weigh_grad={}
    for stu in gr:
        for grads in gr[stu]:
            for i in its:
                if stu not in weigh_grad:
                    weigh_grad[stu]=(gr[stu][i]*wghts[i])/100
                else:
                    weigh_grad[stu] =(gr[stu][i]*wghts[i])/100
    return weigh_grad

final_grade(grades,weights)

My output is:

>>> {'terri': 153.0,'kerry': 224.40000000000003,'sherry': 162.0,'jerry': 234.0,'hari': 236.39999999999998}

Use the example of Terri. Their weighted average is actually 51. It has trebled. The same occured to Kerry and so on. All of my outputs are treble what I expected.

CodePudding user response:

Every key in a dictionary is unique. You are iterating over each key too many times and writing over the value stored at that key.

Code:

grades = {'terri': [55,90,10], 'kerry': [88,66,77], 'sherry': [70, 90,10], 'jerry': [90, 60, 90], 'hari': [0, 100, 97]}

weights = [20,40,40]

def final_grade(gr,wghts):
    """
    input: A dict (with students as keys & a list of length n) and a set of weights for each assignment (length n)
    output: list of pairs (stu_nam/grade)
    """
    weigh_grad={}

    for stu, grads in gr.items():
        weigh_grad[stu] = 0.0
        for idx, g in enumerate(grads):
            weigh_grad[stu]  = g * wghts[idx] / 100
            
    return weigh_grad

Output:

{'terri': 51.0, 'kerry': 74.8, 'sherry': 54.0, 'jerry': 78.0, 'hari': 78.8}

CodePudding user response:

This is the problem:

for grads in gr[stu]

Use this instead, your code is running three more times because of the extra for loop:

def final_grade(gr,wghts):
    """
    input: A dict (with students as keys & a list of length n) and a set of weights for each assignment (length n)
    output: list of pairs (stu_nam/grade)
    """
    its=range(len(wghts))
    weigh_grad={}
    for stu in gr:
        s = 0
        for i in its:
            s =(gr[stu][i]*wghts[i])/100
        weigh_grad[stu]=s
    return weigh_grad

CodePudding user response:

A possible solution is:

def final_grade(grades_per_student, wghts):
    """
    input: A dict (with students as keys & a list of length n) and a set of weights for each assignment (length n)
    output: list of pairs (stu_nam/grade)
    """
    total_weight = sum(wghts)
    weighted_averages = {}

    for student, student_grades in grades_per_student.items():

        weighted_averages[student] = 0

        for index, grade in enumerate(student_grades):
            weighted_averages[student]  = grade * wghts[index] / total_weight

    return weighted_averages 

CodePudding user response:

grades = {'terri': [55,90,10], 'kerry': [88,66,77], 'sherry': [70, 90,10], 'jerry': [90, 60, 90], 'hari': [0, 100, 97]}

weights = [20,40,40]

di = {}

for e in grades:
    
    for i in range(len(weights)):
        if e not in di:
            di[e] = grades[e][i] * weights[i]/100
        else:
            di[e]  = grades[e][i] * weights[i]/100

print(di)

Out:

{'terri': 51.0, 'kerry': 74.8, 'sherry': 54.0, 'jerry': 78.0, 'hari': 78.8}

CodePudding user response:

You can use zip and sum.

def final_grade(gr,wghts):
    for k,v in gr.items():
        gr[k] = sum((a*b)/100 for a,b in zip(wghts, v))
    return gr

Output:

>>> grades = {'terri': [55,90,10], 'kerry': [88,66,77], 'sherry': [70, 90,10], 'jerry': [90, 60, 90], 'hari': [0, 100, 97]}
>>> weights = [20,40,40]
>>> final_grade(grades,weights)
{'terri': 51.0, 'kerry': 74.8, 'sherry': 54.0, 'jerry': 78.0, 'hari': 78.8}
  • Related