2016-06-07 35 views
-3

这里是我的代码:使用类和对象来计算学生的GPA

class student: 
    def __init__(self): 
     self.totalSumOGrades = 0 
     self.numberOGrades = 0 

    def getAverageScore(self): 
     return (self.totalSumOGrades/self.numberOGrades) 

    def addGrade(self,grade): 
     self.totalSumOGrades = str(grade) 
     self.numberOGrades = self.numberOGrades + 1 
     return (self.totalSumOGrades) 


class GPA: 
    def __init__(self,grade): 
     self.grade = grade 
     self.score = 0 


    def gradesScore(self): 
     gradeLetter = self.grade[0] 
     gradeSign = ' ' 
     if (len(self.grade)) == 2: 
      gradeSign = self.grade[1] 

     if (gradeLetter == 'A'): 
      self.score = 4 
     elif (gradeLetter == 'B'): 
      self.score = 3 
     elif (gradeLetter == 'C'): 
      self.score = 2 
     elif (gradeLetter == 'D'): 
      self.score = 1 
     elif (gradeLetter == 'F'): 
      self.score = 0 

     if (gradeSign == '+'): 
      self.score += 0.3 
     elif (gradeSign == '-'): 
      self.score -= 0.3 


    def getScore(self): 
     self.gradesScore() 
     return self.score 

我需要在一张纸上两个类。我遇到的问题是正在为GPA采取的论点是“getScore”计算的。我需要它,所以班级学生的addGrade会添加一个评分,我可以让“getScore”来计算这些评分。我该如何解决?

+1

您是否使用纸质电脑:-)?我没有完成“在一张纸上需要两节课”的任务。在底部的其他散文,是这样的要求,如果一个学生已经有两个等级,并从这些积分得分,如果一个额外的三年级/结果被添加到他的“无论”,总分是积分现在重新计算了所有三个结果的输入?建议也可以为少数可能的有效成绩使用表格解析器,而不是使用if-elsing“眼睛”(也许可以尝试和比较)PEP8可以帮助您了解很多关于Python语言的知识。 – Dilettant

+0

...建议遵循PEP8将学生班重新命名为学生,最后但并非最不重要的是:什么是GPA(我不是美国美国人)作为班级,它可能会更好骆驼案件(这意味着什么) 。不要忘记:说明最重要的是:我们开始帮助我思考,因为你真的尝试并展示它。谢谢。 – Dilettant

+0

平均分... – Guy

回答

1

因此,我承诺答复/反馈版本,以帮助OP走过并挑选一些新问题 - 在这里(希望火车黑客有足够的高质量来展示一些概念并提供良好的开始创建基于此的真正解决方案):

#! /usr/bin/env python 
from __future__ import division, print_function 


