项目----------学生信息管理系统

学生信息管理系统

项目需求
    实现对学生信息的增删改查/排序

项目分析
    界面:先用控制台,后面可以使用web页面展示


    1 识别对象  封装[分]
        界面视图类(V  Views)
        逻辑控制类(C  Controller)
        数据模型类(M  Model)

    2 分配职责
        界面视图类
            负责界面逻辑,比如:菜单/用户输入

        逻辑控制类
            负责学生信息的增删改查排序的算法实现

        数据模型类
            负责定义数据的类型(格式)
项目框架
        MVC
            数据模型类 StudentModel
                属性(数据): id/name/age/score/height/weight/addreess
                          主键(唯一性)

        逻辑控制类 StudentManagerController
            属性:
                __list_student  存储学生对象

            方法:
                增加: add_student
                删除: delete_student
                修改: update_student
                排序: sort_student

        界面视图类 StudentManagerViews   与用户交互
            原则: 提供必要的功能/隐藏实现的细节

            数据:
                self.__controller

            方法:
                显示菜单方法: __display_menu
                选择菜单方法: __select_menu
                输入方法: __input_student
                显示方法: __print_student
                删除方法: __remove_student
                修改方法: __modify_student
                排序方法:__sort_by_score
                主方法: main
  问题:
                1 ID唯一?
                    ID用于修改/删除
                    自动生成(在调用添加方法时实现自增1 [自定义:1000])
                        方案1: 在类外定义一个初始id,通过调用add_student方法实现自增长
                            缺点: 不符合面向对象的思想

                    方案2: 在Controller类中定义实例变量 init_id
                        缺点: 如果实例化多次,id会重复

                    方案3: 定义init_id为类变量


            2 list_student 如何避免外界修改?
                类外可以添加学生的对象到list_student(实例变量)
                私有
                    问题:类外不能直接方法
                    措施:提供只读方法

            3 删除学生对象是使用del或remove方法?
                del item   删除的是一个对象,与__list_student没有关系
                self.__list_student.remove(item) (对)

            4 如何实现新的学生对象更新旧的学生对象?
                更新数据: name/age/score
                id 唯一
                对比ID:找对旧的学生对象,更新name/age/score

            5 在视图类中,如何更好的调用逻辑控制类中的增删改排序的算法?
                StudentManagerConctroller().add_student(stu)
                以上调用方法,会产生每次实例化逻辑控制类造成__list_student为空

                问题:不能重复调用
                措施:
                    1 用户实例化视图类需要几次?   1次
                      意味着:只调用1次构造方法

                    2 调用逻辑控制类的方法都是在视图类中的方法中被调用

                    在视图类中的构造方法中实例化逻辑控制类
                    好处:为视图类实例化视图类的对象添加一个属性

            6 用户修改学生的信息?
                1、创建一个新的学生对象(逻辑控制器类中修改方法需要传递一个修改的学生对象)
                2、用户输入学生的ID(唯一性)
                3、判断用户输的学生ID是否已经存在于存储学生的列表中【列表推导式】
                4、存在,则用户输入name、age、score赋值给新的学生对象对应的变量
                5、调用逻辑控制器类中的修改方法修改成功与否,打印提示信息

            7 用户端不能违背程序设计原则?
                原则:提供必要功能,隐藏实现的细节
                操作:
                    将一些不需要提供的方法实现私有化
'''
    实现学生信息管理系统
'''
import os

class StudentManagerModel:
    ''' 实现学生数据模型类 '''

    def __init__(self, name='', age=0, score=0, id=0):
        self.id = id
        self.name = name
        self.age = age
        self.score = score

    @property
    def age(self):  # 读取方法
        return self.__age

    @age.setter
    def age(self, value):  # 写入(保护实例变量/数据有效性验证)
        if 0 <= value <= 200:
            self.__age = value
        else:
            raise Exception('年龄应该在[0, 200]')

    @property
    def score(self):
        return self.__score

    @score.setter
    def score(self, value):
        if 0 <= value <= 150:
            self.__score = value
        else:
            raise Exception('成绩应该在[0, 150]')


# 方式1:在类外产生一个变量
# init_id = 1000   # 不可变[面向过程的思想]

