基于python的课堂助手
第一个python“项目”(哈哈哈哈),记录一下。
要求
现有一个文件 names.txt
,见附件,保存的是选修与某门课的学生姓名。我们现在要为任课老师创建一个课堂助手 LessonHelper
类,实现以下几个功能:
-
创建初始化函数,其中需要定义的变量请根据下面的要求决定。
-
创建方法
read_names()
,读取names.txt
中所有同学的姓名。 -
创建方法
split_groups()
, 参数为小组数量 x。要求:- 将学生随机分成 x 个小组,每个小组至少有一人,当 x 选择不合适时,要进行提示。
- 将分组后的学生姓名分别保存在文件
group_1.txt
,group_2.txt
, …,group_x.txt
中, - 在分组已存在的情况下调用
split_groups
方法,程序要能够进行提示,并让老师在下面的操作中选择一项继续进行:- 保留已存在的分组。
- 删除已存在的分组文件,并创建新的分组。(提示:os包中存在删除文件的方法)
-
创建方法
ask_one()
,参数为小组序号 n,表示从第 n 个小组中随机选择一名同学回答问题。 -
创建方法
test_some()
,参数为人数 m,表示随机选择 m 名同学参加测试。 -
创建方法
record()
,用record.txt
记录每个学生回答问题和参加测试的总次数,用来进行期末评分,要求:record.txt
中的内容格式应该如下(姓名后面[A, B]
中的A
表示回答问题的次数,B
表示参加测试的次数):... Christine [1, 2 Daisy [0, 1] Dana [2, 0] ...
- 记录可以累加:执行
record
方法时,如果本地已存在record.txt
文件,则需要加上record.txt
中已有的数据。 ask_one()
和test_some()
中可能需要添加代码来进行记录。
结果
代码
# 版本:L1.0 完成时间:2019.9.12 20:30
# 问题:
# 1.当输入非整数时产生错误
# 2.在进入某一项时,若不完成该项任务,无法退出
# 3.导入数据未完成
# 4.程序健壮性差,若跳过读取姓名进行分组,会卡死其中
# 5.字符串删除方法较为复杂
# 我们写的都是bug
import os
import random
import copy
# import tqdm
import time
import re
class LessonHelper:
names = []
sh_name = []
group = []
def __init__(self):
self.num = 0
self.group_flag = 0
self.dit = {}
self.group_num = 0
# 读取姓名
def read_name(self):
with open('names.txt', 'r+') as f:
while True:
line = f.readline()
if line == '':
break
self.names.append(line.rstrip("\n"))
self.num = len(self.names)
self.dit = {k: [0, 0] for k in self.names} # 生成字典
# self.dit = dict.fromkeys(self.names, [0, 0]) # 使用出错
return self.names
# 分组
def split_groups(self, g):
self.group_num = g
self.sh_name = copy.deepcopy(self.names)
random.shuffle(self.sh_name) # 对名字进行打乱
n1, n2 = divmod(self.num, g) # n1整除6 n2取余4
# 错误代码
# 原因:j从n1+1变成n1时,截取错误
# for i in range(g):
# if i < n2:
# j = n1 + 1
# else:
# j = n1
# self.group.append(self.sh_name[j * i: j * (i + 1)])
for i in range(g):
k = 0 # 初始化,实际没用
if i < n2:
j = n1 + 1
self.group.append(self.sh_name[j * i: j * (i + 1)])
k = j * (i + 1)
else:
j = n1
self.group.append(self.sh_name[k + j * (i - n2): k + j * (i - n2 + 1)])
# print(self.group)
for i in range(1, g + 1):
b = "group_" + str(i) + ".txt"
with open(b, "w+") as f:
f.seek(0, 0) # 位置移动到文件开头
for j in self.group[i - 1][:]:
f.write(j + "\n")
return self.group
# 抽n组的学生答题
def ask_one(self, n):
sel_one = random.choice(self.group[n - 1])
self.dit[sel_one][0] += 1
# print("被抽中的是第" + str(n) + "组的" + sel_one)
# print("输出抽后字典", self.dit)
return sel_one
# 抽m人测试
def test_some(self, m):
shu_name = copy.deepcopy(self.names)
random.shuffle(shu_name) # 对名字进行打乱
# print("测试的" + str(m) + "人为:", shu_name[:m])
for i in shu_name[:m]:
self.dit[i][1] += 1
# print("输出测试后字典", self.dit)
return shu_name[:m]
# 记录答题与测试
def record(self):
rec_data = []
with open('record.txt', 'a+') as f:
f.seek(0, 0) # 位置移动到文件开头
line = f.readline()
if line == '': # 没有记录文件
for i in self.dit.keys():
f.write(i + " [" + str(self.dit[i][0]) + ", " + str(self.dit[i][1]) + "]\n")
# print("空的")
else: # 有记录文件
f.seek(0, 0) # 位置移动到文件开头
# with open('record.txt', 'r+') as f:
while True:
line = f.readline()
if line == '':
break
rec_data.append(line.rstrip("\n"))
# print("record有东西", rec_data)
# print("dict", self.dit)
rec_dit = {}
for i in rec_data:
i = i.rstrip(']') # 否则会产生空串
b = re.split(r", | \[", i) # [怎么删???
b[1] = int(b[1])
b[2] = int(b[2])
rec_dit[b[0]] = [b[1], b[2]]
# print("b", b)
# print("rec_dit",rec_dit)
for i in rec_dit.keys():
rec_dit[i][0] += self.dit[i][0]
rec_dit[i][1] += self.dit[i][1]
# print("rec_dit+", rec_dit)
f.seek(0, 0) # 位置移动到文件开头
f.truncate()
for i in rec_dit.keys():
f.write(i + " [" + str(rec_dit[i][0]) + ", " + str(rec_dit[i][1]) + "]\n")
for i in self.dit.keys():
self.dit[i][0] = self.dit[i][1] = 0
def Init_Interface(self):
print("-----------------------------------------------------------")
print("---- History: ")
print("---- Author:Fan Version:L1.0 Date:2019.9.12-------------")
print("---- Copyright©2019-2099 FanHaoran All Right Reserved ---")
print("-----------------------------------------------------------")
# for i in tqdm.tqdm(range(100)):
# time.sleep(0.004)
def file_remove(self, fn):
if os.path.exists(fn):
os.remove(fn)
else:
return -1
def delete_group(self):
for i in range(1, 10000):
b = "group_" + str(i) + ".txt"
if self.file_remove(b) == -1:
break
def Sys_Exit(self):
exit(0)
def Menu(self):
self.Init_Interface()
print("-- 系统初始化完成!")
time.sleep(0.5)
while True:
print("-- MENU(菜单)")
print("-- 1 读取班级学生姓名")
print("-- 2 对学生进行分组")
print("-- 3 从小组中抽一人回答问题")
print("-- 4 抽取若干人测试")
print("-- 5 记录学生回答问题及测试次数")
print("-- 6 删除记录")
print("-- 7 退出系统")
a = int(input("请输入指令:\n>>"))
# 1 读取班级学生姓名
if a == 1:
self.read_name()
print("<< 学生姓名读取成功,共" + str(self.num) + "人")
time.sleep(1.5)
# 2 对学生进行分组
elif a == 2:
if self.group_flag == 1: # 程序分组过
ip = int(input("存在现有分组.重新分组请输入 1 ,退出请输入 2\n>>"))
while True:
if ip == 1 or ip == 2:
break
ip = int(input("!! 输入错误。重新分组请输入 1 ,退出请输入 2\n>>"))
if ip == 1:
self.delete_group()
g = int(input("请输入组数:\n>>"))
while True:
if 0 < g <= self.num:
break
g = int(input("!! 输入错误。请重新输入组数:\n>>"))
self.split_groups(g)
print("<< 分组成功,分为" + str(self.group_num) + "组")
time.sleep(1.5)
else:
print("<< 取消分组")
time.sleep(1.5)
else: # 程序未分组
if os.path.exists("group_1.txt"):
ip = int(input("本地已存在分组文件,导入请输入1,重新分组请输入2\n>>"))
while True:
if ip == 1 or ip == 2:
break
ip = int(input("!! 输入错误。导入请输入1,重新分组请输入2\n>>"))
if ip == 1: # 导入分组
print("<< 导入分组暂时未完成,进入重新分组")
else: # 重新分组
pass
self.group_flag = 1
self.delete_group()
g = int(input("请输入组数:\n>>"))
while True:
if 0 < g <= self.num:
break
g = int(input("!! 输入错误。请重新输入组数:\n>>"))
self.split_groups(g)
print("<< 分组成功,分为" + str(self.group_num) + "组")
time.sleep(1.5)
# 3 从小组中抽一人回答问题
elif a == 3:
ip = int(input("输入欲抽组号:\n>>"))
while True:
if 0 < ip <= self.group_num:
break
else:
ip = int(input("!! 输入错误,请重新输入欲抽组号:\n>>"))
b = self.ask_one(a)
print("<< 被抽中的是第" + str(a) + "组的" + b)
time.sleep(1.5)
# 4 抽取若干人测试
elif a == 4:
ip = int(input("请输入测试人数:\n>>"))
while True:
if 0 < ip <= self.num:
break
else:
ip = int(input("!! 输入错误,请输入测试人数:\n>>"))
b = self.test_some(a)
print("<< 测试的" + str(a) + "人为:", b)
time.sleep(1.5)
# 5 记录学生回答问题及测试次数
elif a == 5:
self.record()
print("<< 答题及测试记录存储完毕")
time.sleep(1.5)
# 6 删除记录
elif a == 6:
self.file_remove("record.txt")
print("<< 记录删除完成")
time.sleep(1.5)
# 7 退出系统
elif a == 7:
print("<< 系统即将关闭")
self.Sys_Exit()
# 输入错误
else:
print("!! 输入错误")
if __name__ == "__main__":
tea = LessonHelper()
tea.Menu()