class GradePointAverage(object): 
    """Implements a "Grade Point Average" (GPA) calculation. 
    Note: It keeps all grades to offer an incremental update path. 
    """ 

    FILL_CHAR_ZERO_ADJUST = '.' 
    VALID_LETTERS = ('A', 'B', 'C', 'D', 'E', 'F') 
    VALID_ADJUSTMENTS = ('+', FILL_CHAR_ZERO_ADJUST, '-') 

    BASE_SCORE_MAP = dict(zip(reversed(VALID_LETTERS), (0., 1., 2., 3., 4.))) 
    ADJ_SCORE_MAP = dict(zip(VALID_ADJUSTMENTS, (0.3, 0., -0.3))) 

    def __init__(self, grades=None): 
     """Inintializes the _grades, a sequence of canonical grade 
     values e.g. ['A+', 'B-'] where any grade recieved is 
     mapped to uppercase letter plus either ''|'+'|'-' or 
     and exception ValueError is thrown. 
     """ 
     if grades is None: 
      self._grades = list() 
     else: 
      self._grades = [self.canonicalize_grade(g) for g in grades] 

    def __repr__(self): 
     """Helper to (de)serialize and put more in print et al.""" 
     return ('GradePointAverage(%s)' % (str(self._grades))) 

    def add_grades(self, grades): 
     """Add a new result/grade to data.""" 
     for g in grades: 
      self.add_grade(g) 

    def add_grade(self, grade): 
     """Add a new result/grade to data.""" 
     self._grades.append(self.canonicalize_grade(grade)) 

    def count_grades(self): 
     """Return the count of grades, the scoring is based upon.""" 
     return len(self._grades) 

    def grades(self): 
     """Return the grades as list, the scoring is based upon.""" 
     return self._grades 

    def canonicalize_grade(self, grade): 
     """Ensure grade is valid, ensure uppercase letter plus either 
     ''|'+'|'-' on output. If invalid, let raise or throw ValueError. """ 
     c_grade = grade.strip().upper() # May raise 
     if 1 <= len(c_grade) <= 2: 
      if len(c_grade) < 2: 
       c_grade += self.FILL_CHAR_ZERO_ADJUST 
     else: 
      raise ValueError("Invalid grade length") 

     if c_grade[0] not in self.VALID_LETTERS: 
      raise ValueError("Invalid main grade") 

     if c_grade[1] not in self.VALID_ADJUSTMENTS: 
      raise ValueError("Invalid grade adjustment") 

     return c_grade 

    def _score(self, canonical_grade): 
     """Calculate score from canonical grade.""" 
     base, adj = canonical_grade[0], canonical_grade[1] 
     return self.BASE_SCORE_MAP[base] + self.ADJ_SCORE_MAP[adj] 

    def average_score(self): 
     """Calculate average score.""" 
     if not self.count_grades(): 
      return None 
     # implicit else: 
     score_sum = sum(self._score(c_g) for c_g in self._grades) 
     return score_sum/float(self.count_grades()) 

    def median_score(self): 
     """Calculate median score.""" 
     if not self.count_grades(): 
      return None 
     # implicit else: 
     middle_index = self.count_grades() // 2 
     return sorted([self._score(c_g) for c_g in self._grades])[middle_index] 

    def best_score(self): 
     """retrieve highest score.""" 
     return NotImplemented 


class Student: 
    """Models student with updateable Grade Point Average.""" 
    def __init__(self, grades): 
     self._gPA = GradePointAverage(grades) 
     self.number_of_grades = self._gPA.count_grades() 

    def __repr__(self): 
     """Helper to (de)serialize and put more in print et al.""" 
     return ('Student(%s)' % (str(self._gPA.grades()))) 

    # Delegated/proxy methods 
    def average_score(self): 
     return self._gPA.average_score() 

    def count_grades(self): 
     return self._gPA.count_grades() 

    def grades(self): 
     return self._gPA.grades() 

    def median_score(self): 
     return self._gPA.median_score() 

    def best_score(self): 
     return self._gPA.best_score() 

    def add_grade(self, grade): 
     return self._gPA.add_grade(grade) 

    def add_grades(self, grades): 
     return self._gPA.add_grades(grades) 


def main(): 
    """Drive some tests on "scored" Students.""" 

    print('Positive test cases:') 
    print('... service class under test:') 
    gPA = GradePointAverage(['a+', 'c-']) 
    print(gPA) 

    print('... main class under test:') 
    student = Student(['F+']) 
    print(student) 
    print(student.count_grades()) 
    print(student.average_score()) 
    print(student.median_score()) 
    a_grade = 'E-' 
    print("Added %s" % (a_grade,)) 
    student.add_grade('E-') 
    print(student.count_grades()) 
    print(student.average_score()) 
    print(student.median_score()) 

    some_grades = ['E', 'b+', 'b-', 'c+', 'D', 'D'] 
    print("Added %s" % (str(some_grades),)) 
    student.add_grades(some_grades) 
    print(student.count_grades()) 
    print(student.average_score()) 
    print(student.median_score()) 
    print(student.grades()) 

    print('Negative test cases:') 

    print(student.best_score()) 

    print('... too long:') 
    try: 
     _ = GradePointAverage(['aa+', 'no_impact']) 
    except ValueError as e: 
     print(e) 

    print('... wrong grade letter:') 
    try: 
     _ = GradePointAverage(['z', 'no_impact']) 
    except ValueError as e: 
     print(e) 

    print('... wrong adjustment:') 
    try: 
     _ = GradePointAverage(['A*', 'no_impact']) 
    except ValueError as e: 
     print(e) 

    print('... wrong grade "type" we did let it just bubble:') 
    try: 
     _ = GradePointAverage([42, 'no_impact']) 
    except AttributeError as e: 
     print(e) 

