购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.8 上机实践演练
——成绩单统计小帮手

又到了实践演练的时候了,主题是制作成绩单统计程序,输入10位学生的姓名以及数学、英语和语文三科的成绩,计算总分、平均分并根据平均分判断属于甲、乙、丙、丁哪一个等级。

3.8.1 范例程序说明

这次学生的成绩不使用input()函数一个个输入了,太费时,笔者事先建立了scores.csv文件,文件里包含10位学生的姓名以及数学、英语和语文三科的成绩,3.8.2小节将会介绍如何读取CSV文件。

此次演练的题目要求如下:

(1)读入CSV文件,文件名为scores.csv。

(2)计算总分、平均分以及等级(甲、乙、丙、丁)。

甲:平均80~100分 乙:平均60~79分

丙:平均50~59分 丁:平均50分以下

(3)输出学生姓名、总分、平均分(保留到小数点后1位)和等级。

输入说明

读入scores.csv文件。

输出结果参考图3-15。

流程图如图3-16所示。

图3-15

图3-16

3.8.2 读取CSV文件

CSV文件是常见的开放数据(Open Data)格式。所谓开放数据,是指可以被自由使用和散布的数据,虽然有些开放数据要求用户标示数据源与所有人,但大部分政府数据的开放平台可以免费获取数据,这些开放数据会以常见的开放格式在网络上公开。不同的应用程序如果想要交换数据,必须借助通用的数据格式,CSV格式就是其中的一种,全名为Comma-Separated Values,字段之间以逗号“,”分隔,与TXT文件一样都是纯文本文件,可以用记事本等文本编辑器来编辑。

CSV格式常用在电子表格以及数据库,比如Excel文件可以将数据导出成CSV格式,也可以导入CSV文件进行编辑。网络上许多开放数据(Open Data)通常也会给用户提供直接下载的CSV格式数据,当大家学会了CSV文件的处理之后,就可以将这些数据用于更多的分析和应用了。

本范例程序使用的scores.csv文件内容如图3-17所示。

图3-17

Python内建csv模块(module),能够非常轻松地处理CSV文件。csv模块是标准库模块,使用前必须先用import指令导入。下面来看csv模块的用法。

csv模块的用法

csv模块既可以读取CSV文件,也可以写入CSV文件,读取之前必须先打开CSV文件,再使用csv.reader方法读取CSV文件里的内容,代码如下:


import csv  #载入csv.py

with open("scores.csv", encoding="utf-8") as csvfile:  #打开文件指定为csvfile
    reader = csv.reader(csvfile)    #返回reader对象
    for row in reader:              #for循环逐行读取数据
        print(row)

上面程序的执行结果如图3-18所示。

图3-18

技巧

如果CSV文件与.py文件放在不同的文件夹中,就必须加上文件的完整路径。

open()指令会将CSV文件开启并返回文件对象,范例程序中将文件对象赋值给csvfile变量,默认文件使用unicode编码,如果文件使用不同的编码,就必须使用encoding参数设置编码。本范例程序所使用的CSV文件是无BOM的utf-8格式,所以encoding="utf-8"。

csv.reader()函数会读取CSV文件,转成reader对象再返回给调用者,reader对象是可以迭代(iterator)处理的字符串(string)列表(List)对象。上面的程序中使用reader变量来接收reader对象,再通过for循环逐行读取数据:


reader = csv.reader(csvfile)   #返回reader对象
for row in reader:               #for循环逐行读取数据放入row变量中

列表对象是Python的容器数据类型(Container Type),它是一串由逗号分隔的值,用中括号“[]”括起来:


['方小花', '87', '100', '98']

上面的列表对象共有4个元素,使用中括号“[]”搭配元素的下标(index,或称为索引)就能存取每一个元素,下标从0开始,从左到右分别是row[0]、row[1]……。例如要获取第4个元素的值,可以如下表示:


name = row[3]

技巧

使用with语句打开文件

在读取或写入文件之前,必须先使用open()函数将文件打开;当读取或写入完成时,必须使用close()函数将文件关闭,以确保数据已被正确读出或写入文件。如果在调用close()方法之前发生异常,那么close()方法将不会被调用,举例来说:


f = open("scores.csv")  #打开文件
csvfile = f.read()       #读取文件内容
1 / 0                      #error
f.close()                 #关闭文件

