简体   繁体   English

在Python中获取函数的平均值

[英]Getting an average in a function in Python

I am trying to learn Python and I am stuck. 我正在尝试学习Python,但被困住了。 Everything went fine until the last function which is the: 一切顺利,直到最后一个函数是:

def get_class_average(students): 

up to that point it all works fine, but there, at the last function, I can't figure out how to make it work. 到那时为止,一切正常,但是在最后一个函数中,我不知道如何使它起作用。 I am trying to get the averages for each student, then calculate the averages of those averages, in other words the "class average" So, I only would like to know the answer for the last function without changing any of the functions before the last one: 我试图获取每个学生的平均值,然后计算这些平均值的平均值,即“班级平均值”,因此,我只想知道最后一个函数的答案,而无需更改最后一个函数的任何函数一:

lloyd = {
    "name": "Lloyd",
    "homework": [90.0, 97.0, 75.0, 92.0],
    "quizzes": [88.0, 40.0, 94.0],
    "tests": [75.0, 90.0]
}
alice = {
    "name": "Alice",
    "homework": [100.0, 92.0, 98.0, 100.0],
    "quizzes": [82.0, 83.0, 91.0],
    "tests": [89.0, 97.0]
}
tyler = {
    "name": "Tyler",
    "homework": [0.0, 87.0, 75.0, 22.0],
    "quizzes": [0.0, 75.0, 78.0],
    "tests": [100.0, 100.0]
}



def average(numbers):
       total = sum(numbers)
       return float(total) / len(numbers)


def get_average(student):
       homework = average(student["homework"]) 
       quizzes = average(student["quizzes"]) 
       tests = average(student["tests"]) 
       return 0.1 * average(student["homework"]) + 0.3 * average(student["quizzes"])    +     0.6 * average(student["tests"])

def get_letter_grade(score):
       if score >= 90:
              return "A"
       elif score >= 80:
              return "B"         
       elif score >= 70:
              return "C"
       elif score >= 60:
              return "D"
       else:
              return "F"

def get_class_average(students):
       results = []
       for student in results:
              get_average(student)
              results.append(student)
              average(student)
              return results

students = [lloyd,alice,tyler]

print get_class_average(students)

I finally figured out the solution for this one. 我终于找到了解决方案。 So, I just want to post the corrected code here below for the last function, get_class_average(students). 因此,我只想在下面为最后一个函数get_class_average(students)发布更正后的代码。 Now it works: 现在可以正常工作:

def get_class_average(students):
       results = []
       for each in students:
              studentavg = float(get_average(each))
              results.append(studentavg)
       return average(results)

students = [lloyd,alice,tyler]

print get_class_average(students)

You're not really supposed to take an average of an average, just so you know. 您不应该真正地取平均数,只是知道。 I've corrected your code to get it to work correctly. 我已更正您的代码以使其正常工作。 Here it is: 这里是:

lloyd = {
    "name": "Lloyd",
    "homework": [90.0, 97.0, 75.0, 92.0],
    "quizzes": [88.0, 40.0, 94.0],
    "tests": [75.0, 90.0]
}
alice = {
    "name": "Alice",
    "homework": [100.0, 92.0, 98.0, 100.0],
    "quizzes": [82.0, 83.0, 91.0],
    "tests": [89.0, 97.0]
}
tyler = {
    "name": "Tyler",
    "homework": [0.0, 87.0, 75.0, 22.0],
    "quizzes": [0.0, 75.0, 78.0],
    "tests": [100.0, 100.0]
}



def average(numbers):
    total = sum(numbers)
    return float(total) / len(numbers)


def get_average(student):
       homework = average(student["homework"]) 
       quizzes = average(student["quizzes"]) 
       tests = average(student["tests"]) 
       return 0.1 * average(student["homework"]) \
            + 0.3 * average(student["quizzes"]) \
        + 0.6 * average(student["tests"])

def get_letter_grade(score):
       if score >= 90:
              return "A"
       elif score >= 80:
              return "B"         
       elif score >= 70:
              return "C"
       elif score >= 60:
              return "D"
       else:
              return "F"

def get_class_average(students):
    results = []
    for student in students:
        a = get_average(student)
        results.append(a)
    return average(results)

students = [lloyd,alice,tyler]

print get_class_average(students)    

