1),启动程序,首页面应该显示成如下格式:
欢迎来到博客园首页
1:请登录
2:请注册
3:文章页面
4:日记页面
5:评论页面
6:收藏页面
7:注销
8:退出程序
2),用户输入选项,3~6选项必须在用户登录成功之后,才能访问成功。
3),用户选择登录,用户名密码从register文件中读取验证,三次机会,没成功则结束整个程 序运行,成功之后,可以选择访问3~6项,访问页面之前,必须要在log文件中打印日志, 日志格式为-->用户:xx 在xx年xx月xx日 执行了 %s函数,访问页面时,页面内容为:欢 迎xx用户访问评论(文章,日记,收藏)页面
4),如果用户没有注册,则可以选择注册,注册成功之后,可以自动完成登录(完成自动登录+5 分),然后进入首页选择。
5),注销用户是指注销用户的登录状态,使其在访问任何页面时,必须重新登录。
6),退出程序为结束整个程序运行。
status_dic = {
'username': None,
'status': False,
}
flag1 = True
# 三次登陆函数
def login(*args,**kwargs):
i = 0
while i < 3:
if args:
status_dic['username'] = args[0]
status_dic['status'] = True
return True
else:
username = input('请输入用户名:').strip()
password = input('请输入密码:').strip()
with open('register',encoding='utf-8') as f1:
for line in f1:
line_list = line.strip().split()
if username == line_list[0] and password == line_list[1]:
print('登录成功')
status_dic['username'] = username
status_dic['status'] = True
return True
else:
print('输入不正确,请重新输入,还剩%s机会' % (2-i))
if i == 2: return Quit() # 执行退出函数
# 注册函数
def register(*args, **kwargs):
flag = True
while flag:
username = input('请输入要注册的用户名:')
f1 = open('register',encoding='utf-8')
for i in f1:
if username in i:
print('用户名重复,请重新输入')
f1.close() # 用户名重复,关闭文件
break
else:
f1.close()
password = input('请输入要注册的密码:').strip()
f2 = open('register', encoding='utf-8', mode='a')
f2.write('\n{}\t{}'.format(username, password)) # 将用户名和密码写入文件
f2.close()
print('恭喜你,注册成功,已经自动为您登录,现在跳转到首页...')
return login(username,password) # 执行登陆函数
def wrapper(func):
def inner(*args,**kwargs):
if status_dic['status']:
ret = func(*args,**kwargs)
return ret
else:
print('请先进行登录')
if login(): # 跳转到登陆函数
ret = func(*args, **kwargs)
return ret
return inner
# 记录日志,登录日志文件log_func
import time
def log_record(func):
def inner(*args,**kwargs):
struct_time = time.localtime()
time_now = time.strftime("%Y-%m-%d %H:%M:%S", struct_time)
with open('log_func','a',encoding='utf-8') as f1:
f1.write('用户:%s 在%s 执行了 %s函数\n'%(status_dic['username'],time_now,func.__name__))
ret = func(*args,**kwargs)
return ret
return inner
@wrapper
@log_record
def article():
print('欢迎%s访问文章页面' % status_dic['username'])
@wrapper
@log_record
def diary():
print('欢迎%s访问日记页面' % status_dic['username'])
@wrapper
@log_record
def comment():
print('欢迎%s访问评论页面' % status_dic['username'])
@wrapper
@log_record
def enshrine():
print('欢迎%s访问收藏页面' % status_dic['username'])
# 注销页面函数
def login_out():
status_dic['username'] = None
status_dic['status'] = False
print('注销成功')
# 退出函数
def Quit():
global flag1
flag1 = False
return flag1
choice_dict = {
1: login,
2: register,
3: article,
4: diary,
5: comment,
6: enshrine,
7: login_out,
8: Quit,
}
while flag1:
print('欢迎来到博客园首页\n1:请登录\n2:请注册\n3:文章页面\n4:日记页面\n5:评论页面\n6:收藏页面\n7:注销\n8:退出程序')
choice = input('请输入您选择的序号:').strip()
if choice.isdigit():
choice = int(choice)
if 0 < choice <= len(choice_dict):
choice_dict[choice]()
else:
print('您输入的超出范围,请重新输入')
else:
print('您输入的选项有非法字符,请重新输入。')
# 购物车
# 要求用户输入总资产,例如:2000 显示商品列表,让用户根据序号选择商品,
# 加入购物车 购买,如果商品总额大于总资产,提示账户余额不足,否则,购买成功。
goods = [
{"name": "电脑", "price": 1999},
{"name": "鼠标", "price": 10},
{"name": "游艇", "price": 20},
{"name": "美女", "price": 998},
]
shopping = []
salary = input("your salary:").strip()
if salary.isdigit():
salary = int(salary)
print("以下是商品列表:")
for index, item in enumerate(goods):
print(index, item['name'], item['price'])
while True:
choice = input('what you want to buy:').strip()
choice = int(choice)
if (choice >= 0) and (choice < len(goods)):
salary -= int(goods[choice]['price'])
shopping.append((goods[choice]['name']))
print('你所购买商品:%s' % goods[choice]['name'])
print('你所剩余额:%s' % salary)
if salary < int(goods[choice]['price']):
print('你的余额已经不足以购买该商品')
print('一下是你所购买的商品清单:', '\n', shopping)
exit()
else:
continue
else:
print('你输入有误,请重新输入选择序号')
else:
print('你输入有误,请重新输入选择序号')
用户注册及登录
# 用户注册
def register():
username = input('请输入你的注册名:').strip()
with open('register_msg.txt', encoding='gbk') as f:
for line in f:
first = line.strip().split()
if username in first[0]:
print('你所注册的用户名已存在,请重新输入')
return register() # 返回这个注册函数继续执行
else: # 文件中不存在这个名字则可以使用这个注册名
password = input('请输入你的注册密码:').strip()
with open('register_msg.txt', encoding='gbk', mode='a') as f1:
f1.write('\n{}\t{}'.format(username, password)) # 写入用户注册的用户名以及注册密码
print('注册成功')
register()
# 用户登陆
def func(): # 用户选择登陆还是注册函数
choice = input('选择登陆/0还是注册/1:').strip()
if choice == '1':
register() # 执行注册函数
elif choice == '0': # 执行登陆
times = 0
while times < 3: # 三次登陆机会,直到登陆成功
times += 1
def fun1(): # 登陆函数
username = input('请输入你的用户名:').strip()
password = input('请输入密码:').strip()
with open('register_msg.txt', encoding='gbk') as f:
for line in f: # 打开文件,读取每行
li = line.strip().split() # 对每行切割,得到列表
if username == li[0] and password == li[1]: # 判断用户名,密码是否在文件内
print('登陆成功')
while True: # 登陆成功后,继续选择登陆注册或者退出
choice = input('请选择登陆还是注册/1还是退出/2:').strip()
if choice == '1':
return func() # 返回,继续执行上面函数
elif choice == '2':
exit()
else:
print('你输入的有误,请重新输入')
else:
print('你的输入有误')
fun1() # 执行fun1登陆函数
if times == 3:
print('你输入的次数已用完')
exit()
else:
print('你输入的包含非法字符,重新输入')
func() # 调用登陆or注册函数
编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),
要求登录成功一次(三次机会),后续的函数都无需再输入用户名和密码
# 经典在于dic字典的使用
dic = {
'username':None,
'status':False,
}
def wrapper(func):
def inner(*args, **kwargs):
if dic['status']:
# 开始是False,所以先走else,用户账户密码正确下,这里改为True,就一直执行这步
ret = func(*args, **kwargs)
return ret
else:
i = 0
while i < 3:
username = input('请输入用户名:').strip()
password = input('请输入密码:').strip()
with open('register_msg', encoding='utf-8') as f1:
for j in f1:
j_li = j.strip().split() # ['张三','123']
if username == j_li[0] and password == j_li[1]:
dic['username'] = username
dic['status'] = True
ret = func(*args, **kwargs)
return ret
else: # 注意这里的else缩进,如果在if下面则会循环打印
print('账号或者密码错误,请重新输入%s机会' % (2-i))
i += 1
return inner
@wrapper
def article():
print('文章')
@wrapper
def diary():
print('日记')
@wrapper
def comment():
print('评论')
@wrapper
def file():
print('文件')
article()
diary()
comment()
file()
文件存储格式如下:
id,name,age,phone,job
1,Alex,22,13651054608,IT
2,Egon,23,13304320533,Tearcher
3,nezha,25,1333235322,IT
现在需要对这个员工信息文件进行增删改查。
a.可以进行查询,支持三种语法:
select 列名1,列名2,… where 列名条件
支持:大于小于等于,还要支持模糊查找。
示例:
select name, age where age>22
select * where job=IT
select * where phone like 133
b.可创建新员工记录,id要顺序增加
c.可删除指定员工记录,直接输入员工id即可
d.修改员工信息
语法:set 列名=“新的值” where 条件
#先用where查找对应人的信息,再使用set来修改列名对应的值为“新的值”
注意:要想操作员工信息表,必须先登录,登陆认证需要用装饰器完成
其他需求尽量用函数实现
import os
user_dic = {'username': None,
'password': None,
'login': True
}
flag = False
name_list = ['id', 'name', 'age', 'phone', 'job']
check_conditions = ['>', '<', '=', 'like']
def auth(func):
def wrapper(*args, **kwargs):
with open('user-pwd', 'r', encoding='utf8') as f:
user = eval(f.read())
count = 0
while count < 3:
username = input('请输入用户名:').strip()
password = input('请输入密码:').strip()
if user.get(username) and password == user[username]:
user_dic['username'] = username
user_dic['password'] = password
user_dic['login'] = True
ret = func(*args, **kwargs)
return ret
else:
count += 1
if count == 3:
print('用户名密码不正确,您已经没有输入机会,请重新登录')
else:
print('用户名密码不正确,您还有%s输入机会' % (3 - count))
return wrapper
def get_last_id():
"""
此函数是获取id表中的id
:return: 返回值是最后的id,如果第一次给员工信息表添加数据,id为0
"""
with open('id表', encoding='utf-8') as f:
list_id = f.read()
return int(list_id) if list_id else 0
def add():
"""
此函数是为员工信息表添加新的数据,关键点在添加新数据之后,你的id表的id会随之改变。
:return: None
"""
old_last_id = get_last_id()
input_info = input('按照下列格式输入信息:'
'姓名,年龄,电话,职业').strip()
new_last_id = str(int(old_last_id)+1)
add_info = new_last_id + ',' + input_info
with open('员工信息表', 'a', encoding='utf-8') as f2:
# 此三元运算符是判断员工信息表中如果是第一次添加内容直接添加,否则 换行添加。
f2.write(add_info) if old_last_id == 0 else f2.write('\n'+add_info)
print('您已成功添加,请继续操作')
with open('id表', 'w', encoding='utf-8') as f3:
f3.write(new_last_id)
def pop():
"""
此函数的功能是删除员工信息表中的数据,关键点:
1,删除的id不是员工信息表最后的id,则不涉及id表中的id更改。
2,删除的id是员工信息表最后的id,则删除之后必须将id表中的id自增1,以便下次添加数据从新的id开始。
3,flag的设置是因为我在打开员工信息表的过程中,不能删除此员工信息表,
所以设置标志位,等操作完成之后,在删除原文件,重新命名新文件。
:return:
"""
pop_id = input('请填写你想删除的信息id')
with open('员工信息表', encoding='utf-8') as f:
for line in f:
line_list = line.strip().split(',')
if pop_id == line_list[0]:
# 判断删除的id是否在文件中,设置标志位,等文件操作完成后,在删除文件,重命名文件。
global flag
flag = True
last_id = get_last_id()
if pop_id == last_id:
with open('id表', 'w', encoding='utf-8') as f3:
f3.write(str(int(pop_id)+1))
with open('员工信息表', encoding='utf-8') as f1, \
open('员工信息表.bak', 'w', encoding='utf-8') as f2:
for line1 in f1:
f2.write(line1) if pop_id != line1.strip().split(',')[0] else f2.write('')
break
else:
print('您输入的序号不存在,请重新输入')
if flag:
os.remove('员工信息表')
os.rename('员工信息表.bak', '员工信息表')
def update():
"""
此函数的功能:修改员工信息
语法:set 列名=“新的值” where 条件
先用where查找对应人的信息,再使用set来修改列名对应的值为“新的值”
关键点:check_conditions, name_list 这两个列表的运用
check_conditions 为 where 关键字后面的比较条件:> < = like
name_list 为员工信息表的列名,'id', 'name', 'age', 'phone', 'job' 索引与员工信息表每行信息的每列一一对应。
思路:
1,先通过 where 分割,得到content(如 set name = 太白),cond(如 id > 3)
2,循环 check_conditions(> < = like) 通过 条件 分割 得到结果:name是id,key是 > , cond 是 3
3,对 content进行操作,得到要修改的列名:column_name,要修改的值update_value
4,接下来就用到了文件改的思想,如果要修改文件,需要对将原文件读取,一行一行的写入新文件,将需要改动的行写入,
然后将原文件删除,新文件重命名成原文件,这样就做到了文件的改的操作。
5,关键点:check_dict 这是一个if条件的字典,这样设置是因为,不管条件为 < > = 或者like
他们只要满足条件,下面进行的操作是一样的,所以只是条件不同,那么根据key的不同,执行check_dict不同的条件,
然后进行相同的内容即可。
:return: None
"""
pass
def check():
"""
:param:
可以进行查询,支持三种语法:
select 列名1,列名2,… where 列名条件
支持:大于小于等于,还要支持模糊查找。
示例:
check_info = select name, age where age>22
select * where job=IT
select * where phone like 133
关键点:check_conditions, name_list 这两个列表的运用
check_conditions 为 where 关键字后面的比较条件:> < = like
name_list 为员工信息表的列名,'id', 'name', 'age', 'phone', 'job' 索引与员工信息表每行信息的每列一一对应。
思路:
1,先通过 where 分割,得到content(如 select name,id),cond(如 id > 3)
2,循环 check_conditions(> < = like) 通过 条件 分割 得到结果:name是id,key是 > , cond 是 3
3,对 content进行操作,得到要修改的列名:column_name,要修改的值update_value
4,接下来读文件,而读文件分两种:select * (全部) 和select name,id,.. 部分,所以走两条路。
5,关键点:check_dict 这是一个if条件的字典,这样设置是因为,不管条件为 < > = 或者like
他们只要满足条件,下面进行的操作是一样的,所以只是条件不同,那么根据key的不同,执行check_dict不同的条件,
然后进行相同的内容即可。
:return:
"""
try:
check_info = input('请输入查询语句:').strip()
content, condition = check_info.split('where')
# print(content,condition)
if 'select' in content:
for key in check_conditions:
if key in condition:
index_check_conditions = check_conditions.index(key)
name, cond = condition.strip().split(key)
# content为 'select name,id,'或'select *,'
# name 是 where后面的第一个关键字
# key 是比较运算符
# cond 是 实际需要比较的 关键字
# 例如:where id > 3 name是id,key是 > , cond 是 3
content = ''.join(content.split('select')[1:])
with open('员工信息表', encoding='utf-8') as f:
for line in f:
if line.strip():
line_list = [i.strip() for i in line.strip().replace(',',',').split(',')]
# 上面此举是为了解决add信息时,输入的有中文逗号,从而导致split出问题的问题。
# 例:line_list = ['3','Egon','23','13304320533','Tearcher']
index = name_list.index(name.strip())
# index 查询条件的索引,比如你的查询条件是select * where id > 3
# name 就是 id 求出的index 就是id在name_list列表中的索引,他亦是line_list的id的索引
# 这样就可以方便比较了。
check_dict = {
0: int(line_list[index]) > int(cond),
1: int(line_list[index]) < int(cond),
2: line_list[index].strip() == cond.strip(),
3: cond.strip() in line_list[index].strip(),
}
if check_dict[index_check_conditions]:
if content.strip() == "*":
print(line.strip())
else:
if ',' in content.strip():
select_name_list = content.strip().split(',')
select_name_list = [i for i in select_name_list if i != '']
str1 = ''
for names in select_name_list:
name_index = name_list.index(names.strip())
str1 = str1 + line_list[name_index] + ','
print(str1)
else:
print(line_list[name_list.index(content)])
break
else:
print('您输入的不正确,请重新输入')
else:
print('您没有输入select或者select输入有误,请重新输入')
except Exception:
print('您输入的查询语句有误,请重新输入。')
def loginout():
print('感谢您登陆员工内部系统')
user_dic['login'] = False
@auth
def main():
menu = """
欢迎%s用户登录内部员工系统,请进行选择:
选项 1,增加员工信息
选项 2,删除员工信息
选项 3,更改员工信息
选项 4,查询员工信息
选项 5,退出内部员工系统
""" % (user_dic['username'])
choice_dict = {
'1': add,
'2': pop,
'3': update,
'4': check,
'5': loginout
}
while user_dic['login']:
print(menu)
option = input('请输入你的选项:').strip()
if option in choice_dict:
choice_dict[option]()
else:
print('请输入正确选项')
if __name__ == '__main__':
main()
# 这里的查不好整,从输入这块就想不到思路。老师巧妙的利用了输入关键语句,然后对关键字切割在进行筛选过滤得到结果