if __name__ == '__main__': 
    main() 

所以学生实例始终代表等级和分数相关任务的GradePointsAverage类的成员实例。这会将学生课程移近一个多余的层次(按原样),但实际上您现在可以将识别正在建模的学生的个人信息填入Student实例。

当我在我的机器上面的代码运行(与蟒蛇V2解释):

Positive test cases: 
... service class under test: 
GradePointAverage(['A+', 'C-']) 
... main class under test: 
Student(['F+']) 
1 
0.3 
0.3 
Added E- 
2 
0.5 
0.7 
Added ['E', 'b+', 'b-', 'c+', 'D', 'D'] 
8 
2.1625 
2.0 
['F+', 'E-', 'E.', 'B+', 'B-', 'C+', 'D.', 'D.'] 
Negative test cases: 
NotImplemented 
... too long: 
Invalid grade length 
... wrong grade letter: 
Invalid main grade 
... wrong adjustment: 
Invalid grade adjustment 
... wrong grade "type" we did let it just bubble: 
'int' object has no attribute 'strip' 
[Finished in 0.0s] 

一个IMO应不超过工程师玩具的问题,但是这一次可能会提供有趣的支线任务,如存储哈希/带有学生实例的匿名ID。这将匹配更多的现实生活,其中可能允许识别个人或可能具有披露个人隐私细节的数据的存储通常被分成散布的腌制散列以附着到需要反参照的所有类别实例,但只需在一个特别安全的地方将映射保留回实名,日期和地点等。

也可以引入(除了增加的中位数)还有来自任何学生实例的最小/最大即最差/最佳得分或等级“信息”,甚至可以对得分进行简单线性回归以找到一些“趋势”。

另一类扩展将尝试“覆盖”测试中的所有路径。

的另一种方法,以“打击的事情了”可能是,一个更elgant迷你语言内部映射,其中“收集阶段”(从等级到数值的映射)完全转化为整数如。通过缩放所有十倍因而具有无损算术,并且价格考虑“报告”预期的回归变换的实际分数(即,样本4.3而不是43),而且还具有容易地重新分级任何分数和记忆只执行一个最后的“舍入”步骤。

还要注意有用的pep8工具或例如python3 -m pep8 so_get_gpa_for_student_edited.py不会给出错误或警告。

另一个暗示,经常在开发过程中,当扩展对象/添加fetaures时,名称慢慢地偏离界限。直到现在(对我来说)GradePointAverage是一个匹配的类/类型名称,因为我经常接受一个中位数与算术平均数作为有用的双胞胎信息。但如果我已经进入了说。一种趋势方法,那么它将是进一步分离功能或重命名类的好时机。

而且决定一个consisten错误的策略有很大帮助。在上面的代码中,我们主要说明问题类,但是例如。不要报告究竟是什么导致了问题。在很多情况下,这是可以的,甚至是想要的,但在其他情况下,可能会在响应中添加一些细节。

最后一个细节:就是让你知道如何首先定义所有的接口方法,然后在增量测试中逐一实现这些方法。我还添加了其中一个技巧来指示somethig计划时,但尚未实现。在这里,我只需返回NotImplemented best_score方法。我们也可以raise NotImplementedError("Method_best_score")代替,但因为这会导致:

File "/Users/sthagen/tmp/so_get_gpa_for_student_edited.py", line 184, in <module> 
    main() 
    File "/Users/sthagen/tmp/so_get_gpa_for_student_edited.py", line 157, in main 
    print(student.best_score()) 
    File "/Users/sthagen/tmp/so_get_gpa_for_student_edited.py", line 117, in best_score 
    return self._gPA.best_score() 
    File "/Users/sthagen/tmp/so_get_gpa_for_student_edited.py", line 90, in best_score 
    raise NotImplementedError("Method best_score") 
NotImplementedError: Method best_score 

我经常活跃在创建过程中,从“零”的更安静return NotImplemented选项,并在(预)生产时,一个尚未实现的方法的调用或功能更可能是在使用中的错误,我切换到例外,你的里程可能会有所不同...

请随时发表评论(如果我误读任务),或者如果我忘记评论你所发生的变化当比较你的代码smaple。