首页 > 编程语言 >[Python学习日记-58] 开发基础练习1——员工信息查询

[Python学习日记-58] 开发基础练习1——员工信息查询

时间:2024-10-30 16:50:11浏览次数:3  
标签:index 58 Python cmd 员工 result str where 日记

[Python学习日记-58] 开发基础练习1——员工信息查询

简介

题目

答案

简介

        该练习结合了函数和一些常用的模块开发了一个使用命令行交互的员工信息查询程序,可以巩固实践之前学习的内容。

题目

一、程序需求

        现要求你写⼀个简单的员⼯信息增删改查程序,需求如下:

staff_idnameagephonedeptenroll_date
1Jove Zou2215864987526IT2020-08-01
2Lucy Wang3013058496789HR2016-05-25
3Mary Li2517591992555Sales2019-12-19
4Jack Chen6013532334478HR2021-03-11

该表在文件中的存储方式:

        文件名:staff_table(文件内容如下)

# 序号(1),姓名(2),年龄(3),手机号(4),部分(5),入职时间(6)

id,name,age,phone,dept,enroll_data

1,Jove Zou,22,15864987526,IT,2020-08-01
2,Lucy Wang,30,13058496789,HR,2016-05-25
3,Mary Li,25,17591992555,Sales,2019-12-19
4,Jack Chen,60,13532334478,HR,2021-03-11
5,Rachel Chen,23,13351024606,IT,2013-03-16
6,Eric Liu,19,18531054602,Marketing,2012-12-01
7,Cao Zang,21,13235324334,Administration,2011-08-08
8,Kevin Chen,22,13151054603,Sales,2013-04-01
9,Shit Wen,20,13351024602,IT,2017-07-03
10,Mosson1,18,13678789527,IT,2018-12-11

文件(staff_table)行数据的说明:

        (1)表示文件中的条目数

        (2)表示员工姓名

        (3)表示员工的年龄

        (4)员工的手机号

        (5)表示该员工的部门

        (6)员工入职时间

提示:每一行的字符串信息通过逗号分隔成为一个列表 [id,name,age,phone,dept,date]

二、程序功能

        对用户输入的字符串进行解析,从文件中筛选出相应符合条件的结果集。

1、查文件(find)

功能演示1:

>>>:find name,age from staff_table where age > 22

>>>:find name from staff_table where age > 22

>>>:find name,age,phone,dept from staff_table where age > 22

 提示:name和age之间 只有⼀个逗号没有空格

        从 staff_table 文件中,找出员工年龄在22岁以上的员工,将这些员工的姓名,员工的年龄打印出来,对用户输入字符串的解析流程如下:

  1. 读文件
  2. 将每⼀个员工的年龄与22进行比较
  3. 获取到员工年龄大于22的员工信息
  4. 从符合条件的员工信息中筛选出员工的姓名、年龄

效果如下:

提示:find 与 from 之间可以是 *(* 表示员工的所有信息)也可以是员工信息的任意字段(多个字段可以用英文逗号隔开)

功能演示2:

>>>:find * from staff_table where dept = "IT"

         从 staff_table 文件中找到 IT 部门的员工,并打印员工的所有信息。

效果如下:

功能演示3:

 >>>:find * from staff_table where enroll_data like "2013"

        要求为,从 staff_table 文件中找到员工的入职时间是2013年的员工,并打印员工所有的信息。

效果如下:

2、添加员工信息(用户的手机号不允许重复)

>>>:add staff_table Mosson,18,13678789527,IT,2018-12-11

        添加员工信息时,必须有员工名称(Mosson)、员工年龄(18)、员工手机号(13678789527)、员工部门(IT)、员工入职时间(2018-12-11);将这些信息追加到 staff_table 文件新的一行中,并插入这一行的 id

注意:添加员工的时候不考虑异常情况,在添加的时候按照姓名,年龄,手机号, 部门,入职时间 且每一条数据都包含员工的完整数据(姓名、年龄、手机号、部门、入职时间)

效果如下:

3、删除员工信息(根据序号删除相应员工的信息)

