作业要求:

角色:学校、学员、课程、讲师

要求:
1. 创建北京、上海 2 所学校
2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开
3. 课程包含,周期,价格,通过学校创建课程 
4. 通过学校创建班级, 班级关联课程、讲师
5. 创建学员时,选择学校,关联班级
5. 创建讲师角色时要关联学校, 
6. 提供两个角色接口
6.1 学员视图, 可以注册, 交学费, 选择班级,
6.2 讲师视图, 讲师可管理自己的班级, 上课时选择班级, 查看班级学员列表 , 修改所管理的学员的成绩 
6.3 管理视图,创建讲师, 创建班级,创建课程

7. 上面的操作产生的数据都通过pickle序列化保存到文件里

思路分析

  1. 模型或者角色:学校, 课程, 学生, 讲师, 班级。 创建类的先后次序上,从属性最简单的课程开始

  2. 角色的成员属性

    • 课程Course: 名称,价格,周期
    • 班级ClassRoom:名称,课程详情(1:1),学生(1:n)
    • 讲师Tutor: 姓名,性别,工资,年龄,所教授的班级(1:n)
    • 学生Student: 姓名,性别,年龄,分数
    • 学校School: 校区名称,地址,课程(1:n), 班级(1:n), 讲师(1:n), 学生(1:n)
  1. 关联关系

班级:课程 = 1:1

班级:学生 = 1:n

讲师:班级 = 1:n

学校:课程 = 1:n

学校:班级 = 1:n

学校:讲师 = 1:n

学校:学生 = 1:n

核心点:信息存储在文件时,需要做到一个文件修改另个文件也修改,类似一个“伪”数据库,这里类和类的一对多关系全部由字典完成。 牵涉到使用shelves。

有待扩展: 学生:班级 = 1:n 学生能够选多个课程班级。

  1. 视图功能
    • 学校视图(admin):创建课程,创建班级,招聘讲师,查看课程,查看班级,查看讲师
    • 学生视图(student):(一个功能点)注册,付学费, 选择班级
    • 讲师视图(Tutor):查看不同班级的学生, 修改学生成绩
  1. 通过视图,勾勒类的方法
    • Student: 修改分数modify_score(逻辑:分数是学士的属性,修改属性提供接口)
    • Tutor: 挂钩班级attach_class(逻辑:所教授班级是tutor属性,修改属性提供接口)
    • School: 实例课程new_course, 实例班级new_class, 实例学生new_student, 显示班级|课程|学生 show_info
  1. main.py, 把故事串起来。

知识点

1. OPP编程基础, 实例绑定及调用

2. shevel函数:创建的文件 .db

3. 伪数据库的建立:文件, 关系链用字典链接

代码结构

 

作业代码:

\bin\course_sys.py

import os, sys

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

sys.path.append(BASE_DIR)

from core import main

if __name__ == '__main__':
    main.sys_run()
主程序入口

\conf\settings.py

import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

DB_FILE = os.path.join(BASE_DIR, "db")

school_db_file = os.path.join(DB_FILE, "school")

#print(school_db_file)
配置文件路径

\conf\templats.py

MAIN_MENU = '''
|----------------------------------------- 选课系统 -------------------------------------------|
|                                                                                             |
|                                       1. 学生   Student                                     |
|                                       2. 讲师   Tutor                                       |
|                                       3. 管理员 Admin                                       |
|                                                                                             |
|---------------------------------------------------------------------------------------------|                  
'''


STUDENT_MENU = '''
|-------------------------------------- 选课系统 学生版 ---------------------------------------|
|                                                                                             |
|                                       1. 课程注册                                           |
|                                                                                             |
|---------------------------------------------------------------------------------------------|
'''


TUTOR_MENU = '''
|-------------------------------------- 选课系统 讲师版 ---------------------------------------|
|                                                                                             |
|                                       1. 查看班级                                           |
|                                       2. 更新成绩                                           |
|---------------------------------------------------------------------------------------------|
'''


