Python+Mysql学生选课系统(附下载链接)

 

程序在python3.5.2下调试通过
mysql发行版本:5.7.24

法律允许范围内,作者保留所有权利!

项目相关文件可以在百度网盘下载,地址为

https://pan.baidu.com/s/1a9AU4E9lvVi0WJFM4nSxfA 
提取码:qp7l
/**********************************
@ author:    CSDN @WilliamCode
@ E-mail:    [email protected]
@ date:        2019-01-09
@ All Rights Reserved
@
@专业程序员,精通C,Python,Java,mysql数据库,python前端与后端开发
@欢迎各位朋友提出建议一起进步
@
@承接web前端外包,微信小程序外包,单片机相关外包,价格实惠,代码质量保证,欢迎联系
@邮箱[email protected]
@微信xiechunhao12138
**********************************/

代码结构图:

Python+Mysql学生选课系统(附下载链接)_第1张图片

 

数据库结构图:

Python+Mysql学生选课系统(附下载链接)_第2张图片

 

下面是创建数据库的命令:

#bash下登陆数据库
	mysql -u root -p


#创建并进入数据库
	create database student_info default charset=utf8;
	use student_info;


#创建学生信息存储表
#这张表以学生id为主键,学生姓名为字符类型,固定长度10位,默认字符集utf8
	create table student(id int primary key, name char(10) not null) default charset=utf8;
	

#创建课程信息存储表
#这张表以课程id为主键,并有自增属性,课程名称为变长,最长30位,不能为空;默认字符集utf8

	create table course(courseid int primary key auto_increment, coursename varchar(30) not null) default charset=utf8;
	
#创建中间表
#存储哪位学生选了哪个课程
#学生id为主键,为了加快检索速度,该字段以student表中的id为外键
#courseid字段以course表中的id为外键

	create table selection(studentid int not null, courseid int not null unique, foreign key(studentid) references student(id) on delete cascade on update cascade, foreign key(courseid) references course(courseid) on delete cascade on update cascade);


#创建学生的用户名密码表
#包含username用户名和passwd密码
	create table user(username int, passwd char(20) not null, foreign key(username) references student(id) on update cascade on delete cascade);


#创建管理员数据表
	create table admin(username char(20) not null, passwd char(20) not null);
#向用户名密码表中添加admin-admin
#用户注册使可以向该张表中加入数据,以便验证
	insert into admin values("admin","admin");






 

下面是数据库操作模块代码:

# -*- coding: UTF-8 -*-
import pymysql

