【python练习】选课系统(基于面向对象的)

程序功能

本程序模拟实现了基于面向对象编写的一个选课系统程序:

1. 可以通过管理员创建学校、老师、学生、班级、课程:	
2. 老师可以在管理员注册之后登陆,查看自己的信息,可以选择学校、班级、课程、为学生打分
3. 学生可以注册、登陆、查看自己的信息,可以缴纳学费

测试:

数据为空,需要手动创建添加,导入了一个prettytable包
1.需要先进入管理员,创建学校、老师、学生、班级、课程(需要先船舰课程,后创建班级)
2. 创建完老师,会自动注册(账号为手机号,密码为后6位)
3. 老师需要登陆后选择学校、班级(课程)

程序结构:

选课系统/
└── ├── README
    ├── bin # 选课系统 执行文件 目录
    │   ├── init.py
    │   └── 选课系统.py # ATM 管理端
    ├── conf # 配置文件
    │   ├── init.py
    │   └── settings.py
    ├── core # 主要程序逻辑都
    │   ├── init.py
    │   ├── db_handler.py   # 数据的存储和加载
    │   ├── logger.py       # 日志记录模块
    │   ├── login.py   	    # 登陆模块
    │   ├── main.py         # 主逻辑交互程序
    │   └── register.py     # 注册模块
    ├── db #用户数据存储的地方
    │   ├── accounts # 存放登陆信息
    │   └── data # 分别存放课程、班级、学校、老师、学生的文件夹
    │       ├── courses # 课程
    │       ├── grades # 班级
    │       ├── schools # 学校
    │       ├── students # 学生
    │       └── teachers # 老师
    └── logs #日志目录
        ├── init.py
        └── access.log #用户访问和操作的相关日志

 


选课系统/bin/选课系统.py 
# Author:q1.ang

import os
import sys

BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
print(BASE_PATH)
sys.path.append(BASE_PATH)

from core import main

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

选课系统/conf/settings.py 
# Author:q1.ang
import os
import sys
import logging

sep = os.sep
BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DB_PATH = '%s%sdb' % (BASE_PATH, sep)

LOG_LEVEL = logging.INFO
LOG_TYPES = {
    'transaction': 'transaction.log',
    'access': 'access.log'
}

# 两个tab的长度
tab = '    ' * 2

accounts_file = ''

schools_file = 'schools'
teachers_file = 'teachers'
grades_file = 'grades'
course_file = 'courses'
students_file = 'students'

pretty_table_school = [' ', '学校', '地址', '班级', '课程']
pretty_table_teacher_student = [' ', '姓名', '年龄', '性别', '电话号码', '学校', '班级', '课程']
pretty_table_grades = [' ', '班级', '学校', '讲师', '课程', '学员']
pretty_table_courses = [' ', '课程', '周期', '价格', '/']
pretty_table_student = [' ', '姓名', '年龄', '性别', '电话号码', '学校', '班级', '课程', '分数']


# 为Admin.info(*args)为Admin.del_instance(*args)传值
args = {
    '1': [schools_file, pretty_table_school],
    '2': [teachers_file, pretty_table_teacher_student],
    '3': [grades_file, pretty_table_grades],
    '4': [course_file, pretty_table_courses],
    '5': [students_file, pretty_table_teacher_student],
}

选课系统/core/db_handle.py
import os
import pickle
from conf import settings

tab = settings.tab

# data = {'name': 'LuffySchool', 'address': '北京'}
#
# path = '{base_path}{sep}db{sep}data{sep}schools{sep}{file_name}.pkl'.format(
#     base_path=settings.BASE_PATH, sep=settings.sep, file_name='15667038228')


def save(data, file, file_name):
    path = '{base_path}{sep}db{sep}data{sep}{file}{sep}{name}.pickle'.format(
        base_path=settings.BASE_PATH, sep=settings.sep, file=file, name=file_name)

    with open(path, 'wb') as f:
        pickle.dump(data, f)


