python项目——基于单例设计模式、面向对象开发选课系统


一、项目开发功能模块划分

1.功能划分

包/文件功能
interface登录、注册、选课等接口
core注册、登录、选课核心功能
db存放注册的用户数据
lib存放编写的公共方法文件
conf存放配置文件
readme.txt项目文档
requirements.txt开发文件说明
start.py启动文件

在这里插入图片描述

2.对象功能分析

管理员:

  1. 注册
  2. 登录
  3. 创建课程
  4. 创建讲师
  5. 创建学校

讲师:

  1. 登录
  2. 查看教授课程
  3. 选择教授课程
  4. 讲师查看课程的学生
  5. 讲师课程评分

学生:

  1. 登录
  2. 注册
  3. 选择课程
  4. 查看成绩
  5. 选择学校

二、开发环境及其版本

没有写版本的对应是python3.7的

开发环境版本
python3.7
json
sys
os
hashlib
pickle

三、db包

在这里插入图片描述
db_handler.py


from conf import settings
import os
import pickle


def save_obj(obj):
    # 1.先获取当前对象所载的文件夹路径
    file_path = os.path.join(
        settings.DB_DIR, obj.__class__.__name__
    )
    # 2.判断当前路径是否存在 不存在自动创建
    if not os.path.exists(file_path):
        os.mkdir(file_path)
    # 3.存在则拼接对象文件路径
    obj_file_path = os.path.join(file_path, obj.name)
    with open(obj_file_path, 'wb') as f:
        pickle.dump(obj, f)


def get_obj(cls, name):
    # 直接拼接对象的完整路径
    obj_file_path = os.path.join(
        settings.DB_DIR, cls.__name__, name
    )
    if os.path.exists(obj_file_path):
        with open(obj_file_path,'rb') as f:
            obj = pickle.load(f)
            return obj

def get_objs(cls):
    obj_file_path = os.path.join(
        settings.DB_DIR, cls.__name__
    )
    dirs = os.listdir(obj_file_path)
    if len(dirs) > 0:
        res = []
        for dir in dirs:
            file = os.path.join(obj_file_path, dir)
            with open(file, 'rb') as f:
                obj = pickle.load(f)
                res.append(obj)
        return res
    return []

if __name__ == '__main__':
    pass

models.py

from db import db_handler

class fa:
    def save(self):
        db_handler.save_obj(self)

    @classmethod
    def get_obj(cls, name):
        return db_handler.get_obj(cls, name)  # 这个方法将来不止一种角色使用

class Admin(fa):
    def __init__(self, name, pwd):
        self.name = name
        self.pwd = pwd
        self.is_identity = "superuser"
        # 只要代码能运行到对象实例化 那么肯定要保存
        self.save()  # 直接自动保存



class Course(fa):
    def __init__(self, name, classTeacher, school):
        self.name = name
        self.classTeacher = classTeacher
        self.school = school
        self.save()

    # 查找学生是否已加入学校
    def get_no_teacher(self):
        if self.classTeacher == "":
            return True
        return False

    @classmethod
    def get_courses(self):
        return db_handler.get_objs(self)


class Teacher(fa):
    def __init__(self, name, tPassWord, tUserName):
        self.tUserName = tUserName
        self.tPassWord = tPassWord
        self.name = name
        self.is_identity = "teacher"
        self.save()

class School(fa):
    def __init__(self, name, address, superuser):
        self.name = name
        self.address = address
        self.superuser = superuser
        self.courses = []
        self.save()

    @classmethod
    def get_schools(self):
        return db_handler.get_objs(self)

    # 为学校开设课程
    def insert_course(self, course):
        self.courses.append(course)
        self.save()