class mysql():
	
	
	def __init__(self, address, port, user, passwd, char_set):
		"""
		Function: 类的初始化函数,数据库对象mysql在初始化时直接连接数据库,并获取cursor对象
		args:
			self:类对象
			address:要连接的数据库ip地址
			port:要连接的数据库端口
			user:连接数据库用户名
			passwd:连接数据库密码
			char_set:连接用字符集,一般为"utf8"(默认)
		return: None
		"""
		try:
			self.database = pymysql.connect(address, user, passwd, charset=char_set, port = port)
			self.cursor = self.database.cursor()
			self.cursor.execute("use student_info")
		except Exception as e:
			print("Connection failed!")
			print(e)
			exit(-1)

	def is_admin(self, admin_name):
		"""
		func:判断用户名admin_name是不是管理员账户
		args:
			admin_name:需要判断的账户名
		return:
			True/False
		"""

		if self.cursor.execute("select * from admin where username=\"%s\"" % admin_name) == 0:
			return False
		return True

	def is_admin_passwd_correct(self, username, passwd):
		"""
		func:判断用户名username的密码是否为passwd
		args:
			admin_name:需要判断的账户名
			passwd:需要判断的密码
		return:
			True/False
		"""
		self.cursor.execute("select * from admin where username=\"%s\"" % username)
		if self.cursor.fetchall()[0][1] == passwd:
			return True
		return False

	@staticmethod
	def username2int(input_username_str):
		"""
		func:把非管理员类的用户名,即学生学号,由字符串转为int
		args:
			input_username_str:需要转换的用户名
		return:
			int
		"""

		try:
			input_username_int = int(input_username_str)
		except:
			return None
		return input_username_int

	@staticmethod
	def is_empty_input(str1, str2):
		"""
		func:判断输入字符串是否为空
		args:
			两个需要判断的字符串
		return:
			bool
		"""
		if (str1 == "") or (str2 == ""):			
			return True
		return False

	def is_student_exist(self,username):
		"""
		func:通过学号判断学生是否存在
		args:
			username:需要判断的学号
		return:
			bool
		"""
		if self.cursor.execute("select * from user where username=%d" % username) != 0:
			return True
		return False

	def is_student_passwd_correct(self, username, passwd):
		"""
		func:判断学生的用户名及密码是否匹配
		args:
			username:需要判断的学号
			passwd:需要判断的密码
		return:
			bool
		"""
		if self.cursor.execute("select * from user where username=%d and passwd='%s'" % (username, passwd)) != 0:
			return True
		return False


	def get_course_list(self):
		"""
		func:得到现有的课程列表
		args:
		return:
			包含了课程列表的元组,格式为
			((课程id1,课程名1),(课程id2,课程名2)......)
		"""
		self.cursor.execute("select * from course")
		return self.cursor.fetchall()

	def course_exist(self, courseid):
		"""
		func:查看课程是否存在
		args:
			courseid:要查看的课程id
		return:
			bool
		"""
		if self.cursor.execute("select * from course where courseid = %d" % courseid) != 0:
			return True
		return False

	def course_have_been_selected(self, studentid, courseid):
		"""
		func:查询某位学生是否已经选择了某课程
		args:
			studentid:要查看的学生id
			courseid:要查看的课程id
		return:
			bool
		"""
		if self.cursor.execute("select * from selection where studentid = %d and courseid = %d" % (studentid, courseid)) != 0:
			return True
		return False

	def select(self, studentid, courseid):
		"""
		func:某位学生选课
		args:
			studentid:要选课的学生id
			courseid:要选择的课程id
		return:
			None
		"""
		self.cursor.execute("insert into selection values(%d,%d)" % (studentid, courseid))
		self.database.commit()

	def get_student_course(self, studentid):
		"""
		func:获取某位同学已经选择的课程
		args:
			studentid:要查看的学生id
		return:
			包含课程信息的列表,元素均为字符串
			[课程名1,课程名2...]
		"""
		self.cursor.execute("select * from selection where studentid=%d" % studentid)
		t = list()
		for i in self.cursor.fetchall():
			self.cursor.execute("select coursename from course where courseid=%d" % i[1])
			t.append((i[1], self.cursor.fetchall()[0][0]))
		return t


	def delete_course_from_student(self, studentid, courseid):
		"""
		func:在某位学生的选课表中删除一门课程
		args:
			studentid:要删除课程的学生id
			courseid:要删除的课程id
		return:
			None
		"""
		self.cursor.execute("delete from selection where studentid = %d and courseid = %d" % (studentid, courseid))
		self.database.commit()

	def get_student_list(self):
		"""
		func:获得所有学生id及其姓名
		args:
		return:
			一个元组,结构为
			((学生1id,学生1姓名),(学生2id,学生2姓名)...)
		"""
		self.cursor.execute("select * from student")
		return self.cursor.fetchall()


	def get_student_name(self, studentid):
		"""
		func:从学生id获得学生姓名
		args:
			studentid:学生id
		return:
			str(学生姓名)
		"""
		self.cursor.execute("select * from student where id=%d" % studentid)
		return self.cursor.fetchall()[0][1]

	def add_student(self, studid, studname):
		"""
		func:向数据库添加学生
		args:
			studid:学生id
			studname:学生姓名
		return:
			None
		"""
		self.cursor.execute("insert into student values(%d,'%s')" % (studid, studname))
		self.cursor.execute("insert into user values(%d,%d)" % (studid, studid))
		self.database.commit()

	def course_exist_by_name(self, coursename):
		"""
		func:判断名为coursename的课程是否存在
		args:
			coursename:课程名
		return:
			bool
		"""
		if self.cursor.execute("select * from course where coursename='%s'" % coursename) != 0:
			return True
		return False

	def add_course(self, coursename):
		"""
		func:添加课程
		args:
			coursename:要添加的课程名,课程id由数据库决定
		return:
			None
		"""
		self.cursor.execute("insert into course values(%s,'%s')" % ("NULL", coursename))
		self.database.commit()

下面是命令行菜单模块:

# -*- coding: UTF-8 -*-