ADMIN_MENU = '''
|-------------------------------------- 选课系统 学校版 ---------------------------------------|
|                                                                                             |
|     1. 新建课程                       2. 新建班级                       3. 招聘讲师           |
|     4. 查看课程                       5. 查看班级                       6. 查看讲师           |
|     7. 查看学生                                                                              |
|---------------------------------------------------------------------------------------------|
'''
配置文件 - 格式

\core\main.py

import os, sys, shelve

from lib.school import School
from conf import settings
from conf import templates


def sys_run():
    """
    主页面
    :return:
    """
    print(templates.MAIN_MENU)
    main_menu = {
        "1": StudentPortal,
        "2": TutorPortal,
        "3": AdminPortal
    }
    while True:
        main_opt = input("请选择相应视图 【q键 退出】>>> ").strip()
        if main_opt == "q":
            sys.exit("感谢使用【选课系统】")
        elif main_opt in main_menu:
            main_menu[main_opt]()
        else:
            print("输入有误,请重新选择")
            continue


class AdminPortal(object):
    """
    学校管理员视图
    """
    def __init__(self):
        if os.path.exists(settings.school_db_file + ".db"):
            self.db = shelve.open(settings.school_db_file)
            self.admin_center()
            self.db.close()
        else:
            self.init_sch()
            self.admin_center()
            self.db.close()

    def init_sch(self):
        # 初始化校区
        self.db = shelve.open(settings.school_db_file)
        self.db["BJ"] = School("北京总校", "北京朝阳")   # shelve的用法,key 必须为字符串
        self.db["SH"] = School("上海分校", "上海浦东")

    def admin_center(self):
        # 管理员视图:
        print("|-------------------------------------- 选课系统 学校版 ---------------------------------------|")
        for sch in self.db:
            print(sch)
        sch_opt = input("请选择校区 >>> ").strip()
        sch_obj = self.db[sch_opt]
        print(sch_obj)

        while True:
            print(templates.ADMIN_MENU)
            admin_menu = {
                    "1": self.add_course,
                    "2": self.add_class,
                    "3": self.hire_tutor,
                    "4": self.check_course,
                    "5": self.check_class,
                    "6": self.check_teacher,
                    "7": self.check_student,
                }
            admin_opt = input("请选择功能 【q键 退出】 >>> ").strip()
            if admin_opt in admin_menu:
                admin_menu[admin_opt](sch_opt)
                self.admin_center()
                break
            elif admin_opt == "q":
                sys.exit("欢迎使用系统")
            else:
                print("输入有误,请重新选择")
                continue

    def add_course(self, sch_opt):
        # 新建课程接口,呼应 school/new_course
        while True:
            course_name = input("请输入【课程名称】")
            course_price = input("请输入【课程价格】")
            course_cycle = input("请输入 【课程周期】")
            print("课程名称:%s | 课程价格:%s | 课程周期:%s |" %
                  (course_name,course_price,course_cycle))
            confirmation = input("请确认 Y/N").strip()
            if confirmation == "Y":
                sch_obj = self.db[sch_opt]
                sch_obj.new_course(course_name, course_price, course_cycle)
                self.db[sch_opt] = sch_obj
                print("%s 校区 新建课程 %s" %(sch_obj.name, course_name))
                break
            else:
                continue

    def add_class(self,sch_opt):
        # 新建班级接口
        while True:
            class_name = input("请输入 【班级名称】")
            sch_obj = self.db[sch_opt]
            course_list = sch_obj.sch_course.keys()
            print("现有课程:%s" % course_list)
            course_name = input("请输入 【关联课程】")
            if course_name in sch_obj.sch_course:
                print("班级名称:%s | 关联课程:%s |" % (class_name, course_name))
                confirmation = input("请确认 Y/N").strip()
                if confirmation == "Y":
                    course_obj = sch_obj.sch_course[course_name]
                    sch_obj.new_class(class_name, course_obj)
                    self.db[sch_opt] = sch_obj
                    print("%s 校区 新建班级 %s" % (sch_obj.name, class_name))
                    break
                else:
                    continue
            else:
                print("无该课程,请先创建")
                continue

    def hire_tutor(self, sch_opt):
        # 招聘新讲师
        while True:
            tutor_name = input("请输入 【讲师名字】")
            tutor_sex = input("请输入 【性别】")
            tutor_salary = input("请输入 【工资】")
            class_name = input("请输入 【班级】")
            print("讲师:%s | 性别:%s | 工资:%s | 班级:%s |" %
                  (tutor_name, tutor_sex, tutor_salary, class_name))
            confirmation = input("请确认 Y/N").strip()
            if confirmation == "Y":
                sch_obj = self.db[sch_opt]
                class_obj = sch_obj.sch_class
                sch_obj.new_tutor(tutor_name, tutor_sex, tutor_salary, class_name, class_obj)
                self.db[sch_opt] = sch_obj
                print("%s 校区 新聘讲师 %s" % (sch_obj.name, tutor_name))
                break
            else:
                continue

    def check_course(self, sch_opt):
        # 查询课程
        self.db[sch_opt].show_course()
        print("|---------------------------------------- THE END -----------------------------------------|")

    def check_class(self, sch_opt):
        # 查询班级
        self.db[sch_opt].show_class()
        print("|---------------------------------------- THE END -----------------------------------------|")

    def check_teacher(self, sch_opt):
        # 查询讲师
        self.db[sch_opt].show_tutor()
        print("|---------------------------------------- THE END -----------------------------------------|")

    def search_tutor(self, sch_opt):
        # 查询讲师
        tutor_name = input("请输入 【讲师名字】")
        self.db[sch_opt].search_tutor(tutor_name)
        print("|---------------------------------------- THE END -----------------------------------------|")

    def check_student(self, sch_opt):
        # 查询学生
        self.db[sch_opt].show_student()
        print("|---------------------------------------- THE END -----------------------------------------|")