Since you're new to python, I've taken the better part of an hour or two and rewritten your code to use various features of python, including docstrings, generators, list comprehensions, classes, as well as a map-reduce pattern, and also some new imports as well as how to unit-test a module. 由于您是python的新手,所以我们花了一两个小时的大部分时间,并重写了您的代码以使用python的各种功能,包括文档字符串,生成器,列表推导,类以及map-reduce模式,以及一些新的导入以及如何对模块进行单元测试。 I know you said to make minimal changes to your code, but I felt like it would be a discourtesy to you to simply solve your problem and move on. 我知道您说过要对代码进行最少的更改,但是我觉得只解决您的问题并继续前进对您来说是一种不鼓励。 I wanted to give you some snippets, using your example, that I built up and learned while learning python myself. 我想用您的示例给我一些片段,这些片段是我自己学习python时建立并学习的。

My example is MUCH longer and larger than yours, and in NO way am I suggesting you take any path beyond the shortest and simplest route, I am merely providing an example. 我的示例比您的示例更长,更大,并且我绝不建议您采用最短和最简单的路线之外的任何方法,我只是提供示例。 Don't be alarmed when you read this, just go through it and play with it and exploit it to the best of your ability. 当您阅读本文时,请不要惊慌,只需仔细阅读并使用它,并尽最大可能利用它即可。 You may have to keep it ruminating around in your head & filesystem for awhile before it begins to make sense. 在它变得有意义之前,您可能必须在头文件系统中保留一段时间。

If you want to know what all that if __name__ == "__main__": garbage is about, I suggest you save my code in a file called Student.py and call import Student from a python interpreter session. 如果您想知道if __name__ == "__main__":垃圾的全部内容,建议您将代码保存在一个名为Student.py的文件中,并从python解释器会话中调用import Student Notice what happens differently :). 注意发生了什么不同:)。 Also, in the same session, after calling import Student (from the same directory Student.py is saved in, of course) type help(Student) -- I guarantee it will be worth your time. 另外,在同一会话中,在调用import Student (当然,来自同一目录的Student.py被保存在其中)之后,键入help(Student) -我保证这将是您的宝贵时间。

from __future__ import division # to get rid of having to use float()
from math       import floor, log10 # for a helper function