def read(file, file_name):
    path = '{base_path}{sep}db{sep}data{sep}{file}{sep}{name}.pickle'.format(
        base_path=settings.BASE_PATH, sep=settings.sep, file=file, name=file_name)

    with open(path, 'rb') as f:
        return pickle.load(f)



def read_dir(file):
    path = '{base_path}{sep}db{sep}data{sep}{file}'.format(
        base_path=settings.BASE_PATH, sep=settings.sep, file=file)
    return os.listdir(r'%s' % path)

def del_file(file, file_name):
    path = '{base_path}{sep}db{sep}data{sep}{file}{sep}{name}.pickle'.format(
        base_path=settings.BASE_PATH, sep=settings.sep, file=file, name=file_name)
    os.remove(path)
    print('删除成功')
选课系统/core/logger.py
import logging
from conf import settings

def logger(log_type):
    # 创建Logger
    logger = logging.getLogger(log_type)
    logger.setLevel(logging.INFO)
    # 创建handler
    ch = logging.StreamHandler()
    ch.setLevel(logging.INFO)

    path = '%s\\logs\\%s' % (settings.BASE_PATH,settings.LOG_TYPES[log_type])
    fh = logging.FileHandler(path)
    fh.setLevel(logging.INFO)
    # 定义formatter
    formatter = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s  %(message)s')
    # 绑定formatter
    ch.setFormatter(formatter)
    fh.setFormatter(formatter)
    # 添加handle对象
    # logger.addHandler(ch)
    logger.addHandler(fh)

    return logger
选课系统/core/login.py
# Author:q1.ang
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import pickle
from core import logger

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


def authentication():
    '''
    用户认证程序
    :return:登陆成功返回True
    '''

    acc = ''
    auth_list = []  # 用于存放每次输入的用户名
    print('- - - Login - - -')
    while auth_list.count(acc) < 3:  # 当相同的用户名登陆失败3次,跳出循环
        acc = input('Account:').strip()
        pwd = input('Password:').strip()
        path = '%s\\db\\accounts\\%s.pickle' % (BASE_PATH, acc)  # 用户信息存放路径
        if os.path.isfile(path):  # 用户名是否存在
            with open(path, 'rb') as f:
                acc_data = pickle.load(f)  # 读取信息
                if acc_data['password'] == pwd:
                    print('Login success !')
                    logger.logger('access').info('Login %s' % acc)
                    return acc
                else:
                    auth_list.append(acc)
                    logger.logger('access').info('Login %s - Password Error' % acc)
                    print('The password is error,you have %s times' % (3 - auth_list.count(acc)))
        else:
            auth_list.append(acc)
            print('The account is not exist...you have %s times' % (3 - auth_list.count(acc)))
选课系统/core/main.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re
from conf import settings
from core import db_handle
from core import register
from core import login
from prettytable import PrettyTable


tab = settings.tab


class School(object):

    def __init__(self, name, address):
        self.name = name
        self.address = address
        self.grade = []
        self.course = []
        self.student = []
        self.save_name = self.name + '_' + self.address

    def info(self, num, table):
        table.add_row(
            [num, self.name, self.address
                , ','.join(list(map(lambda x: x.grade, self.grade)))
                , ','.join(list(map(lambda x: x.course, self.course)))])

    def create_grade(self, grade):
        self.grade.append(Grade(grade))

    def create_course(self, course, period, price):
        self.course.append(Course(course, period, price))

    def bind_student(self):
        pass


class People(object):

    def __init__(self, name, age, sex, phone):
        self.name = name
        self.age = age
        self.sex = sex
        self.phone = phone
        self.save_name = self.phone


