zoukankan      html  css  js  c++  java
  • 老男孩Day4作业:员工信息表程序

    作业要求

    - 实现增删改查操作:
    - 可进行模糊查询,语法至少支持下面3种:
    select name,age from staff_table where age > 22
    select from staff_table where dept = "IT"
    select from staff_table where enroll_date like "2013"
    - 查到的信息,打印后,最后面还要显示查到的条数
    - 可创建新员工纪录,以phone做唯一键,staff_id需自增
    - 可删除指定员工信息纪录,输入员工id,即可删除
    - 可修改员工信息,语法如下:
    UPDATE staff_table SET dept = "Market" WHERE where dept = "IT"
    staff_id,name,age,phone,dept,enroll_date
    1,Alex Li,22,13651054608,IT,2013-04-01
    2,Jack Wang,30,13304320533,HR,2015-05-03
    3,Rain Liu,25,1383235322,Sales,2016-04-22
    4,Mack Cao,40,1356145343,HR,2009-03-01
    - 注意:以上需求,要充分使用函数,请尽你的最大限度来减少重复代码


     1)编写思路

    编写思路参考下面GitHub链接中的流程图

    https://github.com/ChuixinZeng/PythonStudyCode/blob/master/PythonCode-OldBoy/Day4/作业/Day4_员工信息表程序_流程图.png

    2)具体实现

      1 # -*- coding:utf-8 -*-
      2 
      3 # Author:Chuixin Zeng
      4 
      5 import os
      6 # 导入shutil模块,用于备份文件
      7 import shutil
      8 import time
      9 
     10 # 定义一个装饰器,用于备份员工信息表
     11 # 这个装饰器是在全部功能实现以后,额外添加的,实现不修改函数的内容,不修改函数的调用方式,对用户透明
     12 
     13 def staff_info(func_type):
     14     def backup(func):
     15         def re_name(*args,**kwargs):
     16             # 如果func_type传入的参数值不是search_type,但是当前的操作不是查询,而是修改、删除或添加
     17             # 这种情况下,代表文件有改动过,就需要对改动前的staff_info.txt文件先进行备份
     18             if func_type != 'search_type':
     19                 backup_time = time.strftime('%Y%m%d_%H%M%S')
     20                 shutil.copyfile('staff_info.txt','staff_info_%s.bak' % backup_time)
     21                 print("原始员工信息表已备份为 staff_info_%s.bak" % backup_time)
     22             print("已有员工信息如下:")
     23             # 备份完成之后,将当前员工信息表的内容打印出来
     24             with open('staff_info.txt','r',encoding='utf-8') as f:
     25                 for line in f:
     26                     line = line.strip().split(',')
     27                     print('|'+'|'.join(line)+'|')
     28 
     29             # 上面备份完了之后,下面res的内容是执行被装饰的函数,然后再执行文件重命名
     30             # 后面加的*args **kwargs表示函数有参数就传进来,没参数就是空,比较灵活
     31             res = func(*args,**kwargs) # 这一句的func实际上是被装饰的函数
     32 
     33             # 如果func_type传入的值是mod_type或者del_type,代表是修改或删除了文件,这个时候做下面的操作:
     34                 # 1. 因为原始的staff_info.txt文件已经备份过,所以这时候可以把原始文件删除掉了
     35                 # 2. 将函数中新生成的staff_info_new文件改名为staff_info.txt,代表最终删除或修改完成
     36             if func_type in ['mod_type','del_type'] and os.path.exists('staff_info_new'):
     37                 os.remove('staff_info.txt')
     38                 os.rename('staff_info_new','staff_info.txt')
     39             return res # 返回res的内存地址
     40         return re_name # 返回re_name的内存地址,实际上该函数包含重命名和备份文件
     41     return backup
     42 
     43 # 定义查询函数,用于从员工信息表中查询信息
     44 @staff_info(func_type='search_type')
     45 def search():
     46     user_search = input("请输入模糊查询的语句:").strip()
     47     # select name,age from staff_table where age > 22
     48     # select * from staff_info where dept = "IT"
     49     # select * from staff_info where enroll_date like "2013"
     50     # 将输入的条件语法以空格形式拆分成列表
     51     search_list = user_search.split(' ')
     52     #print(search_list)
     53     # 定义一个列表,用于保存查询结果
     54     found_info = []
     55     with open('staff_info.txt','r',encoding='utf-8') as f:
     56         for line in f:
     57             user_info = line.strip().split(',') # 循环读取员工信息
     58             # print(user_info)
     59             # ['staff_id', 'name', 'age', 'phone', 'dept', 'enroll_date']
     60             # ['1', '张三', '25', '152015410', '运维', '2013-11-01']
     61 
     62             # 将查询条件字符串写入变量,这里的查询条件对应的是age > 22
     63             conditional = '%s %s %s' % (user_info[2],search_list[6],search_list[7])
     64             # print(conditional) # age > 22
     65 
     66             # 如果用户输入的查询表达式里面第六个元素是=,则替换成==
     67             # 因为查询条件有可能是:select name,age from staff_table where age = 25
     68             # 为了方便if判断,就需要把=替换成==
     69             if search_list[6] == '=': # 如果是等号就替换
     70                 conditional = conditional.replace('=','==')
     71 
     72             # 用语句关键字匹配,用eval()将字符串转换为判断条件
     73             # 如果用户输入的查询表达式符合下面的条件
     74             if search_list[5] == 'age' and user_info[0].isdigit() and eval(conditional):
     75                 # 则把用户信息表的name,age元素附加到存放查询结果的表格中
     76                 found_info.append([user_info[1],user_info[2]])
     77 
     78             # 如果用户输入的查询表达式符合下面的条件
     79             # 查询语句里面包含元素dept,并且用户信息表的dept信息和查询表达式的dept信息匹配
     80             elif search_list[5] == 'dept' and user_info[4] in search_list[7]:
     81                 # 则把user_info员工信息表的匹配行整个附加到found_info中
     82                 found_info.append(user_info)
     83             # 通过用户输入的表达式中的enroll_date和用户信息表进行匹配,如果匹配上,则附加行到found_info表
     84             # 切片出用户信息列表中的年份与语法中的年份对比,年份只保留年,例如2017,切片后,去掉月日信息-11-01
     85             elif search_list[5] == 'enroll_date' and user_info[5][0:4] in search_list[7]:
     86                 found_info.append(user_info)
     87         if not found_info:
     88             print("没有找到你要搜索的员工!
    ")
     89         else:
     90             print("找到如下员工信息:
    ")
     91             for i in found_info:
     92                 print('|'.join(i))
     93             print("
    共计找到 %d 条信息
    " % len(found_info))
     94     return found_info
     95 
     96 @staff_info(func_type='add_type')
     97 def add():
     98     user_add = input("请输入您要增加的员工信息(格式要求 zengchuixin,22,12378902792,IT,2014-06-23):").strip()
     99     add_list = user_add.split(",") # 用,号将用户输入的员工信息拆分为列表
    100     # print(add_list) # ['guoguoguo', '22', '12378902792', 'IT']
    101     phone = [] # 定义一个空列表
    102     with open('staff_info.txt','r+',encoding="utf-8") as f:
    103         user_id = 0 # 保存员工ID的变量,初始值0
    104         for line in f:
    105             user_info = line.strip().split(',')
    106             # print(user_info)
    107             # ['staff_id', 'name', 'age', 'phone', 'dept', 'enroll_date']
    108             # ['1', '张三', '25', '152015410', '运维', '2013-11-01']
    109 
    110             # 把现有员工信息表中已经存在的phone的值追加保存到前面定义的phone列表里面
    111             phone.append(user_info[3])
    112 
    113             # 判断是否要给员工ID变量赋值,循环结束后,user_id的值就是最后一行员工信息的ID值
    114             if user_info[0].isdigit() and user_id < int(user_info[0]):
    115                 user_id = int(user_info[0])
    116 
    117         # print(phone) # 打印查看追加后的phone列表,包含现有员工的phone信息
    118         # 这里判断增加的信息是不是存在,是以phone做唯一键进行判断的,如果phone不存在,则认为是新员工
    119         # 而且staff_id要自动增加,前面for循环里面的user_id保存了最后一行user_id的值
    120         # 如果通过phone判断员工信息不存在,则ID在此基础上+1
    121         if add_list[2] not in phone:
    122             f.write('
    '+str(user_id+1)+','+','.join(add_list))
    123             print("员工%s的信息已添加成功!
    " % add_list[0])
    124         else:
    125             print("您要添加的员工信息已经存在!
    ")
    126 
    127 @staff_info(func_type='mod_type')
    128 def modify():
    129     user_mod = input("请输入修改员工信息的语法:").strip()
    130     # UPDATE staff_table SET dept = "Market" WHERE where dept = "IT"
    131     mod_list = user_mod.split()
    132     user_list = []
    133     mod_flag = False
    134     with open('staff_info.txt','r',encoding='utf-8') as f,
    135         open('staff_info_new','w',encoding='utf-8') as f2:
    136         for line in f:
    137             user_info = line.strip().split(',')
    138             # 如果用户的dept和修改用户信息语法的dept的值匹配(实际是元素10)
    139             if user_info[4] in mod_list[10]:
    140                 # 将标志位设置为true,如果不满足这个if的条件,则默认标志位为false
    141                 mod_flag = True
    142                 # 将修改语法中set的dept的值更新到user_info中的dept的值,即达到了修改dept的目的
    143                 user_info[4] = mod_list[5].strip('"')
    144                 print("员工%s 信息已修改!
    " % user_info[1])
    145             # 将修改过的员工信息表的所有内容附加到新的类别user_list
    146             user_list.append(user_info)
    147         # 从user_list列表里面循环读取每一行
    148         # print(user_list) 结果是一个列表
    149         for list in user_list:
    150             # 如果list中的第一个元素不是数字,第一行肯定不是数字,是员工信息表的表头
    151             if not list[0].isdigit():
    152                 # 将list内容逐行写入到新的文件中
    153                 f2.write(','.join(list))
    154             else:
    155                 # 如果是数字,则换行后,写入到新表,除了第一行,后续的行都是数字开头
    156                 f2.write('
    '+','.join(list))
    157         if not mod_flag:
    158             print("没有找到要修改信息的员工!
    ")
    159 
    160 @staff_info(func_type='del_type')
    161 def delete():
    162     user_del = input("请输入您要删除的员工的ID:").strip()
    163     # 用户的ID必须是数字,如果用户输入的不是数字,则提示用户输入正确的ID
    164     if not user_del.isdigit():
    165         print("请输入正确的员工ID号:
    ")
    166         return
    167     else:
    168         with open('staff_info.txt','r',encoding='utf-8') as f,
    169             open('staff_info_new','w',encoding='utf-8') as f2:
    170             # 逐行读取原始员工信息表中的内容
    171             for line in f:
    172                 user_info = line.strip().split(',')
    173                 # 如果用户输入的数字和员工信息表元素0所在的数字匹配,则代表要删除的用户存在
    174                 if user_del == user_info[0]:
    175                     # 提示用户已删除员工,并打印出来已删除的员工信息
    176                     print("已删除员工 %s" % line)
    177                     continue
    178                 # 如果不满足iF的条件,则把不满足的所有行写入到新的文件,满足的不写入,实现删除效果
    179                 # 问题:永远只能删一行
    180                 # 问题解决:通过前面定义的装饰器解决,如果有staff_info_new文件,则删除原始的staff_info文件,然后把new
    181                 # 文件重命名为staff_info.txt即可
    182                 else:
    183                     if not line[0].isdigit():
    184                         f2.write(line.strip())
    185                     else:
    186                         f2.write('
    '+line.strip())
    187 
    188 # 定义查询界面
    189 while True:
    190     print("""1.模糊查询
    191     2.创建新员工
    192     3.修改员工信息
    193     4.删除员工信息
    194     5.退出
    195     """)
    196     menu_dict = {'1':search,'2':add,'3':modify,'4':delete}
    197     user_chosen = input("请输入您想要操作的选项序号:")
    198     if user_chosen in menu_dict.keys():
    199         # 执行用户选择的函数
    200         menu_dict[user_chosen]()
    201     elif user_chosen == '5':
    202         exit("下次再见!")
    203     else:
    204         print("请输入正确的格式!")

    3)GitHub笔记

    第四天的笔记地址:

    https://github.com/ChuixinZeng/PythonStudyCode/tree/master/PythonCode-OldBoy/Day4/随堂练习

    第四天的作业地址:

    https://github.com/ChuixinZeng/PythonStudyCode/tree/master/PythonCode-OldBoy/Day4/作业

  • 相关阅读:
    深度学习——02、深度学习入门——经典卷积神经网络架构实例——RNN
    深度学习——02、深度学习入门——经典卷积神经网络架构实例——RNN
    深度学习——02、深度学习入门——经典卷积神经网络架构实例——VGGNet
    深度学习——02、深度学习入门——经典卷积神经网络架构实例——VGGNet
    深度学习——02、深度学习入门——经典卷积神经网络架构实例——VGGNet
    asp.netweb formURL 路由​​​​​​​
    asp.netweb formURL 路由​​​​​​​
    CSS 加粗(css fontweight)
    CSS 加粗(css fontweight)
    MongoDB$unwind操作符展开
  • 原文地址:https://www.cnblogs.com/ChuixinZeng/p/Jamie_Zeng_Day4.html
Copyright © 2011-2022 走看看