This is one list
[74.0, 96.0, 72.0, 88.0, ['71', '80', '83', '77', '90', '88', '95', '71', '76', '94'], 80.0, 74.0, 98.0, 77.0]
74 is calculated with the weight .1, 96 with the weight .1, 72 with the weight .15, 88 with the weight .05, the average of (71,80,83,77,90,88,95,71,76,94) calculated with the weight .3, 80 calculated with the weight .08, 74 with the weight .08, 98 with .09 and lastly 77 with .05. Each score should be multiplied by appropriate weight.
Here is the function
def weighted_total_score(student_scores):
return((int(student_scores[0])*.1)+(int(student_scores[1])*.1)+(int(student_scores[2])*.15)+(int(student_scores[3])*.05)+(int(student_scores[4][0])*.3)+(int(student_scores[5])*.08)+(int(student_scores[5])*.08)+(int(student_scores[5])*.09)+(int(student_scores[8])*.05))
The expected value should be 82.94 but i am getting 78.48
You are slicing the outer list:
student_scores[4:5][0]
Slicing produces a new list, in this case with one element, an the [0]
selects that nested list:
>>> student_scores = [74.0, 96.0, 72.0, 88.0, ['71', '80', '83', '77', '90', '88', '95', '71', '76', '94'], 80.0, 74.0, 98.0, 77.0]
>>> student_scores[4:5]
[['71', '80', '83', '77', '90', '88', '95', '71', '76', '94']]
>>> student_scores[4:5][0]
['71', '80', '83', '77', '90', '88', '95', '71', '76', '94']
Perhaps you want to use student_scores[4][0]
(no slicing, just the 4th element) instead? That'd produce '71'
:
>>> student_scores[4][0]
'71'
You are also skipping student_scores[5]
, and will get an IndexError
for student_scores[9]
, which doesn't exist.
You probably want to avoid typing all those direct references; specify your weights as a sequence and use zip()
with a generator expression and sum()
to calculate the weighted sum:
def weighted_total_score(student_scores):
weights = .1, .1, .15, .05, .3, .08, .08, .09, .05
return sum(int(s[0] if isinstance(s, list) else s) * w
for s, w in zip(student_scores, weights))
This uses isinstance(s, list)
to detect the one list object and extract the first value from that.
If you need the average of the the nested list, calculate that on the spot:
def average(string_scores):
return sum(map(int, string_scores), 0.0) / len(string_scores)
def weighted_total_score(student_scores):
weights = .1, .1, .15, .05, .3, .08, .08, .09, .05
return sum(int(average(s[0]) if isinstance(s, list) else s) * w
for s, w in zip(student_scores, weights))
The average()
function here converts each string in the list to an integer, then sums those integers and divides the result by the length of the list. The sum()
is started with a floating point 0.0 to force the total to be a float, this makes sure the division is also producing a float, this only matters on Python 2.