class Teachers(People):
    db_file = settings.teachers_file

    def __init__(self, name, age, sex, phone):
        super(Teachers, self).__init__(name, age, sex, phone)
        self.save_name = self.phone
        self.school = School('', '')
        self.grade = []
        self.course = []

    def info(self, num, table):
        table.add_row(
            [num, self.name
                , self.age, self.sex
                , self.phone, self.school.name + ' ' + self.school.address
                , ','.join(list(map(lambda x: x.grade, self.grade)))
                , ','.join(list(map(lambda x: x.course, self.course)))])

    def bind_instance(self, bind_type, *args):
        """
        绑定实例
        :param bind_type: 需要绑定的类型
        :param args: 传入筛选后的实例
        :return: 再次筛选后的实例
        """
        if len(args) > 0:  # 如果传入筛选后的实例

            if bind_type == '3':  # '3'为班级
                table = PrettyTable(settings.pretty_table_grades)  # 实例化PrettyTable
                for index, obj in enumerate(args[0].grade, 1):  # args[0].grade为筛选后实例的grade参数
                    obj.info(index, table)  # 调用实例的info方法
                print(table)  # 打印输出
                list_data = list(map(lambda x: x.grade, args[0].grade))  # 生成一个由文件名组成的列表

        else:  # 没有传入筛选后的实例,调用Admin.info_instance()打印输出并返回由文件名组成的列表
            list_data = Admin.info_instance(settings.args[bind_type][0], settings.args[bind_type][1])

        while True:
            inp = input('输入要关联的序号[q返回]:').strip()
            if inp == 'q':
                break
            elif inp.isdigit() and 0 < abs(int(inp)) <= len(list_data):
                instance = db_handle.read(settings.args[bind_type][0], list_data[int(inp) - 1])  # 读取需要管关联的实例
                if bind_type == '1':
                    self.school = instance  # 此时instance为School的一个实例,self.school在每次实例Teacher的时候都会赋值
                    instance.teacher = self.name + ' ' + self.phone  # 此时instance为Grade的一个实例
                    if db_handle.save(instance, settings.schools_file, instance.save_name) != 0:
                        print('数据更新成功')

                elif bind_type == '3':
                    self.grade.append(instance)  # 为自己绑定班级
                    self.course.append(instance.course)
                    instance.teacher = self.name+' '+self.phone  # 此时instance为Grade的一个实例
                    if db_handle.save(instance, settings.grades_file, instance.save_name) != 0:
                        print('数据更新成功')

                print('关联成功')
                return instance
            else:
                print('输入错误')


class Students(People):
    db_file = settings.students_file

    def __init__(self, name, age, sex, phone):
        super(Students, self).__init__(name, age, sex, phone)
        self.save_name = self.phone
        # self.fees = []  # 学费,0代表未交学费
        self.score = 0
        self.grade = []
        self.course = []

    def info(self, num, table):
        table.add_row(
            [num, self.name
                , self.age, self.sex
                , self.phone, self.school.name + ' ' + self.school.address
                , ','.join(list(map(lambda x: x.grade, self.grade)))
                , ','.join(list(map(lambda x: x.course, self.course)))
                , self.score])

    def bind_instance(self, bind_type, *args):
        """
        绑定实例
        :param bind_type: 需要绑定的类型
        :param args: 传入筛选后的实例
        :return: 再次筛选后的实例
        """
        if len(args) > 0:  # 如果传入筛选后的实例

            if bind_type == '3':  # '3'为班级
                table = PrettyTable(settings.pretty_table_grades)  # 实例化PrettyTable
                for index, obj in enumerate(args[0].grade, 1):  # args[0].grade为筛选后实例的grade参数
                    obj.info(index, table)  # 调用实例的info方法
                print(table)  # 打印输出
                list_data = list(map(lambda x: x.grade, args[0].grade))  # 生成一个由文件名组成的列表

        else:  # 没有传入筛选后的实例,调用Admin.info_instance()打印输出并返回由文件名组成的列表
            list_data = Admin.info_instance(settings.args[bind_type][0], settings.args[bind_type][1])

        while True:
            inp = input('输入要关联的序号[q返回]:').strip()
            if inp == 'q':
                break
            elif inp.isdigit() and 0 < abs(int(inp)) <= len(list_data):
                instance = db_handle.read(settings.args[bind_type][0], list_data[int(inp) - 1])  # 读取需要管关联的实例
                if bind_type == '1':
                    self.school = instance  # 此时instance为School的一个实例,self.school在每次实例Teacher的时候都会赋值
                    # 更新instance
                    instance.student.append(self)  # 此时instance为School的一个实例
                    if db_handle.save(instance, settings.schools_file, instance.save_name) != 0:
                        print('数据更新成功')

                elif bind_type == '3':
                    self.grade.append(instance)  # 为自己绑定班级
                    self.course.append(instance.course)  # 绑定课程
                    # self.fees.append(instance.course.price+' '+instance.course.price)  # 添加课程学费
                    # 更新instance
                    instance.student.append(self)  # 此时instance为Grade的一个实例
                    if db_handle.save(instance, settings.grades_file, instance.save_name) != 0:
                        print('数据更新成功')

                print('关联成功')
                return instance
            else:
                print('输入错误')


