Python学生信息管理系统-2(面向对象,涉及到简单的文件操作处理)

举报
乂氼S 发表于 2023/05/28 13:37:20 2023/05/28
【摘要】 Python学生信息管理系统-2(面向对象,涉及到简单的文件操作处理)
​
# coding:utf-8

# @Author:dx
# @Time:2023-4-20
# @File:学生信息管理系统(面向对象).py
"""
    学生信息管理系统
"""
print('欢迎使用学生信息管理系统~>_<~')


class NotArgError(Exception):
    def __init__(self, message):
        self.message = message


class StudentsInfo(object):
    """类中的函数没有先后顺序,无论定义在哪里都可以获取到"""

    # 将字典对象传入类中
    def __init__(self, student):
        self.students = student

    # 按学号查找学生信息
    def get_by_id(self, students_id):
        return self.students.get(students_id)

    # 获取所有的学生信息
    def get_all(self):
        for _id, value in self.students.items():
            print('学号{},姓名{},年龄{},班级{},性别{}'.format(_id, value['name'], value['age'], value['class_number'],
                                                    value['sex']))
        return self.students

    # 检查学生信息是否正确
    @staticmethod
    def check_user_info(**kwargs):
        assert len(kwargs) == 4, '参数必须是四个'
        if 'name' not in kwargs:
            raise NotArgError('缺少学生姓名参数')
        if 'age' not in kwargs:
            raise NotArgError('缺少学生年龄参数')
        if 'class_number' not in kwargs:
            raise NotArgError('缺少学生班级参数')
        if 'sex' not in kwargs:
            raise NotArgError('缺少学生性别参数')

        name_value = kwargs['name']
        age_value = kwargs['age']
        class_number_value = kwargs['class_number']
        sex_value = kwargs['sex']

        if not isinstance(name_value, str):
            raise TypeError('name应该是字符串类型')
        if not isinstance(age_value, int):
            raise TypeError('age应该是整数类型')
        if not isinstance(class_number_value, str):
            raise TypeError('class_number应该是整数类型')
        if not isinstance(sex_value, str):
            raise TypeError('sex应该是字符串类型')

    # 添加学生(单个)
    def add(self, **student):
        try:
            self.check_user_info(**student)
        except Exception as e:
            raise e
        self.__add(**students)

    # 添加成员(批量)
    def adds(self, new_students):
        for student in new_students:
            try:
                self.check_user_info(**student)
            except Exception as e:
                print(e, student.get('name'))
                continue
            self.__add(**student)

    # 用于将学号和新添加的学生成员绑定传入字典中
    def __add(self, **student):
        try:
            new_id = max(self.students) + 1
            self.students[new_id] = student
        except ValueError:
            new_id = 1
            self.students[new_id] = student

    # 用于删除单个成员
    def delete(self, students_id):
        if students_id not in self.students:
            print('{}不存在'.format(students_id))
        else:
            deleted_students = self.students.pop(students_id)
            print('学号为{}, 姓名为{}的学生已删除'.format(students_id, deleted_students['name']))

    # 批量删除成员
    def deletes(self, ids):
        for student in ids:
            self.delete(student)

    # 修改单个成员
    def update(self, students_id, **kwargs):
        if students_id not in self.students:
            print('不存在这个学号')
            return
        try:
            self.check_user_info(**kwargs)
        except (NotArgError, TypeError) as e:
            raise e
        self.students[students_id] = kwargs
        print('学生信息更新完毕!')

    # 批量修改成员
    def updates(self, update_students):
        for student in update_students:
            try:
                _id = list(student.keys())[0]
            except IndexError as e:
                print(e)
                continue
            user_info = self.students[_id]
            if _id not in self.students:
                print('此学号不存在')
                continue
            try:
                self.check_user_info(**user_info)
            except Exception as e:
                print(e)
                continue

            """
                if check != True` 和 `if not check` 在大多数情况下是等价的,都是检查`check`是否为False。
                但是这两个表达式在处理某些特定数据类型时可能会出现不同的行为。
                如果`check`是一个自定义类的实例,那么 `check != True` 可能会调用`__ne__`方法(与`__eq__`相对),而 `not check` 
                则会调用`__bool__`或`__len__`方法来确定对象的“真值”(truth value)。因此,这两个表达式在这种情况下可能会产生不同的结果。
                另外,如果 `check` 是一个可调用对象,例如一个函数或一个lambda表达式,那么 `not check` 会尝试调用它并检查结果是否为False,
                而 `check != True` 则会检查 `check` 是否返回`True`或`False`。
                总之,对于大多数数据类型,这两个表达式是等价的,但在某些特定情况下,它们可能会产生不同的结果。
            """
            self.students[_id] = user_info
        print('学生信息更新完毕!')

    # 用于模糊匹配成员
    def search(self, **kwargs):
        """
            self.students =  {1: {'name': '小舒', 'age': 18, 'class_number': 6, 'sex': 'famale'},
                            2: {'name': 'xiaoshu', 'age': 18, 'class_number': 2, 'sex': 'famale'},
                            3: {'name': 'xiaoding', 'age': 18, 'class_number': 5, 'sex': 'famale'},
                            4: {'name': 'xiaozhao', 'age': 19, 'class_number': 4, 'sex': 'male'}}
        """
        assert len(kwargs) < 4
        datas = self.students
        empty_list = []
        result = []
        compare = []
        if kwargs != {}:
            for s in list(kwargs.values()):
                empty_list.append(s)
        else:
            raise NotArgError('没有发现搜索的关键词!')

        for key in datas:
            value = (self.students[key])
            number = 0
            for s in empty_list:
                if str(s) in str(value):
                    number += 1
            if number == 0:
                continue
            compare.append(number)
            compare.sort(reverse=True)
            result.insert(compare.index(number), value)  # 会按照对应的信息个数从大到小进行排序
        if not result:
            print('未搜索到相关信息')
        return result

    @staticmethod
    def set_info():
        print('请输入要查找、设置或更改后的学生信息:')
        name1 = input('请输入学生姓名:')
        age1 = int(input('请输入学生年龄:'))
        class_number1 = int(input('请输入学生班级:'))
        sex1 = input('请输入学生性别(male/famale):')
        return dict(name=name1, age=age1, class_number=class_number1, sex=sex1)

    # 用户选择的服务
    def server(self):
        n = True
        while n:
            print('==' * 20)
            print('请选择服务:')
            print('1.查看所有学生信息')
            print('2.添加学生信息')
            print('3.批量添加学生信息')
            print('4.修改学生信息')
            print('5.批量修改学生信息')
            print('6.删除学生信息')
            print('7.批量删除学生信息')
            print('8.模糊查找学生信息')
            print('9.按学号查找学生信息')
            print('10.退出学生信息管理系统')
            choose = int(input('请输入服务序号:'))
            try:
                if choose == 1:
                    self.get_all()
                    print('==' * 20)
            except AttributeError:
                print('当前库中无成员~')
            if choose == 2:
                ii = self.set_info()  # ii == input_info代表输入的信息
                self.add(**ii)
                print('添加成功~,添加的学生信息如下:')
                print(self.students[max(students)])
                print('==' * 20)

            if choose == 3:
                result = []
                condition = True
                while condition:
                    infos = self.set_info()
                    result.append(infos)
                    choose_exit = input('是否继续添加?y/n:').lower()
                    if choose_exit == 'y':
                        continue
                    elif choose_exit == 'n':
                        self.adds(result)
                        print('添加成功!添加的全部信息如下~:')
                        for i in result:
                            print(i)
                        while True:
                            sure = input('以上信息是否有误?(y/n):').lower()
                            if sure == 'y':
                                print('即将进入修改界面~')
                                frequency = 0
                                while frequency <= 3:
                                    try:
                                        students_id = int(input('请输入所要更改学生的学号:'))
                                        print('设置学生信息:')
                                        ii1 = self.set_info()  # ii == input_info代表输入的信息
                                        self.update(students_id, **ii1)
                                    except ValueError:
                                        print(f'请输入正确格式的学号!(输错3次即强制退出,目前{frequency}次)')
                                        frequency += 1
                                        print('==' * 20)
                            elif sure == 'n':
                                condition = False
                                break
                            else:
                                print('error!!!请输入y/n:')
                    else:
                        print('error!!!请输入y/n:')

            if choose == 4:
                id_number = int(input('请输入已存在的学号:'))
                print('学号-{{{}}}-,对应的学生信息如下:\n{}'.format(id_number, self.students[id_number]))
                print('请选择要更改的学生信息:')
                print('1.学生姓名')
                print('2.学生年龄')
                print('3.学生班级')
                print('4.学生性别')
                number = int(input('请输入需要更改的序号:'))
                if number == 1:
                    name1 = input('请输入学生姓名:')
                    self.students[id_number]['name'] = name1
                if number == 2:
                    age1 = int(input('请输入学生年龄:'))
                    self.students[id_number]['age'] = age1
                if number == 3:
                    class_number1 = int(input('请输入学生班级:'))
                    self.students[id_number]['class_number'] = class_number1
                if number == 4:
                    sex1 = input('请输入学生性别(male/famale):')
                    self.students[id_number]['sex'] = sex1

                print('更新后的学生信息如下:')
                print(self.students[id_number])
                print('==' * 20)

            if choose == 5:
                frequency = 0
                info_list = []
                _id_list1 = []
                while frequency <= 3:
                    try:
                        print('即将进入修改界面~')
                        print('请更改学生信息:')
                        student_id = int(input('请输入学号(可多次):'))
                        _id_list1.append(student_id)
                        ii1 = self.set_info()
                        _set = {student_id: ii1}  # ii == input_info代表输入的信息
                        info_list.append(_set)
                        choose_exit = input('是否继续添加?y/n:').lower()
                        if choose_exit == 'y':
                            continue
                        elif choose_exit == 'n':
                            print('您已退出~')
                            self.updates(info_list)
                            print('您修改后的信息如下:')
                            for i in _id_list1:
                                print(self.students[i])
                                print('==' * 20)
                            break
                        else:
                            print('error!!!请输入y/n')
                    except ValueError:
                        print(f'请输入正确格式的学号!(输错3次即强制退出,目前{frequency}次)')
                        frequency += 1

            if choose == 6:
                id_number = int(input('请输入要删除学生的学号:'))
                self.delete(id_number)
                print('==' * 20)

            if choose == 7:
                frequency = 1
                _id_list2 = []
                while frequency <= 3:
                    try:
                        student_id = int(input('请输入学号(可多次)'))
                        _id_list2.append(student_id)
                        choose_exit = input('是否继续添加?y/n:').lower()
                        if choose_exit == 'y':
                            continue
                        elif choose_exit == 'n':
                            print('您已退出~')
                            print('您删除的学生信息如下:')
                            for i in _id_list2:
                                print(self.students[i])
                                print('==' * 20)
                            self.deletes(_id_list2)
                            break
                        else:
                            print('error!!!请输入y/n:')
                    except ValueError:
                        print(f'请输入正确格式的学号!(输错3次即强制退出,目前{frequency}次)')
                        frequency += 1

            if choose == 8:
                print('(下列信息,如某一项不知晓请输入\"0\")')
                ii2 = self.set_info()
                # 用于将用户输入为0的值所在的键值对去除,方便查找
                for d in list(ii2.keys()):
                    if ii2[d] == 0 or ii2[d] == '0':
                        del (ii2[d])
                print(self.search(**ii2))

            if choose == 9:
                frequency = 1
                while frequency <= 3:
                    try:
                        stu_id = int(input('请输入您所要查找的学生的学号:'))
                        self.get_by_id(stu_id)
                    except ValueError:
                        print(f'请输入正确格式的学号!(输错3次即强制退出,目前{frequency}次)')
                        frequency += 1

            if choose == 10:
                print('您已退出~')
                print('==' * 20)
                break


if __name__ == '__main__':
    while True:
        # 打开文件
        file = open('储存学生信息.txt', 'r+')
        # 将文件中的数据赋值给一个变量
        students = file.read()
        # 判断student内是否有数据,若没有数据则往里面加入一个大括号,以便让eval函数识别出文件内的数据是个字典对象,以便程序的顺利进行。
        if students:
            #  eval()函数可以将字符串解析为Python表达式,并返回解析后的对象。因此,如果字符串中包含字典的语法结构,那么可以使用eval()函数将其解析为字典对象
            students = eval(students)
        else:
            file.write('{}')
            continue
        break
    # 创建Studentinfo类的一个实例, 并把students实际参数传入类中
    students_info = StudentsInfo(students)
    # 调用类中的server方法
    students_info.server()
    # 关闭文档
    file.close()
    # 以只写模式打开文件(这种方法会自动清空文档中的内容,以确保文档中的数据是更改后的,而不是在原数据的后面追加)
    file = open('储存学生信息.txt', 'w')
    # 将程序执行结束后的变量传入所打开的文档中
    file.write(str(students_info.students))
    # 关闭文档以保存数据
    file.close()

​
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。