所以我们的建议就是创建一个取输入等级的函数〜(N个M矩阵,包含给M个不同任务的N个学生的7个步骤的等级),并计算gradeFinal(矢量长度n包含每个N学生的最终成绩。)。
对于每个学生,最终成绩必须按以下方式计算:
如果只有一项作业(M = 1),则最终成绩等于该作业的成绩。
如果有两个或更多个分配(M> 1),则丢弃最低等级。最终成绩计算为M - 1最高等级的平均值 比例最接近等级(使用roundGrade函数)。
无论上述情况如何,如果学生在一项或多项作业中获得3级,则最终成绩必须为-3。
我已经在下面插入了我的roundGrade函数,但是当我尝试运行矩阵时,我接受了。 “TypeError: unsupported operand type(s) for /: 'NoneType' and 'int'
”。这意味着我可能完全误解了一些东西。
import numpy as np
def computeFinalGrades(grades):
if len(grades)==1:
gradesFinal = grades
elif len(grades)>=2:
trimmed = grades.remove(min(grades))
finalgrade = np.mean(trimmed)
gradesFinal = roundGrade(finalgrade)
elif grades[grades==-3]:
gradesFinal= -3
return gradesFinal
def roundGrade(grades):
grade_groups = [-3,0,2,4,7,10,12]
gradesRounded = [min(grade_groups,key=lambda x:abs(grade-x)) for grade in grades]
return gradesRounded
感谢您的帮助,欢迎向我展示更聪明的方法。
答案 0 :(得分:2)
这是一个直接在NxM
2d数组上工作的解决方案,而不是单独在每个矢量上工作,因此我假设所有学生的M都相同,并且缺失值(赋值)设置为{{ 1}}。 nan
也可以只是1d,这意味着每个学生只有1个作业。
G
答案 1 :(得分:1)
grades.remove(min(grades))
不会返回任何内容。因此trimmed
是None
。此外,您的roundGrade
函数是错误的,因为您正在将数字传递给roundGrade,并且正在尝试在gradesRounded = [min(grade_groups,key=lambda x:abs(grade-x)) for grade in grades]
中进行迭代。
以下代码必须为您提供帮助。
def computeFinalGrade(g_vector):
if -3 in g_vector: # Irrespective of the length of the g_vector
return -3
if len(g_vector) == 1:
return g_vector[0]
g_vector.remove(min(g_vector))
return roundGrade(sum(g_vector)/float(len(g_vector)))
def roundGrade(meanGrade):
gradeGroups = [-3,0,2,4,7,10,12]
return min(gradeGroups,key=lambda x:abs(meanGrade-x))
gradesFinal = []
grades = [
[1, 2, 3, 4],
[1, -3, 2, 4],
[5],
[9, 6, 2, 1]
]
for grade_vector in grades: # grades is a N*M matrix [[1, 2, 3 ... M], [1, 2, 3 ... M], ... N times]
gradesFinal.append(computeFinalGrade(grade_vector))
# >>> gradesFinal
# [2, -3, 5, 7]
答案 2 :(得分:1)
原始代码中大约有5个区域需要更改:缩进,list.remove
,if
/ elif
顺序,检查值是否存在的方式列表和roundGrade()
函数中的列表传递。
<强> 1。压痕强>
首先,你的缩进是不正确的。 python解释器考虑了缩进,因此非常重要。在每个if语句之后,您应该缩进该特定条件的代码块。除此之外,您还应该确保if和elifs处于相同的缩进级别。所以看起来应该是这样的。
import numpy as np
def computeFinalGrades(grades):
if len(grades)==1:
gradesFinal = grades
elif len(grades)>=2:
trimmed = grades.remove(min(grades))
finalgrade = np.mean(trimmed)
gradesFinal = roundGrade(finalgrade)
elif grades[grades==-3]:
gradesFinal= -3
return gradesFinal
def roundGrade(grades):
grade_groups = [-3,0,2,4,7,10,12]
gradesRounded = [min(grade_groups,key=lambda x:abs(grade-x)) for grade in grades]
return gradesRounded
<强> 2。 list.remove返回无
其次,假设您将列表传递给computeFinalGrades,trimmed = grades.remove(min(grades))
中的grade.remove会修改成绩列表并返回None
。因此,当你调用函数roundGrade时,你会得到NoneType错误。
第3。 if / elif块的顺序
第三,if块的流程是错误的。考虑将数组[1,2,3,4,5,-3]传递给computeFinalGrades([1,2,3,4,5,-3])
的情况,然后if语句if len(grades)==1
将返回True并且评估将在那里停止。相反,您应该将grades[grades==-3]
移动到顶部作为要评估的第一个语句,因为一旦此语句为真,则应始终返回-3。
<强> 4。检查列表中的值
第四,grades[grades==-3]
首先评估变量等级是否指向-3,而-3又返回false,因为等级始终是列表而不是整数-3。此时,您将grades[False]
等同地视为grades[0]
,因此您始终获得第一个结果。相反,pythonic方式是使用in运算符。 I.E. elif -3 in grades:
<强> 5。 roundGrade尝试两次迭代非迭代次数
第五,gradesFinal = roundGrade(finalgrade)
不起作用,因为finalgrade = np.mean(trimmed)
是一个数字。但是你在这个单个数字上调用roundGrade然后你在函数for grade in grades
内迭代这个单个数字roundGrade
。尝试min(grade_groups,key=lambda x:abs(grade-x))
时会发生同样的错误。这是因为您在单个值上调用min。如果你想最小化这个配对,一个更好的方法是gradesRounded = [(grade,lambda x:abs(mean_grade-x)) for grade in grade_groups]
。因此你应该知道你何时传入一个列表或变量。
我已经编辑了roundGrade以获取单个值,然后迭代您的成绩分组以创建绝对值差异的元组列表,然后是成绩分组中的成绩。然后我按升序对它进行排序,然后简单地返回第一个元组中的第二个值,这是你在成绩表中的等级。请注意,如果mean_grade恰好位于grade_groups中的两个相邻值之间,则这样做的缺点是始终返回grade_groups中的较低等级。
总而言之,这样做的一种方法是:
import numpy as np
def computeFinalGrades(grades):
if -3 in grades:
print grades
gradesFinal= -3
elif len(grades)>=2:
grades.remove(min(grades))
finalgrade = np.mean(grades)
gradesFinal = roundGrade(finalgrade)
elif len(grades)==1:
gradesFinal = grades
return gradesFinal
def roundGrade(mean_grade):
grade_groups = [-3,0,2,4,7,10,12]
gradesRounded = [(abs(grade-mean_grade),grade)for grade in grade_groups]
gradesRounded.sort()
return gradesRounded[0][1]