class Student(fa):
    def __init__(self, username, password, sname):
        self.name = username
        self.sname = sname
        self.password = password
        self.choose_courses = {}
        self.school = ""
        self.is_identity = "student"
        self.save()

    # 修改学生对应课程分数
    def update_course_score(self, course, score):
        self.choose_courses[course] = score
        self.save()

    # 查看该学生是否有对应课程
    def is_course_student(self, course):
        if course in self.choose_courses:
            return True
        return False

    # 查看学生是否加入学校
    def has_school(self):
        if self.school == "":
            return True
        return False

    # 为学生添加学校
    def insert_school(self, school):
        self.school = school
        self.save()

    @classmethod
    def get_students(self):
        return db_handler.get_objs(self)


四、core包

src.py

from core import admin_view, teacher_view, student_view

module_dict = {
    '1': admin_view,
    '2': teacher_view,
    '3': student_view
}


def run():
    while True:
        print("""
        ==============选课系统=================
                    1.管理员视图
                    2.讲师视图
                    3.学员视图
        ======================================
        """)
        choice = input('请输入您想要执行的视图编号>>>:').strip()
        if choice in module_dict:
            module_name = module_dict.get(choice)
            module_name.run()
        else:
            print('暂无该视图')

admin_view.py

from interface import admin_interface
from lib.common import is_login,public_login

def register():
    # 1.获取用户数据
    name = input('请输入您的用户名>>>:').strip()
    pwd = input('请输入您的密码>>>:').strip()
    confirm_pwd = input('请确认密码>>>:').strip()
    # 2.判断密码是否一致(逻辑太简单 直接在展示层做即可)
    if not pwd == confirm_pwd:
        print('两次密码不一致')
        return
    # 3.直接调用注册接口
    flag, msg = admin_interface.register_interface(name, pwd)
    print(msg)


def login():
    public_login("admin")

@is_login("admin")
def create_course():
    print('管理员创建课程')
    className = input("请输入课程名:").strip()
    classTeacher = input("请输入授课讲师(可为空):").strip()
    school = input("请输入所属学校:").strip()
    flag, msg = admin_interface.create_course_interface(className, classTeacher, school)
    print(msg)

@is_login("admin")
def create_teacher():
    print('管理员创建讲师')
    tUserName = input("请输入讲师账号用户名:").strip()
    tPassWord = input("请输入讲师账号密码:").strip()
    tName = input("请输入讲师名字:").strip()
    flag, msg = admin_interface.create_teacher_interface(tUserName, tPassWord, tName)
    print(msg)

@is_login("admin")
def create_school():
    print('管理员创建学校')
    schoolName = input("请输入学校名字:").strip()
    schoolAddress = input("请输入学校地址").strip()
    flag, msg = admin_interface.create_school_interface(schoolName, schoolAddress)
    print(msg)


func_dict = {
    '1': register,
    '2': login,
    '3': create_course,
    '4': create_teacher,
    '5': create_school,
}


def run():
    while True:
        print("""
                ==============管理员视图=================
                1.注册
                2.登录
                3.创建课程
                4.创建讲师
                5.创建学校
                ======================================
                """)
        choice = input('请输入您想要执行的视图编号>>>:').strip()
        if choice == 'q': return  # 返回上一层功能选择
        if choice in func_dict:
            func_name = func_dict.get(choice)
            func_name()
        else:
            print('暂无该功能编号')


student_view.py

from interface import student_interface
from lib.common import is_login,public_login
from  db import models
from lib import common

def register():
    print('学员注册功能')
    username = input("请输入用户名:").strip()
    password = input("请输入密码:").strip()
    password1 = input("请再次输入密码:").strip()
    sname = input("请输入姓名:").strip()
    if not password == password1:
        print('两次密码不一致')
        return
    flag, msg = student_interface.register_interface(username, password, sname)
    print(msg)

def login():
    public_login("student")

@is_login("student")
def select_school():
    print('学员选择学校')
    scobjs = models.School.get_schools()
    print("可加入学校:")
    for scobj in scobjs:
        print(scobj.name)
    school = input("请输入要加入的学校:").strip()
    flag, msg = student_interface.select_school_interface(school)
    print(msg)