class Course(object):

    def __init__(self, course, period, price):
        self.course = course
        self.period = period
        self.price = price
        self.fees_flag = ' '
        self.save_name = self.course

    def info(self, num, table):
        table.add_row([num, self.course, self.period, self.price, self.fees_flag])


class Grade(object):

    def __init__(self, grade):
        self.grade = grade
        self.teacher = ''
        self.course = ''
        self.student = []
        self.save_name = self.grade

    def info(self, num, table):
        table.add_row(
            [num, self.grade
                , self.school.name + ' ' + self.school.address
                , self.teacher, self.course.course
                , ','.join(list(map(lambda x: x.name, self.student)))])


class Admin(object):

    def __init__(self, admin):
        self.admin = admin
        self.menu = {
            '1-学校管理': {
                '1-浏览学校': 'info_instance',
                '2-创建学校': 'create_school',
                '3-删除学校': 'del_instance',
                'q-退出': 'quit'
            },
            '2-讲师管理': {
                '1-浏览讲师': 'info_instance',
                '2-创建讲师': 'create_teacher',
                '3-删除讲师': 'del_instance',
                'q-退出': 'quit'
            },
            '3-班级管理': {
                '1-浏览班级': 'info_instance',
                '2-创建班级': 'create_grades',
                '3-删除班级': 'del_instance',
                'q-退出': 'quit'
            },
            '4-课程管理': {
                '1-浏览课程': 'info_instance',
                '2-创建课程': 'create_course',
                '3-删除课程': 'del_instance',
                'q-退出': 'quit'
            },
            'q-退出': 'quit'
        }

    def interactive(self):
        while True:
            # 第一级菜单显示
            for i in self.menu.keys():
                print(i, end='   ')
            inp = input('\n>>>').strip()
            # 第二级菜单显示
            if inp.isdigit():
                if 0 < int(inp) <= len(self.menu):
                    new_menu = list(self.menu.items())[int(inp) - 1][1]
                    for i1 in new_menu:
                        print(i1, end='  ')
                else:
                    print('\031[0;33m输入超出范围\033[0m')
                    continue
            elif inp == 'q':
                return
            else:
                print('\031[0;33m输入错误,重新输入\033[0m')
                continue

            inp1 = input('\n>>>').strip()
            # 选择跳转
            if inp1.isdigit():
                inp1 = int(inp1)
                if 0 < inp1 <= len(new_menu):
                    choose = list(new_menu.items())[inp1 - 1][1]
                    getattr(Admin(self.admin), choose)(settings.args[inp][0], settings.args[inp][1])
            elif inp1 == 'q':
                continue
            else:
                print('\031[0;33m输入错误,重新输入\033[0m')

    @staticmethod
    def info_instance(*args):
        instance_file = args[0]  # 需要遍历的文件夹名称
        pretty_table_instance = args[1]  # 打印表格表头形式
        table = PrettyTable(pretty_table_instance)  # 实例化PrettyTable
        file_list = db_handle.read_dir(instance_file)  # 返回文件夹内文件名的列表
        num = 1  # b表格第一列的序号
        list_data = []  # 保存文件的实例,用于返回
        for i in file_list:
            instance = db_handle.read(instance_file, i.split('.')[0])
            instance.info(num, table)
            list_data.append(instance.save_name)
            num += 1
        print(table)
        return list_data

    def del_instance(self, *args):
        instance_file = args[0]
        pretty_table_instance = args[1]
        list_data = self.info_instance(instance_file, pretty_table_instance)
        while True:
            inp = input('\033[0;32m输入要删除的序号[q返回]:\033[0m').strip()
            if inp == 'q':
                break
            elif inp.isdigit() and 0 < abs(int(inp)) <= len(list_data):
                db_handle.del_file(instance_file, list_data[int(inp) - 1])
                break
            else:
                print('\033[0;31m输入错误\033[0m')

    def create_school(self, *args):
        name = input('\033[0;32m学校:\033[0m').strip()
        address = input('\033[0;32m地址[北京\上海]:\033[0m').strip()
        # 实例化学校,保存对象
        school = School(name, address)
        if db_handle.save(school, settings.schools_file, school.save_name) != 0:
            print('\033[0;33m创建成功\033[0m')

    def create_teacher(self, *args):
        print('\033[0;33m- - - 填写资料 - - - \033[0m')
        while True:
            name = input('\033[0;32m姓名[中文/英文]:\033[0m').strip()
            if not name.isalpha():
                print('\033[0;31m格式错误[只能为中文/英文]\033[0m')
                continue
            else:
                break
        while True:
            age = input('\033[0;32m年龄[1~99数字]:\033[0m').strip()
            if age.isdigit() and (len(age) <= 2):
                break
            else:
                print('\033[0;31m格式错误[1~99数字]\033[0m')
                continue
        while True:
            sex = input('\033[0;32m性别[男/女]:\033[0m').strip()
            if sex == '' or sex == '':
                break
            else:
                print('\033[0;31m格式错误[男/女]\033[0m')
                continue

        if len(args) < 3:
            while True:
                phone = input('\033[0;32m电话号码[11位数字]:\033[0m').strip()
                if not re.fullmatch('\d{11}', phone):
                    print('\033[0;31m格式错误[11位数字]\033[0m')
                    continue
                else:
                    break
        else:
            phone = args[3]

        # 实例化老师/学员,绑定学校
        instance = Teachers(name, age, sex, phone)
        # print('选择学校:')
        # filter_instance = instance.bind_instance('1')
        # print('选择班级:')
        # instance.bind_instance('3', filter_instance)

        if db_handle.save(instance, instance.db_file, phone) != 0:
            print('\033[0;33m创建成功\033[0m')
        register.register(phone)
        print('\033[0;36m账号为手机号,密码为手机号后6位\033[0m')

    def create_grades(self, *args):
        list_data = self.info_instance(settings.schools_file, settings.pretty_table_school)
        while True:
            inp = input('\033[0;32m请选择学校:\033[0m').strip()
            if inp.isdigit() and 0 < abs(int(inp)) <= len(list_data):
                school = db_handle.read(settings.schools_file, list_data[int(inp) - 1])  # school.address,是一个参数
                break
            else:
                print('\033[0;31m输入错误\033[0m')
        # 打印筛选后的school
        table = PrettyTable(settings.pretty_table_courses)  # 实例化PrettyTable
        for index, obj in enumerate(school.course, 1):  # 筛选后实例的course参数
            obj.info(index, table)  # 调用实例的info方法
        print(table)  # 打印输出

        list_data = list(map(lambda x: x.course, school.course))  # 生成一个由文件名组成的列表
        while True:
            inp = input('\033[0;32m请绑定课程:\033[0m').strip()
            if inp == 'q':
                return
            if inp.isdigit() and 0 < abs(int(inp)) <= len(list_data):
                course = db_handle.read(settings.course_file, list_data[int(inp) - 1])  # course.course,是一个参数
                break
            else:
                print('\033[0;31m输入错误\033[0m')

        while True:
            grade = input('\033[0;32m班级[数字]:\033[0m').strip()
            if grade == 'q':
                return

            if grade.isdigit():
                # 学校实例,保存对象
                school.create_grade(grade)  # 通过School()的实例创建班级
                school.grade[-1].school = school  # 为grade绑定学校信息,school.grade[-1]为Grade实例
                school.grade[-1].course = course  # 为grade绑定课程信息

                if db_handle.save(school.grade[-1], settings.grades_file, grade) != 0:
                    print('\033[0;33m创建成功\033[0m')
                if db_handle.save(school, settings.schools_file, school.save_name) != 0:
                    print('\033[0;33m数据更新成功\033[0m')
                    break
            else:
                print('\033[0;31m请输入数字\033[0m')

    def create_course(self, *args):
        list_data = self.info_instance(settings.schools_file, settings.pretty_table_school)
        while True:
            inp = input('\033[0;32m请选择学校[q返回]:\033[0m').strip()
            if inp == 'q':
                break
            elif inp.isdigit() and 0 < abs(int(inp)) <= len(list_data):
                school = db_handle.read(settings.schools_file, list_data[int(inp) - 1])
                break
            else:
                print('\033[0;31m输入错误\033[0m')
        while True:
            course = input('\033[0;32m课程:\033[0m').strip()
            if course.isalnum():
                if course.lower() == 'go' and school.address == '上海':
                    break
                elif (course.lower() == 'python' or course.lower() == 'linux') and school.address == '北京':
                    break
                else:
                    print('\033[0;31m%s没有开设%s课程\033[0m' % (school.address, course))
                    continue
            else:
                print('\033[0;31m输入错误\033[0m')

        period = input('\033[0;32m周期[数字、月]:\033[0m').strip()
        price = input('\033[0;32m价格[数字]:\033[0m').strip()

        if period.isdigit() and price.isdigit():
            # 实例化学校,保存对象
            school.create_course(course, period, price)
            school.course[-1].school = school
            if db_handle.save(school.course[-1], settings.course_file, course) != 0:
                print('\033[0;33m创建成功\033[0m')
            if db_handle.save(school, settings.schools_file, school.save_name) != 0:
                print('\033[0;33m数据更新成功\033[0m')
        else:
            print('\033[0;31m请输入数字\033[0m')