class Student:
    """
    A class encapsulating elements of a student object. 
    Notable properties:
    homework_weight(0.1) --> a float multiplying student's homework average
    quiz_weight(0.3)     --> a float multiplying the student's quiz average
    test_weight(0.6)     --> a float multiplying the student's test average
    delimiter            --> a character used to separate fields in __str__
    """
    sig_figs        = 2
    homework_weight = 0.1
    quiz_weight     = 0.3
    test_weight     = 0.6
    delimiter       = '|'

    def __init__(self, name, homework, quizzes, tests):
        """
        Constructor for the Student object. Parameters are as follows:
        name      --> a string containing the student's name
        homework  --> a list of floats containing homework grades
        quizzes   --> a list of floats containing quiz grades
        tests     --> a list of floats containing test grades
        """
        self.__name     = name
        self.__homework = homework
        self.__quizzes  = quizzes
        self.__tests    = tests

    def get_name(self):
        """ Returns the current object's name """
        return self.__name

    def get_homeworks(self):
        """ yields a generator object for student's homework grades"""
        for i in self.__homework: yield i

    def get_quizzes(self):
        """ yields a generator object for student's quiz grades"""
        for i in self.__quizzes:  yield i

    def get_tests(self):
        """ yields a generator object for student's test grades"""
        for i in self.__tests:    yield i


    @classmethod
    def from_dict(cls, student_dict):
        """
        Creates a Student object from a dictionary. The dictionary must
        contain the following key-value pairs:
        'name'     : student_name
        'homework' : list of floats for homework grades
        'quizzes'  : list of floats for quiz grades
        'tests'    : list of floats for test grades
        """
        d = student_dict
        return cls(d['name'], d['homework'], d['quizzes'], d['tests'])

    def __str__(self):
        """
        Returns a string representation of the current
        object. The representation will be in the form
        of the fields separated by the default separator
        character (currently '|').
        """
        conv = lambda x, d: d.join(map(str, x))
        sep  = self.delimiter

        buff = ''
        buff +=      self.__name           + sep
        buff += conv(self.__homework, sep) + sep
        buff += conv(self.__quizzes,  sep) + sep
        buff += conv(self.__tests,    sep) 

        return buff

    def __repr__(self):
        """
        Returns a representation of the current object. In this
        case, we will return the same thing as __str__
        """
        return str(self)


    def to_dict(self):
        """
        Returns a dict representation of this object containing
        the keys ['name', 'homework', 'quizzes', 'tests'] where
        homework, quizzes, and tests are lists of floats.
        """
        obj = {}
        obj['name']     = self.__name
        obj['homework'] = self.__homework
        obj['quizzes']  = self.__quizzes
        obj['tests']    = self.__tests
        return obj



    def get_student_average(self, tuplify=False):
        """
        This method retrieves the student's class average according
        to predefined weighting rules. In this method, we average the
        list of scores together for the student's homework, quizzes,
        and tests, multiply them by their respective weights, and
        sum them together to obtain the final score. See implementation
        for more details.
        """
        hw = self.__homework
        qu = self.__quizzes
        ts = self.__tests

        if(0 not in map(len, [hw, qu, ts])): #division by zero, bla bla
            avg  = lambda l: sum(l)/len(l)
            avgs = map(avg,  [hw, qu, ts])
            hwa  = avgs[0] * Student.homework_weight
            qua  = avgs[1] * Student.quiz_weight
            tsa  = avgs[2] * Student.test_weight
            if tuplify is False:
                return sum([hwa, qua, tsa])
            else: 
                return (hwa, qua, tsa)

    def get_student_averages(self):
        """
        This method retrieves the student's class averages according
        to predefined weighting rules. In this method, we average the
        list of scores together for the student's homework, quizzes,
        and tests, multiply them by their respective weights, and return
        a set of them as a tuple where (homeworka, quiza, testa)
        See implementation for more details. 
        """
        return self.get_student_averages(tuplify=True)

    def get_student_letter_grade(self):
        """
        This method takes a student's letter score according to their
        average (computed by self.get_student_average()) and fetches
        the appropriate letter grade (A through F)
        """
        score = self.get_student_average()
        if   score >= 90:   return 'A'
        elif score >= 80:   return 'B'
        elif score >= 70:   return 'C'
        elif score >= 60:   return 'D'
        else:           return 'F'

    @staticmethod
    def __get_significant_average(grade_list):
        """ 
        Takes a list of grades and returns an average, does the average
        using proper significant figures according to a global variable
        grade_list -- a list of floats to average
        """
        sigfig = lambda x, n: round(x, -int(floor(log10(x))) + (n - 1))
        avg    = sigfig(sum(grade_list)/len(grade_list), num_figs)
        print '\t\t' + str(avg)
        return avg

    @staticmethod
    def get_class_set(student_list):
        """
        Generates a student object from a list of students
        and by assembling all the student's grades for each
        assignment and then using methods in the Student class
        to compute what we need to compute. 
        """
        # this is REALLY slick. What we're going to do is create a 
        # generator  generators of the student's homework and test
        # grades, but for the quizzes we will make regular list of
        # lists. 
        hwg = (x.get_homeworks()            for x in student_list)
        qwg = [[q for q in y.get_quizzes()] for y in student_list]
        twg = (z.get_tests()                for z in student_list)

        tl = lambda l: [x for x in l]
        # ^This is a lambda expression that converts a generator l
        # to a list (hence tl)



        # since each get_blabla() function returns a generator
        # and since each *wg variable is a generator of a generator
        # we will eventually get sublists of sublists of sublists
        # on and on and on and need to flatten them. Here are three
        # ways to do that. 
    # http://stackoverflow.com/questions/952914/making-a-flat-list-out-of-list-of-lists-in-python 
        hwl = [item for sublist in hwg for item in sublist]
        qwl = sum(qwg, []) 
        twl = reduce(lambda x,y: tl(x)+tl(y), twg)

        class_set = Student('class_whole_set', hwl, qwl, twl)
        return class_set




if __name__ == "__main__":

    lloyd = {
        "name": "Lloyd",
        "homework": [90.0, 97.0, 75.0, 92.0],
        "quizzes": [88.0, 40.0, 94.0],
        "tests": [75.0, 90.0]
    }

    alice = {
        "name": "Alice",
        "homework": [100.0, 92.0, 98.0, 100.0],
        "quizzes": [82.0, 83.0, 91.0],
        "tests": [89.0, 97.0]
    }

    tyler = {
        "name": "Tyler",
        "homework": [0.0, 87.0, 75.0, 22.0],
        "quizzes": [0.0, 75.0, 78.0],
        "tests": [100.0, 100.0]
    }

    slloyd  = Student.from_dict(lloyd)
    salice  = Student(alice['name'], alice['homework'], alice['quizzes'], alice['tests'])
    styler  = Student.from_dict(tyler)