@is_login("student")
def select_course():
    print('学员选择课程')
    stobj = models.Student.get_obj(common.get_cookie_username())
    flag = stobj.has_school()
    if flag:
        print("请先加入学校再选课")
    else:
        scobj = models.School.get_obj(stobj.school)
        print(f"{scobj.name}可申请学习的课程:")
        for i in scobj.courses:
            print(i)
        course_name = input("请输入申请的课程:").strip()
        flag1, msg1 = student_interface.select_course_interface(course_name)
        print(msg1)

@is_login("student")
def check_score():
    print('学员查看分数')
    flag, msg = student_interface.check_score_interface()
    if flag:
        for i in msg.items():
            print("课程:%s,成绩:%s"%(i[0], i[1]))
    else:
        print(msg)


func_dict = {
    '1': register,
    '2': login,
    '3': select_school,
    '4': select_course,
    '5': check_score
}


def run():
    while True:
        print("""
                ==============学员视图=================
                1.注册
                2.登录
                3.学员选择学校
                4.学员选择课程
                5.学员查看分数
                ======================================
                """)
        choice = input('请输入您想要执行的视图编号>>>:').strip()
        if choice == 'q': return  # 返回上一层功能选择
        if choice in func_dict:
            func_name = func_dict.get(choice)
            func_name()
        else:
            print('暂无该功能编号')

teacher_view.py

from interface import teacher_interface
from lib.common import is_login,public_login
from db import models

def login():
    public_login("teacher")


@is_login("teacher")
def check_teach_course():
    print('讲师查看课程')
    flag, msg = teacher_interface.check_teach_course_interface()
    print(msg)

@is_login("teacher")
def select_teach_course():
    print('讲师选择课程')
    courses = models.Course.get_courses()
    print("所有可申请教授的课程(为空说明没有):")
    for course in courses:
        if course.get_no_teacher():
            print(course.school + "开设的" + course.name)
    course_name = input("请输入申请教授的课程名:").strip()
    flag, msg = teacher_interface.select_teach_course_interface(course_name)
    print(msg)

@is_login("teacher")
def check_course_student():
    print('讲师查看课程的学生')
    print("可查看的课程:")
    f, m = teacher_interface.check_teach_course_interface()
    print(m)
    course_name = input("请输入要查看的课程名字:").strip()
    flag, msg = teacher_interface.check_course_student_interface(course_name)
    print(msg)

@is_login("teacher")
def update_student_score():
    print('讲师设置分数')
    flag, msg = teacher_interface.check_teach_course_interface()
    if not flag:
        print("没有你教授的课,无法给学生打分")
    else:
        print(msg)
        course_name = input("请输入你要打分的课程:").strip()
        flag1, msg1 = teacher_interface.check_course_student_interface(course_name)
        if not flag1:
            print("该课程还没选课学生")
        else:
            print(msg1)
            student = input("请输入要打分的学生:").strip()
            score = input("请输入分数:").strip()
            flag2, msg2 = teacher_interface.update_student_score_interface(student, course_name, score)
            print(msg2)




func_dict = {
    '1': login,
    '2': check_teach_course,
    '3': select_teach_course,
    '4': check_course_student,
    '5': update_student_score
}


def run():
    while True:
        print("""
                ==============讲师视图=================
                1.登录
                2.查看课程
                3.选择课程
                4.讲师查看课程的学生
                5.设置分数
                ======================================
                """)
        choice = input('请输入您想要执行的视图编号>>>:').strip()
        if choice == 'q': return  # 返回上一层功能选择
        if choice in func_dict:
            func_name = func_dict.get(choice)
            func_name()
        else:
            print('暂无该功能编号')



六、lib包

common.py

import hashlib

cookie = {}