class TeacherInterface(object):
    def teacher_interactive(self):
        acc = login.authentication()
        if acc.isdigit():
            instance = db_handle.read(settings.teachers_file, acc)
            while True:
                print('\n1-浏览信息   2-选择学校   3-选择班级  4-打分   q-退出')
                inp1 = input('>>>')
                if inp1 == '1':
                    table = PrettyTable(settings.pretty_table_teacher_student)  # 实例化PrettyTable
                    instance.info(1, table)  # 调用实例的info方法
                    print(table)  # 打印输出
                elif inp1 == '2':
                    print('选择学校:')
                    instance.bind_instance('1')
                    db_handle.save(instance, settings.teachers_file, acc)
                    continue
                elif inp1 == '3':
                    print('选择班级:')
                    instance.bind_instance('3', instance.school)
                    db_handle.save(instance, settings.teachers_file, acc)
                    continue
                elif inp1 == '4':
                    self.give_score()
                elif inp1 == 'q':
                    return
                else:
                    print('输入错误')
            else:
                return
    def give_score(self):
        # 获得学员的实例列表
        instance_list = Admin.info_instance(settings.students_file, settings.pretty_table_student)
        student = input('选择学生:').strip()
        if student == 'q':
            return
        elif student.isdigit() and 0 < abs(int(student)) <= len(instance_list):
            instance = db_handle.read(settings.args['5'][0], instance_list[int(student) - 1])  # 读取需要管关联的实例
            score = input('分数:')
            instance.score = score  # 此时instance为Student的一个实例
            if db_handle.save(instance, settings.students_file, instance.save_name) != 0:
                print('数据更新成功')