class menu():
	@staticmethod
	def welcome():
		print("欢迎来到选课系统")

	@staticmethod
	def get_username_passwd_str():
		str1 = input("请输入你的用户名:")
		str2 = input("请输入你的密码:")
		return str1, str2

	@staticmethod
	def wrong_passwd():
		print("密码错误,请重新登陆")

	@staticmethod
	def empty_input():
		print("用户名或密码不能为空")

	@staticmethod
	def inexist_username():
		print("用户名不存在")

	@staticmethod	
	def student_top_menu():
		print("""
			操作列表:
			1、选课
			2、查看已选课程
			3、查看所有课程
			4、退课
			0、退出登陆
		""")

	@staticmethod	
	def get_input_order():
			return int(input("请输入要进行的操作序号"))

	@staticmethod			
	def print_course_list(courselist):
		for i in courselist:
			print("%d  %s" % (i[0], i[1]))
		

	@staticmethod	
	def please_select():
		print("请输入要选择的课程代号输入0退出选课:")

	@staticmethod	
	def inexist_course_id():
		print("所选课程不存在")

	@staticmethod
	def course_have_been_selected():
		print("你已经选择该课程")

	@staticmethod
	def select_ok():
		print("选课成功")

	@staticmethod
	def print_student_selected_course(course):
		print("你已经选择了如下课程")
		for i in course:
			print("%d  %s" % (i[0], i[1]))
	
	@staticmethod
	def select_course_to_exit():
		print("请输入要退选的课程代号:")

	@staticmethod
	def exit_ok():
		print("退课成功")

	@staticmethod
	def have_not_chosen():
		print("你没有选择该课程")

	@staticmethod
	def print_student_list(student_list):
		for i in student_list:
			print("Student ID: %d, Student Name: %s" % (i[0], i[1]))
	
	@staticmethod
	def to_file(studentid, studentname, coursetuple, file):
		"""
		将所给信息按照格式写入到文本文件中
		"""
		file.write("%s\t%d\t" % (studentname, studentid))
		for i in coursetuple:
			file.write("%d-%s\t" % (i[0], i[1]))
		file.write('\n')

	@staticmethod
	def admin_top_menu():
		print("""
		1、查看所有课程及其id
		2、查看所有同学及其id
		3、查看所有同学及其id和所选课程
		4、查看某位同学所选课程
		5、添加学生信息
		6、添加课程信息
		7、导出学生选课表
		0、退出程序
		""")




下面是主函数代码(这个项目的一大缺点就是在主函数里写了太多东西,而且代码复用做的很不好)

# -*- coding: UTF-8 -*-

import menus
import mysqlpython as sql

#初始化变量
menu = menus.menu()
db = sql.mysql("localhost", 3306, "root", "qqqq", "utf8")

