• 员工信息表作业


    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # __author: 金鑫
    # 2017/8/8
    """
    1,Alex,22,13651054608,IT
    2,Egon,23,13304320533, Tearcher
    3,沛齐,23,13304320533, Tearcher
    4,金鑫,23,13304320533, Tearcher
    """
    import os   #引用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:   #r模式打开账号密码文件
                user = eval(f.read())   #user-pwd文件是个字典,用eval取出来
            count = 0   #计数器刚开始为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  #计数器加1
                    if count == 3:  #如果三次都输错
                        print('用户名密码不正确,您已经没有输入机会,请重新登录')   #打印内容
                    else:   #输错次数不到三次
                        print('用户名密码不正确,您还有%s输入机会' % (3 - count))   #打印内容
    
        return wrapper  #装饰器闭包
    
    
    def get_last_id():  #获取id表id
        """
        此函数是获取id表中的id
        :return: 返回值是最后的id,如果第一次给员工信息表添加数据,id为0
        """
        with open('id表', encoding='utf-8') as f:    #r模式打开id表文件
            list_id = f.read()  #读取id表,并赋值给 list_id
            return int(list_id) if list_id else 0   #如果id表有内容就返回整数的id,没有就返回0
    
    
    def add():  #增加函数
        """
        此函数是为员工信息表添加新的数据,关键点在添加新数据之后,你的id表的id会随之改变。
        :return: None
        """
        old_last_id = get_last_id() #执行获取id表的函数,并赋值给old_last_id
        input_info = input('按照下列格式输入信息:'
                           '姓名,年龄,电话,职业').strip()   #让用户输入
        new_last_id = str(int(old_last_id)+1)   #让id表的数字加1
        add_info = new_last_id + ',' + input_info   #给用户输入的信息添加序号
        with open('员工信息表', 'a', encoding='utf-8') as f2:    #a模式打开员工信息表
            # 此三元运算符是判断员工信息表中如果是第一次添加内容直接添加,否则 换行添加。
            f2.write(add_info) if old_last_id == 0 else f2.write('
    '+add_info)
        print('您已成功添加,请继续操作')   #打印操作成功
        with open('id表', 'w', encoding='utf-8') as f3:  #w模式打开id表
            f3.write(new_last_id)   #写入新的id号
    
    
    def pop():  #删除函数
        """
        此函数的功能是删除员工信息表中的数据,关键点:
            1,删除的id不是员工信息表最后的id,则不涉及id表中的id更改。
            2,删除的id是员工信息表最后的id,则删除之后必须将id表中的id自增1,以便下次添加数据从新的id开始。
            3,flag的设置是因为我在打开员工信息表的过程中,不能删除此员工信息表,
                所以设置标志位,等操作完成之后,在删除原文件,重新命名新文件。
        :return:
        """
        pop_id = input('请填写你想删除的信息id')  #获取用户想删除的id号
        with open('员工信息表', encoding='utf-8') as f:  #r模式打开员工信息表
            for line in f:  #循环员工信息表的每一行
                line_list = line.strip().split(',') #把每一行以','切割,并赋值
                if pop_id == line_list[0]:  #如果就是用户要删除的行,执行下面操作
                    # 判断删除的id是否在文件中,设置标志位,等文件操作完成后,在删除文件,重命名文件。
                    global flag #给flag定义全局变量
                    flag = True
                    last_id = get_last_id() #获取id表的id
                    if pop_id == last_id:   #如果要删除的ID就是最后一行
                        with open('id表', 'w', encoding='utf-8') as f3:  #w模式打开id表
                            f3.write(str(int(pop_id)+1))    #给id表加1
                    with open('员工信息表', encoding='utf-8') as f1, 
                            open('员工信息表.bak', 'w', encoding='utf-8') as f2: #r模式打开员工信息表,w模式打开员工信息表.bak
                        for line1 in f1:    #循环员工信息表的每一行
                            f2.write(line1) if pop_id != line1.strip().split(',')[0] else f2.write('')  #如果删除id不等于这一行就写入备份文件,如果这行就是要删除的那一行就写一个''
                    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')  #将用户的查询语句以where切割,分别赋值给content和condition
            # print(content,condition)
            if 'select' in content: #如果select在content中执行下面操作
                for key in check_conditions:    #循环创建的条件列表
                    if key in condition:    #如果列表的内容在用户输入的条件中
                        index_check_conditions = check_conditions.index(key)    #获得查询条件列表中条件的索引,并赋值index_check_conditions
                        name, cond = condition.strip().split(key)   #将筛选条件去除空格并以要比较的符号或like分割,将前后分别赋值给name和cond
                        #  content为 'select name,id,'或'select *,'
                        #  name 是 where后面的第一个关键字
                        #  key  是比较运算符
                        #  cond 是 实际需要比较的 关键字
                        # 例如:where id > 3  name是id,key是 > , cond 是 3
                        content = ''.join(content.split('select')[1:])  #将content以select分割并切片去除空字符串再转换成字符串
                        with open('员工信息表', encoding='utf-8') as f:  #r模式打开员工信息表
                            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())   #查找name在列名的索引,列名的顺序和员工信息表的表头一样,并赋值给index
                                    # 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(),
                                    }   #创建了一个筛选字典,字典的筛选条件和条件列表的顺序一样,也就是说key的索引就是字典的键
                                    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
                                                select_name_list = [i for i in select_name_list if i != ''] #如果查询语句内容不为空就添加到列表里,并重新赋值给select_name_list
                                                str1 = ''   #创建一个空字符串赋值
                                                for names in select_name_list:  #循环用户输入的查询语句列表
                                                    name_index = name_list.index(names.strip()) #寻找用户输入的查询语句在列名中的索引,并赋值给 name_index
                                                    str1 = str1 + line_list[name_index] + ',' #根据索引查找之前分割后的每一行的列表中的内容,并隔开
                                                print(str1) #打印用户要查询的内容
                                            else:   #只剩下用户要查找的单个条件
                                                print(line_list[name_list.index(content)])  #直接根据索引去查找用户要查询的信息并打印
    
                        break
                else:   #如果输入的条件不在列表里
                    print('您输入的不正确,请重新输入')  #打印内容
            else:   #没有select
                print('您没有输入select或者select输入有误,请重新输入')  #打印内容
        except Exception:   #不报错
            print('您输入的查询语句有误,请重新输入。')#打印内容
    
    
    def loginout():#写一个注销函数
        print('感谢您登陆员工内部系统')
        user_dic['login'] = False #将登陆状态改为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']:    #如果认证状态为True
            print(menu) #打印主菜单
            option = input('请输入你的选项:').strip()  #让用户输入选项
            if option in choice_dict:   #如果用户输入的内容在字典里
                choice_dict[option]()   #根据输入的内容执行对应的函数
            else:
                print('请输入正确选项') #不在字典里就打印
    
    
    if __name__ == '__main__':
        main()  #执行函数
    

      

  • 相关阅读:
    Gantt/BTS 生产计划电子看板甘特图
    C# DotNetty TCP对接 松下扣料机
    Vue 和 Zebra 打印机连接直接打印条码
    JavaFx 通信ITC数字广播 SAPI 使用NeoSpeech Liang包生成语音
    Docker RabbitMQ 镜像集群
    游戏匹配实现
    Metro 界面设计案例
    JavaFX 集成 Sqlite 和 Hibernate 开发爬虫应用
    Discuz论坛 自动加好友留言程序
    JavaFX Metro UI 和 开发库
  • 原文地址:https://www.cnblogs.com/nicess/p/8856505.html
Copyright © 2020-2023  润新知