class StudentInterface(object):

    def student_interactive(self):
        while True:
            print('1-登陆   2-注册  q-退出')
            inp1 = input('>>>')
            if inp1 == '1':
                acc = login.authentication()
                if acc.isdigit():
                    instance = db_handle.read(settings.students_file, acc)
                    while True:
                        print('1-查看信息   2-缴纳学费  q-退出')
                        inp2 = input('>>>')
                        if inp2 == '1':
                            table = PrettyTable(settings.pretty_table_student)  # 实例化PrettyTable
                            instance.info(1, table)  # 调用实例的info方法
                            print(table)  # 打印输出
                        elif inp2 == '2':
                            table = PrettyTable(settings.pretty_table_courses)  # 实例化PrettyTable
                            for index, obj in enumerate(instance.course, 1):  # args[0].grade为筛选后实例的grade参数
                                obj.info(index, table)  # 调用实例的info方法
                            print(table)  # 打印输出

                            inp3 = input('输入要缴纳的课程[q退出]:').strip()
                            if inp3.isdigit() and 0 < int(inp3) <= len(instance.course):
                                instance.course[int(inp3)-1].fees_flag = '已缴纳'
                                db_handle.save(instance, settings.students_file, acc)
                                print('缴纳成功')
                            elif inp3 == 'q':
                                break
                            else:
                                print('输入错误')

                        elif inp2 == 'q':
                            break
                        else:
                            print('输入错误')

            elif inp1 == '2':
                phone = register.register()
                self.create_student(phone)
            elif inp1 == 'q':
                return
            else:
                print('输入错误')

    def create_student(self, phone):
        print('- - - 填写资料 - - -')
        while True:
            name = input('姓名[中文/英文]:').strip()
            if not name.isalpha():
                print('格式错误[只能为中文/英文]')
                continue
            else:
                break
        while True:
            age = input('年龄[1~99数字]:').strip()
            if age.isdigit() and (len(age) <= 2):
                break
            else:
                print('格式错误[1~99数字]')
                continue
        while True:
            sex = input('性别[男/女]:').strip()
            if sex == '' or sex == '':
                break
            else:
                print('格式错误[男/女]')
                continue

        # 实例化学员,绑定学校
        instance = Students(name, age, sex, phone)
        print('选择学校:')
        filter_instance = instance.bind_instance('1')
        print('选择班级:')
        instance.bind_instance('3', filter_instance)
        if db_handle.save(instance, instance.db_file, phone) != 0:
            print('创建成功')