#主循环
while True:
	#打印欢迎信息
	menu.welcome()

	#输入用户名及密码
	input_username_str, input_passwd_str = menu.get_username_passwd_str()

	#判断输入是否为空,为空则不继续
	if db.is_empty_input(input_username_str, input_passwd_str) == True:
		menu.empty_input()
		continue

	#判断用户名是否为管理员用户名,是则验证密码进入管理员模式,否则去学生数据库验证密码
	if db.is_admin(input_username_str) == True:
		#在管理员数据库验证密码
		if db.is_admin_passwd_correct(input_username_str, input_passwd_str) == True:
			while True:

				#显示管理员顶级菜单,读入操作代码
				menu.admin_top_menu()
				try:
					op = menu.get_input_order()
				except:
					print("输入不合法,请重新输入")
					continue

				#1、查看所有课程及其id
				if op == 1:
					menu.print_course_list(db.get_course_list())
				#2、查看所有同学及其id
				elif op == 2:
					menu.print_student_list(db.get_student_list())

				#3、查看所有同学及其id和所选课程
				elif op == 3:
					#menu.print_student_course_list(db.get_student_course_list())
					for op_ in db.get_student_list():
						print("Student ID: %d, Student Name: %s. Selected:" % (op_[0], op_[1]))
						menu.print_student_selected_course(db.get_student_course(op_[0]))
				#4、查看某位同学所选课程
				elif op == 4:
					print("请输入学生学号")
					try:
						op_ = menu.get_input_order()
					except:
						print("输入不合法")
						continue

					if db.is_student_exist(op_) == False:
						menu.inexist_username()
						continue
					menu.print_student_selected_course(db.get_student_course(op_))

				#5、添加学生信息
				elif op == 5:
					print("请输入要添加的学生学号")
					try:
						studid = menu.get_input_order()
					except:
						print("输入不合法")
						continue
					if db.is_student_exist(studid) == True:
						print("True")
						print("学生已经存在,姓名为",db.get_student_name(studid))
						continue
					print("False")
					print("请输入要添加的学生姓名")
					studname = input()
					if studname == "":
						print("学生姓名不能为空")
						continue
					db.add_student(studid, studname)
					print("添加学生成功")
				#6、添加课程信息
				elif op == 6:
					coursename = input("请输入要添加的课程名称")
					if coursename == "":
						print("课程名称不能为空")
						continue
					if db.course_exist_by_name(coursename) == True:
						print("课程已经存在")
						continue
					db.add_course(coursename)
					print("添加课程成功")
				
				#7、导出学生选课表
				elif op == 7:
					print("学生选课表将导出到程序目录下的output文件夹下")

					#写入文件时,将会把旧文件覆盖
					#.csv文件使用utf8编码
					#每条字段之间用tab制表符即'\t'分隔
					#每条记录之间用回车符分隔
					#可以在excel中打开
					#打开方式为Excel 2010 -> 菜单栏选择'数据' -> 选择自文本 ->选择文件打开 -> 选择编码utf8
					file = open("./output/chart.csv", "wt")
					file.write("姓名\t学号\t所选课程\n")
					for op_ in db.get_student_list():
						menu.to_file(op_[0], op_[1], db.get_student_course(op_[0]),file)
					file.close()

				elif op == 0:
					break
		else:
			menu.wrong_passwd()
	else:
		input_username_int = db.username2int(input_username_str)
		if input_username_int is None:
			menu.inexist_username()
			continue
		if db.is_student_exist(input_username_int) == False:
			menu.inexist_username()
			continue
		if db.is_student_passwd_correct(input_username_int, input_passwd_str) == True:
			while True:
				menu.student_top_menu()
				try:
					op = menu.get_input_order()
				except:
					print("输入不合法,请重新输入")
					continue
				if op == 0:
					break
				#1、选课
				elif op == 1:
					menu.print_course_list(db.get_course_list())
					print("输入0退出选课")
					while True:
						menu.please_select()
						try:
							op_ = menu.get_input_order()
						except:
							print("输入不合法,请重新输入课程编号")
							continue
						if op_ == 0:
							break
						if db.course_exist(op_) == False:
							menu.inexist_course_id()
							continue
						if db.course_have_been_selected(input_username_int, op_) == True:
							menu.course_have_been_selected()
							continue
						db.select(input_username_int, op_)
						menu.select_ok()
				#2、查看已选课程
				elif op == 2:
					menu.print_student_selected_course(db.get_student_course(input_username_int))
				#3、查看所有课程
				elif op == 3:
					menu.print_course_list(db.get_course_list())
				#4、退课
				elif op == 4:
					menu.print_student_selected_course(db.get_student_course(input_username_int))
					while True:
						menu.select_course_to_exit()
						try:
							op_ = menu.get_input_order()
						except:
							print("输入不合法,请重新输入课程编号")
							continue
						if op_ == 0:
							break
						if db.course_exist(op_) == False:
							menu.inexist_course_id()
							continue
						if db.course_have_been_selected(input_username_int, op_) == True:
							db.delete_course_from_student(input_username_int, op_)
							menu.exit_ok()
						else:
							menu.have_not_chosen()
		else:
			menu.wrong_passwd()

#1120170001


一点开发心得:

  1. 稍微大型的代码项目,就必须先定一个架构,把各个部分主题的结构用图或者语言表达出来。否则中途根本不知道要怎么写
  2. 先写主函数的逻辑,函数可以先不实现,先把整体架构写出来,然后一点一点完善代码,写函数。
  3. 自己对面向对象的理解还有很大问题,menu菜单里出现了非常多只有一行print的函数,复用度很低,但使代码非常繁杂,不知道该如何解决,还需要向老师请教
  4. 开发有些仓促,计划的部分功能没有实现。但毕竟只是一次练习,还没有加上GUI,今后再出一版更加完整的代码

代码中的不足,请各位多多指正。

我的邮箱是[email protected]

各位如果有需要代写C,C++,Java,Python,深度学习,单片机,mysql代码的,也欢迎联系我,价格实惠,质量保证

你可能感兴趣的:(python,MySQL)