#  YOU COULD DO THIS!
#   print 'lloyd dict'
#   print '\t' + str(sdlloyd)
#
#   print 'alice ctor'
#   print '\t' + str(slloyd)
#
#   print 'slloyd name: ' + slloyd.to_dict()['name']
#   print 'slloyd home: ' + str(map(str, slloyd.to_dict()['homework']))
#   print 'slloyd quiz: ' + str(map(str, slloyd.to_dict()['quizzes']))
#   print 'slloyd test: ' + str(map(str, slloyd.to_dict()['tests']))
#   print 'slloyd avg:  ' + str(slloyd.get_student_average())
#
#   conv = lambda x: str(map(str, x))
#   print 'salice name: ' + salice.get_name()
#   print 'salice home: ' + conv(salice.get_homeworks())
#   print 'salice quiz: ' + conv(salice.get_quizzes())
#   print 'salice test: ' + conv(salice.get_tests())
#   print 'salice avg:  ' + str(salice.get_student_average())
#


    """Unit test some object obj"""
    def unit_test(objname, obj):
        conv = lambda x: str(map(str, x))
        print str(objname) + ' name: ' + obj.get_name()
        print str(objname) + ' home: ' + conv(obj.get_homeworks())
        print str(objname) + ' quiz: ' + conv(obj.get_quizzes())
        print str(objname) + ' test: ' + conv(obj.get_tests())
        print str(objname) + ' avg : ' + str(obj.get_student_average())
        print str(objname) + ' let : ' + obj.get_student_letter_grade()

    sclss  = Student.get_class_set( [slloyd, salice, styler] )
    unit_test('sclss', sclss)
    unit_test('slloyd', slloyd)
    unit_test('salice', salice)
    unit_test('styler', styler)

Please let me know if this helps you and if you are confused by any aspect of this code. 请告诉我这是否对您有帮助,以及您是否对此代码的任何方面感到困惑。 Welcome to stack overflow :) 欢迎来到堆栈溢出:)

lloyd = { "name": "Lloyd", "homework": [90.0, 97.0, 75.0, 92.0], "quizzes": [88.0, 40.0, 94.0], "tests": [75.0, 90.0] } alice = { "name": "Alice", "homework": [100.0, 92.0, 98.0, 100.0], "quizzes": [82.0, 83.0, 91.0], "tests": [89.0, 97.0] } tyler = { "name": "Tyler", "homework": [0.0, 87.0, 75.0, 22.0], "quizzes": [0.0, 75.0, 78.0], "tests": [100.0, 100.0] }

Add your function below! def average(numbers): total = float(sum(numbers)) return total/len(numbers) def get_average(student): homework = average(student['homework']) * 0.1 quizzes = average(student['quizzes']) * 0.3 tests = average(student['tests']) * 0.6 return (homework + quizzes + tests) def get_letter_grade(score): if score > 90 or score == 90: return "A" elif score > 80 or score == 80 and score < 90: return "B" elif score > 70 or score == 70 and score < 80: return "C" elif score > 60 or score == 60 and score < 70: return "D" else: return "F" students = [lloyd,alice,tyler] def get_class_average(students): results = [] for student in students: print "student: %s, srednia %s" % (student['name'],get_average(student)) results.append(get_average(student)) print results print get_average(student) return average(results)

Add your function below! def average(numbers): total = float(sum(numbers)) return total/len(numbers) def get_average(student): homework = average(student['homework']) * 0.1 quizzes = average(student['quizzes']) * 0.3 tests = average(student['tests']) * 0.6 return (homework + quizzes + tests) def get_letter_grade(score): if score > 90 or score == 90: return "A" elif score > 80 or score == 80 and score < 90: return "B" elif score > 70 or score == 70 and score < 80: return "C" elif score > 60 or score == 60 and score < 70: return "D" else: return "F" students = [lloyd,alice,tyler] def get_class_average(students): results = [] for student in students: print "student: %s, srednia %s" % (student['name'],get_average(student)) results.append(get_average(student)) print results print get_average(student) return average(results)