def run():
    print('\033[0;33m%s- - - 欢迎来到课程管理系统 - - - \033[0m' % tab)
    while True:

        inp = input('''
        1. 管理员
        2. 讲师
        3. 学生
        - - - - - -
        >>>''').strip()

        if inp == '1':
            admin = Admin('admin')
            admin.interactive()
        elif inp == '2':
            teacher_interface = TeacherInterface()
            teacher_interface.teacher_interactive()
        elif inp == '3':
            student_interface = StudentInterface()
            student_interface.student_interactive()
选课系统/core/register.py
# Author:q1.ang
from conf import settings
import pickle
import re
import os

tab = settings.tab


def register(*args):
    print('- - - 注册账号 - - - ')
    if len(args) == 0:
        while True:
            acc = input('输入手机号:').strip()
            if not re.fullmatch('\d{11}', acc):
                print('格式错误[11位数字]')
                continue
            else:
                break
        while True:
            pwd = input('输入密码[大于6位的英文大小写和数字]:').strip()
            if len(pwd) < 6:
                print('密码应为大于6位的英文大小写和数字')
                continue
            else:
                break
    else:
        acc = args[0]
        pwd = args[0][-6:]  # 后六位,默认密码

    path = '{db_path}{sep}accounts{sep}{acc}.pickle'.format(
        db_path=settings.DB_PATH, sep=settings.sep, acc=acc)

    if os.path.isfile(path):
        cover_flag = input('账号已经存在,是否覆盖(Y/N)').strip()
        if cover_flag == 'N':
            return 0
        elif cover_flag == 'Y':
            pass
        else:
            print('输入错误')

    data = {
        'account': acc,
        'password': pwd
    }

    with open(path, 'wb') as f:
        pickle.dump(data, f)
    print('注册成功')
    return acc

选课系统/db/accounts/... 
选课系统/db/data/...

选课系统/logs/...
posted @ 2018-05-23 21:59  q1ang  阅读(313)  评论(0编辑  收藏  举报