第3行程序语句犯了分母为0的错误,执行到此,程序就会停止执行,所以close()不会被调用,这样可能会有文件损坏或数据遗失的风险。

有两特种方法可以避免这样的问题:一种方法是加上try…except语句捕获错误,另一种方法是使用with语句。Python的with语句配有特殊的方法,文件被打开之后,如果程序发生异常,就会自动调用close()方法,如此一来,就能确保已打开的文件被正确、安全地关闭。

3.8.3 程序代码说明

这个范例程序使用的scores.csv文件包含10位学生的姓名及数学、英语和语文三科的成绩,我们需要将三科成绩加总、计算平均分,再以平均分来评比等级。

scores.csv文件第一行是标题,必须略过不处理,所以我们使用一个变量x来记录当前读取的行数,x的初始值为0,x必须大于0,if条件判断表达式才会为真,代码如下:


with open("scores.csv",encoding="utf-8") as csvfile:
    x = 0          #设置x初始值为0
    for row in csv.reader(csvfile):
            if x > 0:  #当x>0时,if判断表达式为真
        …
            x += 1     #相当于x=x+1

编写Python程序的时候不同区块记得缩排,上面的语句共有三个区块,即with…as区块、for循环区块、if区块,x=0的声明必须放在for循环外面,x+=1语句放在for循环内,这样每一次循环x才会累加,如图3-19所示。

图3-19

进入if区块之后要将三科成绩加总,由于csv.reader函数读入的都是字符串(string)格式,因此计算前必须先转换成int格式,再将加总结果赋值给变量scoreTotal:


scoreTotal = int(row[1]) + int(row[2]) + int(row[3])

接着计算平均值,题目要求平均值保留到小数点后1位:


average = round(scoreTotal / 3, 1)

使用平均分来评级,4个等级的分数区间如下。

·甲:平均80~100分。

·乙:平均60~79分。

·丙:平均50~59分。

·丁:平均50分以下。

平均80~100分就评定为“甲”等,80分也在这一区间,因此必须用“>=”(大于等于)关系运算符,如果只用average>80来判断,80分就不会落在这一区间。

平均60~79分就评定为“乙”等,这个判断需要两个条件,average>=60以及average<80,而且两个条件必须都符合,所以必须用and(与)来判断:


average > = 60 and average < 80

由于这两个条件是一个数值区间,因此可以写成下面的表达式,表示average的值必须在60~79以内。


60 <= average < 80

完整if...else语句如下:


if average >= 80 :
    grade = "甲"
elif 60 <= average < 80:
    grade = "乙"
elif 50 <= average < 60:
    grade = "丙"
else:
    grade = "丁"

最后只要将总分(scoreTotal)、平均分(average)以及等级(grade)用print语句输出就完成了,执行结果如图3-20所示。

图3-20

以下是完整的程序代码。

【范例程序:Review_scores.py】成绩单统计小帮手 v/dyukJprR9TSDaiLLyGYuqSwOjTl7JfGh4pFAxrRMeEUSJRUO22vf5AsA1iesHL


01        # -*- coding: utf-8 -*-
02        """
03        程序名称:成绩单统计小帮手
04        题目要求:
05        读入CSV文件
06        列出总和、平均分以及等级(甲、乙、丙、丁)
07        甲:平均80~100分
08        乙:平均60~79分
09        丙:平均50~59分
10        丁:平均50分以下
11        """
12        import csv
13
14        print("{0:<3}{1:<5}{2:<4}{3:<5}{4:<5}".format("", "姓名", "总分", "平均分", "等级"))
15        with open("scores.csv",encoding="utf-8") as csvfile:
16            x = 0
17            for row in csv.reader(csvfile):
18
19                if x > 0:
20                    scoreTotal = int(row[1]) + int(row[2]) + int(row[3])
21                    average = round(scoreTotal / 3, 1)
22
23                    if average >= 80 :
24                        grade = "甲"
25                    elif 60 <= average < 80:
26                        grade = "乙"
27                    elif 50 <= average < 60:
28                        grade = "丙"
29                    else:
30                        grade = "丁"
31
32                    print("{0:<3}{1:<5}{2:<5}{3:<6}{4:<5}".format(x, row[0], scoreTotal, average, grade))
33
34        x += 1

点击中间区域
呼出菜单
上一章
目录
下一章
×