def password_md5(password):
    md5 = hashlib.md5()
    md5.update(password.encode("utf8"))
    return md5.hexdigest()

def password_md5_super(password):
    md5 = hashlib.md5("super".encode("utf8"))
    md5.update(password.encode("utf8"))
    return md5.hexdigest()

def add_cookie(name, identity):
    cookie["username"] = name
    cookie["is_identity"] = identity

def get_cookie_username():
    return cookie["username"]

def get_cookie_is_identity():
    return cookie["is_identity"]

def is_has_cookie():
    if len(cookie) == 0:
        return False
    return True

def is_login(user_type):
    def outer(func):
        def inner(*args, **kwargs):
            from core import admin_view,student_view,teacher_view
            l = {
                "admin":admin_view,
                "student":student_view,
                "teacher":teacher_view
            }
            if not is_has_cookie():
                print(f"你需要登录才能使用,{user_type}的功能")
                l[user_type].login()
            else:
                res = func(*args, **kwargs)
                return res
        return inner
    return outer

def public_login(type):
    from interface import student_interface,teacher_interface,admin_interface
    l = {
        "admin":admin_interface,
        "teacher":teacher_interface,
        "student":student_interface
    }
    print(f'{type}登录功能')
    username = input("请输入账号:").strip()
    password = input("请输入密码:").strip()
    flag, msg = l[type].login_interface(username, password)
    print(msg)



七、interface包

admin_interface.py

from db import models
from lib import common


def register_interface(name, pwd):
    # 1.校验用户名是否已存在
    obj = models.Admin.get_obj(name)
    if obj:
        return False, f'用户名{name}已存在'
    # 2.调用接口保存数据  创建管理员对象并保存
    models.Admin(name, common.password_md5_super(pwd))
    return True, f'{name}注册成功'


def login_interface(name, pwd):
    # 1.获取用户数据
    user_obj = models.Admin.get_obj(name)
    if not user_obj:
        return False, '用户名不存在'
    # 2.校验用户数据
    if user_obj.pwd == common.password_md5_super(pwd):
        common.add_cookie(name, user_obj.is_identity)
        return True, f'{name}登录成功'
    return False, '密码错误'

def create_course_interface(className, classTeacher, school):
    obj = models.Course.get_obj(className)
    if obj:
        return False, f'{className}课程已存在'
    if classTeacher != '':
        teacher = models.Teacher.get_obj(classTeacher)
        if not teacher:
            return False, f'{classTeacher}讲师不存在'
    if not models.School.get_obj(school):
        return False, f"{school}不存在"
    models.Course(className, classTeacher, school)
    sobj = models.School.get_obj(school)
    sobj.insert_course(className)
    return True, f'{school}下的{className}课程创建成功'

def create_teacher_interface(tUserName, tPassWord, tName):
    obj = models.Teacher.get_obj(tUserName)
    if obj:
        return False, f'用户名:{tUserName},{tName}讲师已存在'
    models.Teacher(tUserName, common.password_md5(tPassWord), tName)
    return True, f'用户名:{tUserName},讲师名字:{tName}创建成功'

def create_school_interface(schoolName, schoolAddress):
    obj = models.School.get_obj(schoolName)
    if obj:
        return False, f'{schoolName}学校已存在'
    models.School(schoolName, schoolAddress, common.get_cookie_username())
    return True, f'{schoolName}学校创建成功'

student_interface.py

from db import models
from lib import common

def register_interface(username, password, sname):
    obj = models.Student.get_obj(username)
    if obj:
        return False, f'用户名{username}已存在'
    models.Student(username, common.password_md5(password), sname)
    return True, f'{username}注册成功'

def login_interface(username, password):
    obj = models.Student.get_obj(username)
    if not obj:
        return False, "用户名或密码错误"
    if obj.password != common.password_md5(password):
        return False, "用户名或密码错误"
    common.add_cookie(obj.name, obj.is_identity)
    return True, f'{obj.sname}学生登陆成功'