class StudentPortal(object):
    # 学生视图:注册学籍,选课缴费
    def __init__(self):
        if os.path.exists(settings.school_db_file + ".db"):
            self.db = shelve.open(settings.school_db_file)
            self.stu_center()
            self.db.close()
        else:
            sys.exit("请联系学校管理员")

    def stu_center(self):
        """
        学生中心
        :return:
        """
        print("|-------------------------------------- 选课系统 学生版 ---------------------------------------|")
        for sch in self.db:
            print(sch)
        sch_opt = input("请选择校区 >>> ").strip()

        while True:
            print(templates.STUDENT_MENU)
            stu_menu = {
                "1": self.stu_enroll}
            # "2": self.sel_class}
            while True:
                stu_opt = input("请选择功能 【q键 退出】 >>> ").strip()
                if stu_opt in stu_menu:
                    stu_menu[stu_opt](sch_opt)
                elif stu_opt == "q":
                    sys.exit("欢迎使用系统")
                else:
                    print("输入有误,请重新选择")
                    continue

    def stu_enroll(self, sch_opt):
        # 新生注册
        sch_obj = self.db[sch_opt]
        while True:
            stu_name = input("请输入 【学生姓名】")
            stu_sex = input("请输入 【性别】")
            stu_age = input("请输入 【年龄】")
            print("学生姓名:%s | 性别:%s | 年龄:%s |" % (stu_name, stu_sex, stu_age))
            confirmation = input("请确认 Y/N").strip()
            if confirmation == "Y":
                while True:
                    class_name = input("请输入 【班级】")
                    if class_name in sch_obj.sch_class:
                        class_obj = sch_obj.sch_class[class_name]
                        course_obj = class_obj.class_course
                        while True:
                            pay_opt = input("您选择 【%s】, 价格为 【%s】。请付款" %(class_name, course_obj.price)).strip()
                            if pay_opt == course_obj.price:
                                sch_obj.new_student(stu_name, stu_sex, stu_age, class_name)  # 实例学生
                                self.db[sch_opt] = sch_obj                              # 非常关键,实例化好后需要存储到db里
                                print("选课成功,少年。快学习去吧")
                                break
                            else:
                                print("哥儿,多付少付都不行")
                                continue
                        break
                    else:
                        print("没开课,滚出")
                        continue
                break
            else:
                continue


