Sorting alphabet in terms of numbers

前端 未结 2 1337
死守一世寂寞
死守一世寂寞 2021-01-15 12:58
def make_gradebook():
    return []

def make_module_info(module, grade):
    module_info = (module,grade)
    return module_info

def get_module(module_info):
    r         


        
相关标签:
2条回答
  • 2021-01-15 13:13

    Here's an OO rewrite:

    class Module:
        def __init__(self, name):
            self.name = name
    
        @property
        def level(self):
            for ch in self.name:
                if ch.isdigit():
                    return int(ch)
    
    class Grade:
        grade_marks = {
            "A+": 90,
            "A-": 80,
            "A":  75,
            "B+": 70,
            "B-": 65,
            "B":  60,
            "C+": 55,
            "C-": 50,
            "C":  46
        }
    
        def __init__(self, grade):
            self.grade = grade
    
        @property
        def mark(self):
            return Grade.grade_marks[self.grade]
    
    class ModuleGrade:
        def __init__(self, module, grade):
            self.module = module if isinstance(module, Module) else Module(module)
            self.grade  = grade  if isinstance(grade,  Grade ) else Grade(grade)
    
        def __str__(self):
            return "{}: {}".format(self.module.name, self.grade.grade)
    
    class StudentGrades:
        sortkeys = {
            "module": lambda mg: mg.module.name,
            "level":  lambda mg: mg.module.level,
            "grade":  lambda mg: -mg.grade.mark    # Note: the -ve makes it descending order
        }
    
        def __init__(self, name, module_grades = None):
            self.name = name
            if module_grades is None:
                self.module_grades = []
            else:
                self.module_grades = [mg if isinstance(mg, ModuleGrade) else ModuleGrade(*mg) for mg in module_grades]
    
        def add_grade(self, *args):
            if len(args) == 1:
                mg = args[0]
                if isinstance(mg, ModuleGrade):
                    self.module_grades.append(mg)
                else:
                    self.module_grades.append(ModuleGrade(*mg))
            elif len(args) == 2:
                self.module_grades.append(ModuleGrade(*args))
            else:
                raise ValueError("Bad arguments to StudentGrades.add_grade")
    
        def sort(self, key, reverse=False):
            key = StudentGrades.sortkeys.get(key, key)
            self.module_grades.sort(key=key, reverse=reverse)
    
        def __str__(self):
            return "\n".join([self.name] + ["  {}".format(mg) for mg in self.module_grades])
    

    And here's how you use it:

    nf = StudentGrades("Norman Foster", [("CS1010S", "A+"), ("CS2020", "A")])
    nf.add_grade("MA1101R", "C")
    nf.add_grade("SSA1207", "B+")
    nf.add_grade("CS4247", "A+")
    nf.add_grade("EA5001", "B")
    
    print(nf)    # original insertion order
    
    nf.sort("module")
    print(nf)    # alphabetical by module name
    
    nf.sort("level", reverse=True)
    print(nf)    # in descending order by level
    
    nf.sort("grade")
    print(nf)    # descending order by grade
    
    0 讨论(0)
  • 2021-01-15 13:33

    What if you, instead of having multiple if/elif/else checks, define dictionaries grade->value and sign-value. Then, in the key function grade_to_numeric_marks just sum up base points per grade and points per sign (+/- or empty).

    For example (you may need to tweak values per grade/sign a bit):

    points = {'A': 80, 'B': 65}
    signs = {'+': 10, '-': -5}
    
    def grade_to_numeric_marks(item):
        grade = item[1]
        return points.get(grade[0], 50) + signs.get(grade[1:], 0)
    
    def sort_by_grade(gradebook):
        return sorted(gradebook, key=lambda x: grade_to_numeric_marks(x), reverse=True)
    
    grades = [('CS1010S', 'A+'), ('MA1101R', 'C'), ('SSA1207', 'B+'), ('CS2020', 'A')]
    print sort_by_grade(grades)
    

    prints:

    [('CS1010S', 'A+'), ('CS2020', 'A'), ('SSA1207', 'B+'), ('MA1101R', 'C')]
    

    Or, as @clutton mentioned in the comments, define just one dictionary with a mapping grade to points:

    {'A+': 95, 'A': 90 ... }
    

    Then, you can simplify the sorting:

    points = {'A+': 95, 'A': 90, 'B+': 70, 'B': 65, 'C+': 55, 'C': 50}  # need to define all of the possible grades
    
    grades = [('CS1010S', 'A+'), ('MA1101R', 'C'), ('SSA1207', 'B+'), ('CS2020', 'A')]
    print sorted(grades, key=lambda x: points.get(x[1]), reverse=True) 
    
    0 讨论(0)
提交回复
热议问题