def select_school_interface(school):
    sobj = models.School.get_obj(school)
    stname = common.get_cookie_username()
    stobj = models.Student.get_obj(stname)
    if not sobj:
        return False, f"{school}不存在"
    if not stobj.has_school():
        return False, f"已选择{stobj.school},不可再次选择"
    stobj.insert_school(school)
    return True, f"成功加入{school}"


def select_course_interface(course_name):
    cobj = models.Course.get_obj(course_name)
    stobj = models.Student.get_obj(common.get_cookie_username())
    choose_course = stobj.choose_courses
    if not cobj:
        return False, f"{course_name}课程不存在"
    if len(choose_course) == 0:
        stobj.choose_courses[course_name] = 0
        stobj.save()
        return True, f"{course_name}课程学习申请成功"
    else:
            if course_name in choose_course :
                return False, f"{course_name}已经申请学习,请勿重复"
            else:
                stobj.choose_courses[course_name] = 0
                stobj.save()
                return True, f"{course_name}课程学习申请成功"

def check_score_interface():
    choose_course = models.Student.get_obj(common.get_cookie_username()).choose_courses
    if len(choose_course) == 0:
        return False, "你还没有课程,请先申请学习课程"
    return True, choose_course


teacher_interface.py

from db import models
from lib import common

def login_interface(tUserName, tPassWord):
    obj = models.Teacher.get_obj(tUserName)
    if not obj:
        return False, "用户名或密码错误"
    if obj.tPassWord != common.password_md5(tPassWord):
        return False, "用户名或密码错误"
    common.add_cookie(obj.name, obj.is_identity)
    return True, f'{obj.name}讲师登陆成功'

def check_teach_course_interface():
    courses = models.Course.get_courses()
    obj = common.cookie["username"]
    res = f"{obj}讲师的课程:"
    for course in courses:
        if course.classTeacher == obj:
           res += course.name + "\n"
    return True, res

def select_teach_course_interface(course_name):
    courses = models.Course.get_courses()
    obj = common.cookie["username"]
    for course in courses:
        if course.name == course_name:
            if course.classTeacher == '':
                course.classTeacher = obj
                models.Course.save(course)
                return True, f"你教授课程{course.name}成功"
    return False, f'你教授课程{course.name}不存在或已有授课讲师'

def check_course_student_interface(course_name):
    cobj = models.Course.get_obj(course_name)
    students = models.Student.get_students()
    if not cobj:
        return False, f"没有{course_name}课程"
    if not cobj.classTeacher == common.get_cookie_username():
        return False, f"不是{course_name}课任老师,无法查看"
    i = 0
    res = ""
    for student in students:
        if student.is_course_student(course_name):
            res += student.name + "\n"
    return True, f"{course_name}学生: \n" + res

def update_student_score_interface(student, course, score):
    if not models.Student.get_obj(student):
        return False, f"{student}学生不存在"
    if not models.Course.get_obj(course):
        return False, f"{course}课程不存在"
    if not score.isdigit():
        return False, "分数必须是整数"
    obj = models.Student.get_obj(student)
    obj.update_course_score(course, score)
    return True, f"{student}{course}课程分数为:{score}分,评分成功"




七、conf包

setting.py

import os
# 路径信息一般都不会改变 所以建议放在配置文件中
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
DB_DIR = os.path.join(BASE_DIR, 'db')


八、start

start.py

import os
import sys

# 添加sys.path
sys.path.append(os.path.dirname(__file__))

from core import src

if __name__ == '__main__':
    src.run()

总结

目前项目划分比较合理,将整个项目分为了三个部分表现层、业务逻辑层、数据持久层,由于没有使用前端和数据库只能大致模拟这样的效果,项目分割后方便协作开发、产生异常时也不会项目影响,开发项目时使用了单例设计模式,用以节省项目资源,本项目在于练习面向对象的使用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值