class StudentManagerController:
    '''  实现增删改查/排序的算法  '''
    # 方法3
    init_id = 1000  # 类变量

    def __init__(self):
        # 原因: views中是用户输入的数据,通过对象的属性传递数据
        # 在逻辑算法中存储学生对象可以操作兑现实现对应的功能.避免需要传入多个参数
        self.__list_student = []  # 存储所有的学生对象
        # 方法2:
        # self.init_id = 1000

    @classmethod
    def generate_id(cls, stu):
        ''' 通过类变量,实现id自增长 '''
        stu.id = cls.init_id
        cls.init_id += 1

    @property
    def list_student(self):    # 只读
        return self.__list_student

    def add_student(self, stu):
        '''
            添加学生对象
        :param stu: objetct, 添加的学生对象
        :return: None
        '''
        # 方法1: 不符合面向对象的思想
        # global init_id
        # stu.id = init_id     # 修改学生对象的初始id
        # init_id += 1

        # 方法2: 如果实例化多次,id会重复
        # stu.id = self.init_id
        # self.init_id += 1

        # 方法3:
        StudentManagerController.generate_id(stu)
        self.__list_student.append(stu)

    def delete_student(self, del_stu_id):
        '''
            删除学生对象
        :param del_stu_id: int, 要删除的学生的ID
        :return: bool, True:表示删除成功,False:表示删除失败
        '''
        for item in self.__list_student:
            if item.id == del_stu_id:
                # del item
                self.__list_student.remove(item)
                return True
        return False

    def update_student(self, new_stu):
        '''
            修改学生对象的数据
        :param new_stu: object, 要修改的学生对象
        :return: bool, True:表示修改成功,False:表示修改失败
        '''
        for item in self.__list_student:
            if item.id == new_stu.id:
                item.name = new_stu.name
                item.age = new_stu.age
                item.score = new_stu.score
                return True
        return False

    def sort_student(self):
        ''' 按成绩降序排列 '''
        for r in range(len(self.__list_student)-1):
            for c in range(r+1, len(self.__list_student)):
                if self.__list_student[r].score < self.__list_student[c].score:
                    self.__list_student[r], self.__list_student[c] = \
                        self.__list_student[c], self.__list_student[r]

# 测试
# 添加学生
# stu_col = StudentManagerController()
# s01 = StudentManagerModel('孙悟空', 90, 77)
# s02 = StudentManagerModel('八戒', 60, 86)
# s03 = StudentManagerModel('悟净', 50, 67)
# stu_col.add_student(s01)
# stu_col.add_student(s02)
# stu_col.add_student(s03)

# 删除学生
# stu_col.delete_student(1001)

# 修改学生
# stu_col.update_student(
#     StudentManagerModel('沙僧', 70, 99, 1002)
# )

# 排序
# stu_col.sort_student()

# 只读
# stu_col.list_student.append(StudentManagerModel('唐僧', 22, 99))

# for stu in stu_col.list_student:
#     print(stu.name, stu.age, stu.score, stu.id)


class StudentManagerViews:
    '''  实现与用户交互(输入/输出数据)  '''
    def __init__(self):
        self.controller = StudentManagerController()

    def display_menu(self):
        print('1 添加学生')
        print('2 查看学生')
        print('3 删除学生')
        print('4 修改学生')
        print('5 排序学生')
        print('---------------')

    def select_menu(self):
        chioce = input('请输入您的选择')
        if not chioce:
            # break     # 只能用于循环中(while/for)
            # return    # 是作为了select_menu的返回值
            os._exit(0) # 程序正常结束

        if chioce == '1':    # 添加学生
            self.input_student()
        elif chioce == '2':  # 查看学生
            self.print_student()
        elif chioce == '3':  # 删除学生
            pass
        elif chioce == '4':   # 修改学生
            pass
        elif chioce == '5':   # 排序学生
            pass
        else:
            print('请输入[1, 5]之间的整数')

    def input_student(self):
        '''
            用户输入学生的信息(name/age/score)
        :return: None
        '''
        name = input('请输入姓名:')
        age = int(input('请输入年龄:'))
        score = int(input('请输入成绩:'))
        stu = StudentManagerModel(name, age, score)
        self.controller.add_student(stu)

    def print_student(self):
        '''
            打印学生的信息
        :return: None
        '''
        for item in self.controller.list_student:
            print(item.id, item.name, item.age, item.score)

    def main(self):
        ''' 主方法: 实现最后逻辑的链接 '''
        while True:
            self.display_menu()
            self.select_menu()


stu_view = StudentManagerViews()
stu_view.main()


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XU AE86

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值