繁体   English   中英

Python在读取文件时创建对象

[英]Python creating an Object while reading file

我编写了一个简单的Python脚本来确定是否报告了所有学生的成绩。 该脚本首先循环浏览,并将学生添加到有关年级状态的数组中。 然后,我再次遍历该文件,以确定每个学生的成绩是否合格。我最终得到三个数组,其中包括“已报告所有成绩”,“已报告某些成绩”,“未报告任何成绩”的学生。 但是,我想通过更多的面向对象方法来解决这个问题。 我试图创建一个有效的类。 我坚持如何遍历并为每个学生创建一个对象,然后使用添加课程将每门课程推入对象。 我可以成为一名更好的程序员的任何帮助都是很棒的!

数据:

**id,fname,lname,course,grade,mode**
10001,Freddy,Freshman,Art-101,A,online
10001,Freddy,Freshman,Art-101,A,online
10002,Suize,Sophmore,Mat-102,C,inperson
10002,Suize,Sophmore,Bio-101, ,inperson
10002,Suize,Sophmore,Soc-201,D,online
10003,Jilly,Junior,mth-102, ,inperson
10003,Jilly,Junior,Bus-101, ,inperson
10003,Jilly,Junior,Che-204, ,inperson

工作代码:

fh = open('students.txt').readlines()
header = fh.pop(0)
gradereported = []
nogradereported = []
    for line in fh:
        students = line.split(',')
        ids = students[0]
        grade = students[4]
        if grade != "":
            gradereported.append(ids)
        else:   
            nogradereported.append(ids)
allgradesin =[]
nogradesin = []
somegradesin = []
for i in fh:
    students = line.split(',')
    ids = students[0]
    if ids in gradereported and ids not in nogradereported:
            if ids not in allgradesin:
                    allgradesin.append(ids)
    elif ids not in gradereported and ids in nogradereported:
            if ids not in nogradesin:
                    nogradesin.append(ids)
    elif ids in gradereportedand and ids in nogradereported:
            if ids not in somegradesin:
                    somegradesin.append(ids)

尝试上课:

class Student(object):
    def __init__(self, lname, fname, term, courses = []):
        self.studid = studid
        self.lname = lname
        self.fname = fname
        self.term = term
        self.courses = []

    def addcourse(self, course, grade, mode):
        self.course = course
        self.grade = grade
        self.mode = mode
        self.courses.append((self.course, self.grade, self.mode))

您可以按照@blade的建议执行此操作,方法是创建一个按学生ID索引的字典,然后为输入文件的每一行从字典中获取现有学生(如果存在)或创建一个新学生。 在代码中,这看起来像:

class Student(object):
    def __init__(self, student_id, lname, fname):
        self.studid = student_id
        self.lname = lname
        self.fname = fname
        self.courses = []

    def addcourse(self, course, grade, mode):
        self.courses.append((course, grade, mode))

students = {}

fh = open('students.txt').readlines()
header = fh.pop(0)

for line in fh:
    row = line.split(',')
    if len(row) < 6:
        continue

    student_id, fname, lname, course, grade, mode = [i.strip() for i in row]

    student = students.get(student_id, Student(student_id, lname, fname))
    student.addcourse(course, grade, mode)
    students[student_id] = student

需要注意的几件事。 首先,我修改了Student类的构造函数,删除了term参数,因为尚不清楚该term在输入文件中的指定位置。 此外,由于您不使用courses参数,因此我也删除了该参数。 (请注意,您可能不想使用[]作为默认参数。 在此处了解可变的默认参数 。)您也不需要在addcourse函数中为课程,成绩和模式创建实例变量,您可以可以直接将它们附加到数组。

我还添加了一个调用,以strip从输入文件中提取的每个项目,以清除每行末尾的换行符。

这个怎么样:

  1. 添加一个字典,其中id是键,Student对象是值
  2. 循环文件,如果密钥在字典中,请从字典中获取Student对象。 否则,创建一个新的Student对象。 然后将课程添加到Student对象。

除了@JCVanHanne的答案外,您还可以在班级中定义另一个函数来收集信息,无论学生是否拥有,全部或全部成绩都没有。

一种可能的方式(假设缺少的成绩由一个空字符串表示,而诸如A +或其他非空值的成绩也是可能的)可能是:

def gradeStatus(self):
    miss = [course[1] for course in self.courses].count("") # count empty grades
    if len(self.courses) == miss:
        print('No grades at all')
    elif miss in range(1, len(self.courses)):
        print('Some, but not all grades')
    elif miss == 0:
        print('All grades provided')
    else:
        print('Invalid Data')

您可能会使用状态码或其他方式(例如返回值以进行进一步处理)来处理信息,而不仅仅是打印它们。 以打印命令为例:

students['10003'].gradeStatus() # leads to: No grades at all

暂无
暂无

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

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