class TutorPortal(object):
    # 讲师视图:查询班级,更新成绩
    def __init__(self):
        if os.path.exists(settings.school_db_file + ".db"):
            self.db = shelve.open(settings.school_db_file)
            self.tutor_center()
            self.db.close()
        else:
            sys.exit("请联系学校管理员")

    def tutor_center(self):
        # 讲师中心
        print("|-------------------------------------- 选课系统 讲师版 ---------------------------------------|")
        for sch in self.db:
            print(sch)
        sch_opt = input("请选择校区 >>> ").strip()

        while True:
            print(templates.TUTOR_MENU)
            tutor_menu = {
                "1": self.check_class,
                "2": self.update_score}
            while True:
                tutor_opt = input("请选择功能 【q键 退出】 >>> ").strip()
                if tutor_opt in tutor_menu:
                    tutor_menu[tutor_opt](sch_opt)
                elif tutor_opt == "q":
                    sys.exit("欢迎使用系统")
                else:
                    print("输入有误,请重新选择")
                    continue

    def check_class(self, sch_opt):
        sch_obj = self.db[sch_opt]
        tutor_name = input("请输入 【讲师姓名】 >>>").strip()
        if tutor_name in sch_obj.sch_tutor:
            sch_obj.search_tutor(tutor_name)
        else:
            print("无该讲师")

    def update_score(self, sch_opt):
        sch_obj = self.db[sch_opt]
        stu_name = input("请输入 【学生名字】 >>>").strip()
        new_score = input("请输入 【考试分数】 >>>").strip()
        sch_obj.modify_score(stu_name, new_score)
        self.db[sch_opt] = sch_obj
主程序

\lib\classroom.py

class ClassRoom(object):
    """
    类,班级
    """
    def __init__(self, classroom_name, course_obj):
        """
        描述班级
        :param classroom_name: 班级名称,如[s1,s2, b1,b2]
        :param course_obj: 班级所对应课程的实例对象
        """
        self.name = classroom_name
        self.class_course = course_obj
        self.class_student = {}
classroom类

\lib\course.py

class Course(object):
    """
    类,课程
    """

    def __init__(self, course_name, course_price, course_cycle):
        """
        课程
        :param course_name: 课程名称
        :param course_price: 课程价格
        :param course_cycle: 课程周期
        """
        self.name = course_name
        self.price = course_price
        self.cycle = course_cycle
course类

\lib\student.py

class Student(object):
    '''
    类,学生
    '''
    def __init__(self, stu_name, stu_sex, stu_age):
        '''
        学生
        :param stu_name: 学生名字
        :param stu_sex: 学生性别
        :param stu_age: 学生年龄
        '''
        self.name = stu_name
        self.sex = stu_sex
        self.age = stu_age
        self.score = 0
学生类

\lib\tutor.py

class Tutor(object):
    """
    类,讲师
    """
    def __init__(self, tutor_name, tutor_sex, tutor_salary):
        """
        讲师
        :param tutor_name: 讲师名字
        :param tutor_sex: 讲师性别
        :param tutor_salary: 讲师工资
        """
        self.name = tutor_name
        self.sex = tutor_sex
        self.salary = tutor_salary
        self.tutor_class = {}

    def attach_classroom(self, class_name, class_obj):
        self.tutor_class[class_name] = class_obj
讲师类

\lib\school.py

rom lib.classroom import ClassRoom
from lib.course import Course
from lib.student import Student
from lib.tutor import Tutor