Add your function below! def average(numbers): total = float(sum(numbers)) return total/len(numbers) def get_average(student): homework = average(student['homework']) * 0.1 quizzes = average(student['quizzes']) * 0.3 tests = average(student['tests']) * 0.6 return (homework + quizzes + tests) def get_letter_grade(score): if score > 90 or score == 90: return "A" elif score > 80 or score == 80 and score < 90: return "B" elif score > 70 or score == 70 and score < 80: return "C" elif score > 60 or score == 60 and score < 70: return "D" else: return "F" students = [lloyd,alice,tyler] def get_class_average(students): results = [] for student in students: print "student: %s, srednia %s" % (student['name'],get_average(student)) results.append(get_average(student)) print results print get_average(student) return average(results)

Add your function below! def average(numbers): total = float(sum(numbers)) return total/len(numbers) def get_average(student): homework = average(student['homework']) * 0.1 quizzes = average(student['quizzes']) * 0.3 tests = average(student['tests']) * 0.6 return (homework + quizzes + tests) def get_letter_grade(score): if score > 90 or score == 90: return "A" elif score > 80 or score == 80 and score < 90: return "B" elif score > 70 or score == 70 and score < 80: return "C" elif score > 60 or score == 60 and score < 70: return "D" else: return "F" students = [lloyd,alice,tyler] def get_class_average(students): results = [] for student in students: print "student: %s, srednia %s" % (student['name'],get_average(student)) results.append(get_average(student)) print results print get_average(student) return average(results)

Add your function below! def average(numbers): total = float(sum(numbers)) return total/len(numbers) def get_average(student): homework = average(student['homework']) * 0.1 quizzes = average(student['quizzes']) * 0.3 tests = average(student['tests']) * 0.6 return (homework + quizzes + tests) def get_letter_grade(score): if score > 90 or score == 90: return "A" elif score > 80 or score == 80 and score < 90: return "B" elif score > 70 or score == 70 and score < 80: return "C" elif score > 60 or score == 60 and score < 70: return "D" else: return "F" students = [lloyd,alice,tyler] def get_class_average(students): results = [] for student in students: print "student: %s, srednia %s" % (student['name'],get_average(student)) results.append(get_average(student)) print results print get_average(student) return average(results)

Add your function below! def average(numbers): total = float(sum(numbers)) return total/len(numbers) def get_average(student): homework = average(student['homework']) * 0.1 quizzes = average(student['quizzes']) * 0.3 tests = average(student['tests']) * 0.6 return (homework + quizzes + tests) def get_letter_grade(score): if score > 90 or score == 90: return "A" elif score > 80 or score == 80 and score < 90: return "B" elif score > 70 or score == 70 and score < 80: return "C" elif score > 60 or score == 60 and score < 70: return "D" else: return "F" students = [lloyd,alice,tyler] def get_class_average(students): results = [] for student in students: print "student: %s, srednia %s" % (student['name'],get_average(student)) results.append(get_average(student)) print results print get_average(student) return average(results)

print get_class_average(students)

This worked for me: 这为我工作:

lloyd = {
  "name": "Lloyd",
  "homework": [90.0, 97.0, 75.0, 92.0],
  "quizzes":  [88.0, 40.0, 94.0],
  "tests":    [75.0, 90.0]
}
alice = {
  "name": "Alice",
  "homework": [100.0, 92.0, 98.0, 100.0],
  "quizzes":  [82.0, 83.0, 91.0],
  "tests":    [89.0, 97.0]
}
tyler = {
  "name": "Tyler",
  "homework": [0.0, 87.0, 75.0, 22.0],
  "quizzes":  [0.0, 75.0, 78.0],
  "tests":    [100.0, 100.0]
}

# Add your function below!
def average(numbers):
  total = 0.0
  total = sum(numbers)
  total = float(total) / len(numbers)
  return total

def get_average(student):
  hweight = 0.1
  qweight = 0.3
  tweight = 0.6
  homework = average(student["homework"])
  quizzes  = average(student["quizzes"])
  tests    = average(student["tests"])
  total = (homework * hweight) + (quizzes * qweight) + (tests * tweight)
  return total

def get_letter_grade(score):
  if score >= 90:
    return 'A'
  elif score < 90 and score >= 80:
    return 'B'
  elif score < 80 and score >= 70:
    return 'C'
  elif score < 70 and score >= 60:
    return 'D'
  else:
    return 'F'

def get_class_average(class_list):
  results = []
  for student in class_list:
    running = get_average(student)
    results.append(running)
  return average(results)

students = [lloyd, alice, tyler]
print "The Average for the class is:\n"
print get_class_average(students)
print
print "Which corresponds to a letter grade of:\n"
print get_letter_grade(get_class_average(students))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM