python数据结构学习笔记-2016-10-05-04-抽象数据类型(四)

        1.5 应用:学生记录

         提取学生信息,产生相应的报告。

         对于每一个学生,有五部分信息

  1. ID,以整数表示;
  2. 姓名,以字符串表示;
  3. 年级,以整数代号表示;
  4. GPA,以浮点数表示。         
         但是我们并不知道,这些学生的信息是怎么储存的,它们可能储存在纯文本文件中,在二进制文件中,甚至是在数据库中。

        1.5.1 设计解决方法
         无论学生信息是怎么储存的,从外部提取信息都分为以下3个步骤:
  1. 建立连接;
  2. 提取每一条记录;
  3. 关闭连接。
         我们定义学生文件读取器ADT,来表示对学生信息的提取。注意读取器(Reader)是是一个用于从外部读取输入数据的对象,而写入器(writer)是一个用于向外部输出数据的对象。
         学生文件读取器ADT包含如下方法:
  • StudentFileReader(filename):创建实例,用于从给定的文件名的文件中读取数据;
  • open():与输入源建立连接,准备提取学生记录;
  • close():关闭与输入源的连接,若连接已关闭,则引发异常;
  • fetchRecord():从输入源中提取下一行学生记录,并返回包含这一数据的储存对象的引用,若连接已关闭,则引发异常;
  • fetchAll():从输入源提取所有学生信息,以列表形式返回。
         创建报告
         如前面所述,我们可以先不管学生文件读取器ADT如何实现,先使用这一ADT来生成相应报告。
#-*-coding: utf-8-*-

# 从外部来源提取数据,生成学生报告

from studentfile import StudentFileReader

# 要打开的文件名
FILE_NAME = "students.txt"

# 打印学生报告
def printReport(theList):
    # 
    classNames = (None, "Freshman", "Sophomore", "Junior", "Senior")

    # 打印头部
    print "LIST OF STUDENTS".center(50)
    print ""
    print "%-5s %-25s %-10s %-4s" % ('ID', 'NAME', 'CLASS', 'GPA')
    print "%5s %25s %10s %4s" % ('-' * 5, '-' * 25, '-' * 10, '-' * 4)

    # 打印主体部分
    for record in theList:
        print "%5d %-25s %-10s %4.2f" % (record.idNum, record.lastName + ', ' + record.firstName, classNames[record.classCode], record.gpa)

    # 增加页脚
    print "-" * 50
    print "Number of students:", len(theList)

def main():
    # 从给定的文件中提取出学生记录
    reader = StudentFileReader(FILE_NAME)
    reader.open()
    studentList = reader.fetchAll()
    reader.close()

    # 按照ID排列,使用lambda函数(返回学生的ID)。
    studentList.sort(key = lambda rec: rec.idNum)
 
    # 打印学生报告
    printReport(studentList)

if __name__ == "__main__":
    main()

        储存类(Storage Class)
        当每一条学生记录从输入源中读入后,会被暂时储存在一个储存对象中。这个储存对象可以是列表或元组。在这里,我们使用类来实现这一目的,这被称为储存类(Storage class)。储存类中,只有构造器方法,即__init__,而没有其他方法。
        储存类应在同一模块定义(在这里是studentfile)。储存类有时可能被设置为模块私有,无法从外部调用,只供模块内使用。这种储存类以单下划线开头。
        在这里,在前述代码中,也是用了储存类(猜测可能是由于studentList中存储的student就是储存类的实例的缘故)。(说实话,这里不是很明白,看来还得在复习类的私有属性)
        
        1.5.2 ADT的实现
        假设输入源是纯文本文件,即txt格式,每一行是一个学生的一条记录,如ID、姓、名、年级或者GPA等。
#-*-coding: utf-8-*-

# 实现“学生文件读取器”这一抽象数据类型

class StudentFileReader(object):
    # 创建新的学生读取器实例
    def __init__(self, inputSrc):
        self._inputSrc = inputSrc # 文件名
        self._inputFile = None

    # 创建输入文件的连接
    def open(self):
        self._inputFile = open(self._inputSrc, 'r') # 本质是文件对象
  
    # 关闭输入文件的连接
    def close(self):
        self._inputFile.close()
        self._inputFile = None

    # 提取所有学生记录,并储存到一个列表中
    def fetchAll(self):
        theRecords = list()
        student = self.fetchRecord()
        while student != None:
            theRecords.append(student)
            student = self.fetchRecord()
        return theRecords

    # 从输入文件中提取下一个学生记录
    def fetchRecord(self):
        # 读取第一行记录
        line = self._inputFile.readline()
        if line == '':
            return None

        # 如果有记录,则创建储存对象
        student = StudentRecord()
        student.idNum = int(line)
        student.firstName = self._inputFile.readline().rstrip()
        student.lastName = self._inputFile.readline().rstrip()
        student.classCode = int(self._inputFile.readline())
        student.gpa = float(self._inputFile.readline())
        return student

# 用于储存学生记录的储存类
class StudentRecord(object):
    def __init__(self):
        self.idNum = 0
        self.firstName = None
        self.lastName = None
        self.classCode = 0
        self.gpa = 0.0




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值