class School(object):
    def __init__(self, sch_name, sch_addr):
        """
        学校
        :param sch_name: 校区名字,如“北京总校”,“上海分校”
        :param sch_addr:校区地址
        """
        self.name = sch_name
        self.address = sch_addr
        self.sch_course = {}
        self.sch_class = {}
        self.sch_tutor = {}
        self.sch_student = {}

    def new_course(self,course_name, course_price, course_cycle):
        """
        创建新课程
        :param course_name: 课程名称
        :param course_price: 价格
        :param course_cycle: 周期
        :return:
        """
        course_obj = Course(course_name,course_price,course_cycle)
        self.sch_course[course_name] = course_obj

    def new_class(self, class_name, course_obj):
        """
        创建新班级
        :param classroom_name: 班级名称
        :param course_obj: 课程实例
        :return:
        """
        if course_obj.name in self.sch_course and class_name not in self.sch_class:
            class_obj = ClassRoom(class_name, course_obj)
            self.sch_class[class_name] = class_obj
        else:
            print("信息错误")

    def new_tutor(self, tutor_name, tutor_sex, tutor_salary, class_name, class_obj):
        """
        创建新讲师, 并关联一个课程
        :param tutor_name: 讲师名字
        :param tutor_sex: 讲师性别
        :param tutor_salary: 讲师收入
        :param class_name: 班级名称
        :param class_obj: 班级实例
        :return:
        """
        tutor_obj = Tutor(tutor_name, tutor_sex, tutor_salary)
        tutor_obj.attach_classroom(class_name, class_obj)
        self.sch_tutor[tutor_name] = tutor_obj

    def new_student(self, stu_name, stu_sex, stu_age, class_name):
        """
        创建新学生,包括实例化学生,加入班级
        :param stu_name:
        :param stu_sex:
        :param stu_age:
        :param class_name:
        :return:
        """
        stu_obj = Student(stu_name, stu_sex, stu_age)
        self.sch_student[stu_name] = stu_obj
        class_obj = self.sch_class[class_name]
        class_obj.class_student[stu_name] = stu_obj
        self.sch_class[class_name] = class_obj

    def show_course(self):
        """
        课程信息显示,结果:【课程名称:xx 课程价格:xxxx 周期:xx】
        :return:
        """
        for course_name in self.sch_course:
            course_obj = self.sch_course[course_name]
            print("课程名称:%s 价格:%s 周期:%s" % (course_obj.name,
                                           course_obj.price, course_obj.cycle))

    def show_class(self):
        """
        班级信息显示,数据显示:【班级名称:xx 课程名称:xx 价格:xxxx 周期:xx 】
        :return:
        """
        for class_name in self.sch_class:
            class_obj = self.sch_class[class_name]
            course_obj = class_obj.class_course
            print("班级:%s 课程:%s 周期:%s" %
                  (class_obj.name, course_obj.name, course_obj.cycle))

    def show_student(self):
        """学生信息"""
        for class_name in self.sch_class:
            class_obj = self.sch_class[class_name]
            for stu_name in class_obj.class_student:
                stu_obj = class_obj.class_student[stu_name]
                print("班级:%s 学生:%s 性别:%s 分数:%s" %
                      (class_obj.name, stu_obj.name, stu_obj.sex, stu_obj.score))


    def show_tutor(self):
        """
        老师信息显示,数据显示:【讲师:xx 课程名称:xx 班级:xx 学员:xx】
        :return:
        """
        for tutor_name in self.sch_tutor:
            tutor_obj = self.sch_tutor[tutor_name]
            class_list = []
            for class_name in tutor_obj.tutor_class:
                class_list.append(class_name)
                print("讲师:%s 薪酬:%s 班级:%s" %
                      (tutor_obj.name, tutor_obj.salary, class_list))

    def search_tutor(self, tutor_name):
        """
        查询某讲师信息
        :param tutor_name:
        :return:
        """
        tutor_obj = self.sch_tutor[tutor_name]
        for class_name in tutor_obj.tutor_class:
            class_obj = self.sch_class[class_name]
            stu_list = []
            for stu in class_obj.class_student:
                stu_list.append(stu)
            print("======== 讲师【%s】的信息如下 ========" % tutor_name)
            print("班级:%s | 课程:%s | 周期:%s | 学生:%s" %
                  (class_name, class_obj.class_course.name, class_obj.class_course.cycle, stu_list))

    def modify_score(self, stu_name, new_score):
        stu_obj = self.sch_student[stu_name]
        stu_obj.score = new_score
        self.sch_student[stu_name] = stu_obj
学校类,很重要

 

作业评语:

1. 

这类这种代码可用 字符串格式化 和 字符串乘以一个数字 来替代  

2. 有部分 无法退出 的情况,可进一步改进

 

posted on 2017-12-06 22:00  lg100_lg100  阅读(444)  评论(0编辑  收藏  举报