>>>:del from staff_table where id = 10

         从 staff_table 中删除序号 id 为10的这⼀条员工的信息。

效果如下:

4、修改员工信息(可以根据特殊条件修改员工的信息)

功能演示1: 

>>>:update staff_table set dept="Market" where dept = "IT"

         将 staff_table 中 dept 为 IT 的修改成 dept 为 Market。

效果如下:

功能演示2:

>>>:update staff_table set age=25 where name = "Jove Zou"

        将 staff_table 中用户名为 Jove Zou 的用户的年龄改成25。

效果如下:

 

 

答案

 程序运行流程图:

        在开发程序前最好还是先画一个程序的运行流程图,这样程序的开发逻辑会非常清晰,我们画这个图的时候可以上网注册一个 processon(https://www.processon.com/)或者下载一个 Visio 来画流程图。

目录结构:

Employer_info/

| --  __init__.py        # 代表 Employer_info 是一个包,无代码

| --  employer_info.py

| --  README.md

| --  staff_table        # 该数据与题目中的一致

employer_info.py:

# -*- coding:utf-8 -*-


def read_file(f_n):
    try:
        f = open(f_n, 'r', encoding='utf-8')
        info_d = {}
        f.seek(0)
        for line in f:  # 读取文件中的内容并转换为dict
            info_d[line.split(',')[0]] = line.strip().split(',')
        f.close()
        return info_d
    except:
        print("The file is not available...")


def analysis(cmd):
    def char_optimization(in_c_l):  # 字符串优化函数,优化名字当中有空格的情况
        if '<' in cmd[cmd.index('where ') + 6:]:  # 如果是del的话符号的序号为5 in_c_l[5 if in_c_l[0] == 'del' else 6]
            if in_c_l[0] == 'update':  # 对update当中的set name的时候作出处理
                before_str = cmd[:cmd.index(' set') + 4]
                middle1_str = cmd[cmd.index('set ') + 4:cmd.index(' where')]
                middle2_str = cmd[cmd.index('where '):cmd.index(' <') + 2]
                after_str = cmd[cmd.index('< ') + 2:]
                in_c_l_result = before_str.strip().split()  # 合拼为list
                in_c_l_result.append(middle1_str)
                in_c_l_result.extend(middle2_str.strip().split())
                in_c_l_result.append(after_str)
            else:  # 其他语句的处理方式
                before_str = cmd[:cmd.index(' <') + 2]
                after_str = cmd[cmd.index('< ') + 2:]
                in_c_l_result = before_str.strip().split()
                in_c_l_result.append(after_str)
        elif '>' in cmd[cmd.index('where ') + 6:]:
            if in_c_l[0] == 'update':
                before_str = cmd[:cmd.index(' set') + 4]
                middle1_str = cmd[cmd.index('set ') + 4:cmd.index(' where')]
                middle2_str = cmd[cmd.index('where '):cmd.index(' >') + 2]
                after_str = cmd[cmd.index('> ') + 2:]
                in_c_l_result = before_str.strip().split()
                in_c_l_result.append(middle1_str)
                in_c_l_result.extend(middle2_str.strip().split())
                in_c_l_result.append(after_str)
            else:
                before_str = cmd[:cmd.index(' >') + 2]
                after_str = cmd[cmd.index('> ') + 2:]
                in_c_l_result = before_str.strip().split()
                in_c_l_result.append(after_str)
        elif '=' in cmd[cmd.index('where ') + 6:]:
            if in_c_l[0] == 'update':
                before_str = cmd[:cmd.index(' set') + 4]
                middle1_str = cmd[cmd.index('set ') + 4:cmd.index(' where')]
                middle2_str = cmd[cmd.index('where '):cmd.index(' =') + 2]
                after_str = cmd[cmd.index('= ') + 2:]
                in_c_l_result = before_str.strip().split()
                in_c_l_result.append(middle1_str)
                in_c_l_result.extend(middle2_str.strip().split())
                in_c_l_result.append(after_str)
            else:
                after_str = cmd[cmd.index('= ') + 2:]
                before_str = cmd[:cmd.index(' =') + 2]
                in_c_l_result = before_str.strip().split()
                in_c_l_result.append(after_str)
        elif 'like' in cmd[cmd.index('where ') + 6:]:
            if in_c_l[0] == 'update':
                before_str = cmd[:cmd.index(' set') + 4]
                middle1_str = cmd[cmd.index('set ') + 4:cmd.index(' where')]
                middle2_str = cmd[cmd.index('where '):cmd.index(' =') + 2]
                after_str = cmd[cmd.index('= ') + 2:]
                in_c_l_result = before_str.strip().split()
                in_c_l_result.append(middle1_str)
                in_c_l_result.extend(middle2_str.strip().split())
                in_c_l_result.append(after_str)
            else:
                after_str = cmd[cmd.index('like ') + 5:]
                before_str = cmd[:cmd.index(' like') + 5]
                in_c_l_result = before_str.strip().split()
                in_c_l_result.append(after_str)
        else:
            in_c_l_result = []
        return in_c_l_result

    c_l = cmd.split()
    c_l_result = []
    # 赋值需要返回的变量
    if c_l[0] == 'find' and len(c_l) >= 8:
        c_l_result = char_optimization(c_l)
        f_n = c_l[3]
    elif c_l[0] == 'update' and len(c_l) >= 8:
        c_l_result = char_optimization(c_l)
        f_n = c_l[1]
    elif c_l[0] == 'del' and len(c_l) >= 7:
        c_l_result = char_optimization(c_l)
        f_n = c_l[2]
    elif c_l[0] == 'add' and len(c_l) >= 3:
        c_l_result = c_l
        f_n = c_l[1]
    else:
        f_n = None
    return c_l_result, f_n


def header_analysis(k, sec_l, d):
    search_list = sec_l[1].split(',')  # 记录查询项列表
    yc_position = []  # 记录显示项的序号
    s_position = d[k].index(sec_l[5])  # 记录需要比较的值在list当中的序号
    if sec_l[1] == '*':  # 如果是'*'直接赋值所有项
        search_list = d[k]
    for i in search_list:
        yc_position.append(d[k].index(i))  # 记录需要显示的值在list当中的序号
    return search_list, yc_position, s_position


def display(y_code, yc_position, d_r):  # 打印出符合的值
    p_list = []  # 返回匹配到的信息
    for k in d_r:
        p_str = ''  # 输出的str
        for i in range(0, len(yc_position)):  # 合拼需要打印的值
            p_str += y_code[i] + ' ' + d_r[k][yc_position[i]] + ' '
        p_list.append(p_str)
    return p_list


def search(sec_l, d):
    search_list = []  # 记录查询项列表
    yc_position = []  # 记录显示项的序号
    s_position = None  # 记录比较项的序号
    first_key = True  # 判断是否为表头
    d_result = {}  # 记录比较结果
    if len(sec_l) == 8:
        for k in d:
            if first_key:  # 表头信息获取
                if sec_l[5] in d[k]:
                    search_list, yc_position, s_position = header_analysis(k, sec_l, d)
                    first_key = False
                else:
                    print("Parameter is not in the table...")
                    break
            else:
                if sec_l[6] == '>' and sec_l[7].isdigit():
                    if d[k][s_position] > sec_l[7]:
                        d_result[k] = d[k]
                elif sec_l[6] == '<' and sec_l[7].isdigit():
                    if d[k][s_position] < sec_l[7]:
                        d_result[k] = d[k]
                elif sec_l[6] == '=':
                    if d[k][s_position] == sec_l[7].strip('\"'):
                        d_result[k] = d[k]
                elif sec_l[6] == 'like':
                    if sec_l[7].strip('\"') in d[k][s_position]:
                        d_result[k] = d[k]
                else:
                    print("Sorry,the comparison type is not supported...")
        for line in display(search_list, yc_position, d_result):  # 调用函数打印在终端
            print(line)
        return d_result
    else:
        print("Sorry,the command is not supported...\nPlease input the comparison value.")


def add(add_l, d):
    staff_id = d.keys().__len__()  # 记录最新序号
    f_n = add_l[1]  # 记录需要查询的文件名
    f = open(f_n, 'a', encoding='utf-8')  # 在文件的末尾添加,所以使用追加模式
    if len(add_l) == 3:
        f.write(str(staff_id) + ',' + add_l[2] + '\n')  # 写入文件
    else:
        print("Sorry,the command is ERROR")
    f.close()


def delete(del_l, d):
    f_del = open(del_l[2], 'w', encoding='utf-8')
    if len(del_l) == 7:
        for k in d:
            if del_l[5] == '<' and del_l[6].isdigit():
                if k < del_l[6]:
                    continue
            elif del_l[5] == '>' and del_l[6].isdigit():
                if k > del_l[6]:
                    continue
            elif del_l[5] == '=':
                if k == del_l[6].strip('\"'):
                    continue
            else:
                print("Sorry,the comparison type is not supported...")
            f_del.write(','.join(d[k]) + '\n')
    else:
        print("Sorry,the command is ERROR")
    f_del.close()


def modify(mod_l, d):
    if len(mod_l) == 8:
        sec_l = 'find * from %s where %s = %s' % (mod_l[1], mod_l[5], mod_l[7])  # 转换成search的语法,后面调用search()来找出需要修改的信息
        mod_c_l, mod_f_n = analysis(sec_l)
        print("------- Modify info -------")
        mod_d = search(mod_c_l, d)  # 需要修改的员工信息
        set_yc_position = mod_l[3].split('=')[0]  # 需要修改这个参数
        set_value = mod_l[3].split('=')[1].strip('\"')  # 需要改为这个值
        mod_yc_position = d['id'].index(set_yc_position)  # 定位修改信息的位置
        f_mod = open(mod_f_n, 'w', encoding='utf-8')
        for k in mod_d:  # 修改符合条件的条目
            d[k][mod_yc_position] = set_value
        for k in d:  # 写入文件
            f_mod.write(','.join(d[k]) + '\n')
        f_mod.close()
    else:
        print("Sorry,the command is ERROR")


func_dict = {
    'add': add,
    'del': delete,
    'find': search,
    'update': modify
}
while True:
    # 准备阶段
    """
    0:id
    1:name
    2:age
    3:phone
    4:dept
    5:enroll_date
    """
    command = input(">>>>>:").strip()
    if not command:  # 不能输入空命令
        print("Please input command...")
    else:
        cmd_list, file_name = analysis(command)
        if file_name is not None and cmd_list != []:  # 命令经过处理后返回的值不能为空,为空就是命令有错
            info_dict = read_file(file_name)
            if info_dict != {}:  # 读取到文件后字典一定不能为空
                if cmd_list[0] in func_dict:  # 判断find add del update
                    func = func_dict.get(cmd_list[0])
                    func(cmd_list, info_dict)
                else:
                    print("Not this functions,available functions:add del find update...")
            else:
                print("Sure your file name...")
        else:
            print("CMD is bad...")

README.md(没开发完成一个程序就应该写一个):

开发环境
Python (3.12.4)

实现功能
该程序包含了对员工信息的 查询(find) 增加(add) 删除(del) 修改(update)这四个功能,输入的命令需要严格遵守语法规则
示例当中的符号示意:{} 当中的option必填其之一,| 或,* 代表所有,option_* 任意option,[] 必填;当中规定的空格是严格规定的
查询(find)
find {option_1|option_1,...,option_n|*} from [filename] where [option_* {<|>|=} {digit|string}] # < > 必须为digit
增加(add)
add [filename] [info]
删除(del)
del from [filename] where [option_* {<|>|=} {digit|string}] # < > 必须为digit
修改(update)
update [filename] set [option_*[=]{digit|string}] where [option_* {<|>|=} {digit|string}]

导入虚拟数据
./staff_table

启动项目
进入到程序所在目录
./Employer_info/
python employer_info.py

常见问题
问题
终端执行python错误
解决
设置环境变量,Windows在Path当中添加Python安装的所在路径
问题
命令当中涉及到大小判断时输入字符可能会报错,而不是语句提示
解决
目前该bug还未解决

标签:index,58,Python,cmd,员工,result,str,where,日记
From: https://blog.csdn.net/zjw529507929/article/details/143315752

相关文章

  • Matplotlib配置和样式表操作——Python实现
    今天在使用Python进行Matplotlib配置和样式表操作时候,发生如下报错:NameError:name'IPython_default'isnotdefined源代码如下:importnumpyasnpfrommatplotlibimportpyplotaspltplt.style.available[:5]defhist_and_lines():np.random.seed(0)fig,......
  • 【2024华为OD-E卷-200分-任务最优调度】(题目+思路+Java&C++&Python解析+在线测试)
    在线评测链接题目内容给定一个正整数数组表示待系统执行的任务列表,数组的每一个元素代表一个任务,元素的值表示该任务的类型。请计算执行完所有任务所需的最短时间。任务执行规则如下:任务可以按任意顺序执行,且每个任务执行耗时间均为111个时间单位两个同类型的......
  • 爬虫 python
    服务端渲染客户端渲染urllib.request.urlopen(url)还是requests.get(url)取决于具体的需求和上下文。        以下是两者的对比以及如何选择适合自己的工具:功能对比:易用性和API设计:requests:API设计更加人性化,提供了丰富的高级功能,如会话管理、自动重定向......
  • 说它是谁就是谁—Python语言中的鸭子类型
    鸭子类型(DuckTyping)是动态类型语言中的一种类型推断风格,尤其在Python语言中得到了广泛的应用。它的核心思想是:“如果它走起路来像鸭子,叫起来像鸭子,那么它就是鸭子”。这句话的意思是,我们不关心对象的类型是什么,而只关心对象的行为。只要对象具有所需的方法和属性,它就可以被视......
  • RK3588J的6路MIPI CSI视频采集方案
    本文主要介绍基于RK3588J的6路高清视频采集案例,开发环境如下Windows开发环境:Windows764bit、Windows1064bit虚拟机:VMware15.5.5开发环境:Ubuntu20.04.664bitU-Boot:U-Boot-2017.09Kernel:Linux-5.10.160LinuxSDK:rk3588_linux_release_v1.2.1摄像头模块型号:TL138......
  • Python元类揭秘:掌控类的创造艺术
    元类(metaclass),作为类的构造者,不仅决定类的行为,还塑造其结构,开启了一扇通往高级元编程的大门。本文旨在全面解析Python元类的奥秘:从概念解析,到需求分析,再到定义与实践,最后,通过具体实例展现元类在现实世界应用中的魅力。一、元类:描述类的类在Python中,一切皆对象。类,作为对象......
  • Python工具箱系列(五十五)
    ​​文字识别文字识别是热门研究方向。目前相对成熟的有:•Google的tesseract项目,它能识别100多种语言•基于机器学习的多个项目,例如百度的paddlehubtesseract使用比较简单,但是配置相对复杂一下。在Ubuntubionic的安装过程如下。aptinstall-ytesseract-ocrtesseract-v#......
  • Python工具箱系列(五十六)
    抠图抠图是基本需求,最常见的应用场景就是证件照,每次去拍照,都要用个纯色的幕布,而且要求衣服不能太浅。其实背后是有原因的:为了管理部门更准确识别出人像。许多科幻电影也是要求演员在绿幕前表演,后期抠图合成逼真的电影。抠图工具非常多,例如PhotoShop就是抠图利器,可以很神奇地把图......
  • Python工具箱系列(五十七)
    图像分割与人脸识别众所周知图像是由若干有意义的像素组成的,图像分割作为计算机视觉的基础,对具有现有目标和较精确边界的图像进行分割,实现在图像像素级别上的分类任务。图像分割可分为语义分割和实例分割两类,区别如下:语义分割:将图像中每个像素赋予一个类别标签,用不同的颜色来表......
  • 代码随想录刷题学习日记
    仅为个人记录复盘学习历程,解题思路来自代码随想录代码随想录刷题笔记总结网址:代码随想录222.完全二叉树的节点个数给出一个完全二叉树,求出该树的节点个数。提供参数:根结点root主要操作:遍历所有节点,记录节点数。代码(递归法)大致如下:publicintcountNodes(TreeNoder......