作业 1: 员工信息表程序,实现增删改查操作

可进行模糊查询,语法至少支持下面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"

注意:以上需求,要充分使用函数,请尽你的最大限度来减少重复代码

实现了统一入口,自动判断增删改查,输出结果:

详细代码:

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
import os ,sys
BASE_DIR=os.path.dirname(os.path.abspath(__file__))#获取相对路径转为绝对路径赋于变量
sys.path.append(BASE_DIR)#增加环境变量 select_='select'#定义关键字
from_='from'
where_='where'
update_='update'
set_='set'
WHERE_='WHERE'
UPDATE_='UPDATE'
SET_='SET'
delete_='delete'
insert_='insert'
values_='values'
into_='into' def sql_parsing(sql):#sql解析函数 主入口
if sql.startswith('select'):#判断语句类型
_dict_=select_par(sql)#调用相关函数
elif sql.startswith('update') or sql.startswith('UPDATE') :#判断语句类型
_dict_=update_par(sql)
elif sql.startswith('insert'):#判断语句类型
_dict_=insert_par(sql)
elif sql.startswith('delete'):
_dict_=delete_par(sql)
else:
return print('输入有误,请重新输入!')
return _dict_#返回解析完成的列表 def select_par(sql):#select语句的解析函数
list_key=parsing(sql,index_select=-1,index_from=-1,index_where=-1,select_=select_,where_=where_,from_=from_)#查询调用
return list_key
def update_par(sql):#update语句的解析函数
list_key=parsing(sql,index_update=-1,index_set=-1,update_=update_,set_=set_,where_=where_)#更新修改调用
return list_key
def insert_par(sql):#insert语句的解析函数
list_key=parsing(sql,index_insert=-1,index_into=-1,index_values=-1,insert_=insert_,values_=values_)#添加调用
return list_key def delete_par(sql):#delete语句的解析函数
list_key=parsing(sql,index_delete=-1,index_from=-1,index_where=-1,delete_=delete_,where_=where_,from_=from_)#删除调用
return list_key #where子句再格式化
def where_chard(str_list):#where子句再格式化
key=[]#定义一个临时列表变量
list_key=['<','>','=']#运算符
tag=False#定义点为假
str_=''#字符串拼接变量
chrd=''#运算符拼接
for i in str_list:
if i in list_key :#如果点为假,并且在关键字字典中
tag=True#点为真
if len(str_)!=0:#不为空时
key.append(str_)#列表添加字符串
str_=''
chrd+=i#运算符拼接
if not tag :#点为假
str_+=i#字符拼接
if tag and i not in list_key:#如果点为真,并且在不在关键字字典中
tag=False#转为假
key.append(chrd)#关键字字典中所对应的添加这个值
chrd=''
str_+=i
key.append(str_)
if len(key)==1:#判断like运算符
key=key[0].split('like')#用like分割
key.insert(1,'like')
cq='\"'
if cq in key[2]:#判断是否有包含 ”
key[2]=cq_c(key[2],cq)
return key#返回一个列表
#格式化where 子句函数
def where_format(where_list):#格式化where 子句函数
list_format=[]
key_=['and','or','not']
str_=''#字符连接变量
for i in where_list:
if len(i)==0:continue#如果为空就不连接
if i not in key_:##如果不是关键字就进行连接
str_+=i
elif i in key_ and len(str_)!=0:
str_=where_chard(str_)#进行再处理
list_format.append(str_)#之前的字符串添加到列表
list_format.append(i)#关键 字添加到列表
str_=''#清空变量 备用
str_=where_chard(str_)#进行再处理
list_format.append(str_)#最后的字符串
return list_format #格式化select函数
def select_format(select_list):#格式化select函数
if select_list[0]=='*':#如果为* 就不改动
return select_list#直接返回
else:
list_=str_conn(select_list).split(',')#字符串连接函数
return list_
#字符串连接函数
def str_conn(list):
str_=''
for i in list:
str_+=i
return str_ #语句的解析总函数
def parsing(sql,**kwargs):#语句的解析总函数
list_l=sql.split(' ')#分割存为列表
index_from=-1#下标定义from
index_select=-1#select
index_where=-1#where
index_update=-1#update
index_set=-1#set
index_delete=-1#delete
index_insert=-1#insert
index_values=-1#valuse
index_into=-1
list_key={'select':[],'update':[],'delete':[],'insert':[],'set':[],'from':[],'into':[],'where':[],'values':[]}#定义要处理的关键字字典
for index,i in enumerate(list_l):#获取下标
if i==select_:#如果是关键字select字典下标
index_select=index
if i==update_ or i==UPDATE_:#如果是关键字update字典下标,全部转为小写
index_update=index
if i==set_ or i==SET_:
index_set=index
if i==insert_:#如果是关键字insert字典下标
index_insert=index
if i==into_:
index_into=index
if i==values_:
index_values=index
if i==delete_:
index_delete=index
if i==from_:#如果是关键字from字典下标
index_from=index
if i==where_ or i==WHERE_:#如果是关键字where字典下标
index_where=index for index,i in enumerate(list_l):#用下标界定,对进行关键字字典的添加
if index_select !=-1 and index>index_select and index<index_from:#在select和from中添加到select中,不为空时
list_key[select_].append(i)#添加当前值
if index_update !=-1 and index>index_update and index<index_set:#如果是update语句添加一个1值
list_key[update_].append(i)
if index_insert !=-1 and index==index_insert:#如果是insert语句添加一个1值
list_key[insert_].append(1)
if index_into !=-1 and index>index_into and index<index_values:#如果是into后的语句添加一个1值
list_key[into_].append(i)
if index_delete !=-1 and index==index_delete:#如果是delete语句添加一个1值
list_key[delete_].append(1)
if index_from!=-1 and index>index_from and index<index_where:#添加from中的值
list_key[from_].append(i)
if index_set!=-1 and index>index_set and index<index_where:#添加set中的值
list_key[set_].append(i)
if index_where!=-1 and index>index_where:#添加到where列表中
list_key[where_].append(i)
if index_values!=-1 and index>index_values:#添加到values列表中
list_key[values_].append(i)
if list_key.get(where_):#如果字典在的列表不为空
list_key[where_]=where_format(list_key.get(where_))#进行格式化,重新赋于字典,调用格式化函数
if list_key.get(select_):#如果字典select在的列表不为空
list_key[select_]=select_format(list_key.get(select_))#进行格式化,重新赋于字典
if list_key.get(values_):#如果字典values在的列表不为空
list_key[values_]=select_format(list_key.get(values_))#进行格式化,重新赋于字典
if list_key.get(set_):#如果字典set在的列表不为空
list_key[set_]=where_format(list_key.get(set_))#进行格式化,重新赋于字典
return list_key #执行部分 主入口
def sql_perform(sql_dict):#执行函数
if sql_dict[from_]:
file_name='db\\'+sql_dict[from_][0]#获取文件路径
elif sql_dict[into_]:#判断是不是在into里面
file_name='db\\'+sql_dict[into_][0]#获取文件路径
else:
file_name='db\\'+sql_dict[update_][0]#获取文件路径
user_info=open(file_name,'r+',encoding='utf-8')
key=['id','name','age','phone','dept','enroll_date']
if sql_dict[select_]:#不为空,就调用select的函数
perform_select(sql_dict,user_info,key)#传入 字典调用select 函数
user_info.close()#关闭文件
if sql_dict[update_]:#不为空,就调用update的函数
perform_update(sql_dict,user_info,key,file_name)#传入 字典调用update函数
user_info.close()#关闭文件
if sql_dict[insert_]:#不为空,就调用insert的函数
perform_insert(sql_dict,user_info,file_name,key)#传入 字典调用insert函数
if sql_dict[delete_]:#不为空,就调用insert的函数
del_tag=True#标示是删除
perform_update(sql_dict,user_info,key,file_name,del_tag) #执行select操作的函数
def perform_select(sql_dict,user_info,key):#执行select操作的函数
list_l=[]#定义要输出的列表
conut=0#定义计数
for line in user_info:
file=line.strip().split(',')#每一行存为列表
file_dict=dict(zip(key,file))#用zip拉链成字典 file_dict
if sql_dict[where_]:#where条件不为空
where_l=sql_dict[where_]#定义where子句变量
if where_conn(where_l,file_dict):#调用where子句判断函数 如果返回为真
if sql_dict[select_][0]!='*':#如果查询条件不为 *
file.pop(0)#删除ID号
file_dict2=dict(zip(sql_dict[select_],file))#进行对比拼接 如只输出 name age
list_l.append(file_dict2)
else:
list_l.append(file_dict)#添加到输出的列表
conut+=1
for i in list_l:#输出
print(i)
print('总共查询结果数为:%s 条'%conut)
return #返回处理后的信息 #where子句判断函数where函数传入员工字典,where子句
def where_conn(where_l,file_dict):#where子句判断函数where函数传入员工字典,where子句
reg=[]#临时列表
for i in where_l:#循环判断where_l中的条件
if type(i) is list:#判断是否是列表
i_key,conn,i_val=i#三元赋值 key,运算,内容
if i[1]=='=':#如果运算符是 = 进行拼接
conn=i[1]+'='
if file_dict[i_key].isdigit():#如果员工表内键对应的值是整数
dict_vla=int(file_dict[i_key])#员工表内的值赋于一个变量
i_vla=int(i_val)#where条件语句的值赋于一个变量 用于对比
else:#否则
dict_vla="'%s'"%file_dict[i_key]#员工表内键对应的值赋于字符串
if 'like' in i:
if i_val in dict_vla:#如果where条件
i='True'#返回真
else:
i='False'#返回假
else:
i=str(eval("%s%s%s"%(dict_vla,conn,i_val)))#进行员工表与条件的比对 再转为字符串
reg.append(i)#判断后添加到列表
reg=eval(' '.join(reg))#用 join拼接,最后运算
return reg #执行update操作的函数
def perform_update(sql_dict,user_info,key,file_name,tag=False):#执行update操作的函数
list_l=[]#定义要更新的列表
conut=0#定义计数
for line in user_info:
file=line.strip().split(',')#每一行存为列表
file_dict=dict(zip(key,file))#用zip拉链成字典 file_dict
if sql_dict[where_]:#where条件不为空
where_l=sql_dict[where_]#定义where子句变量
set_l=sql_dict[set_]#定义要更新的字符
if where_conn(where_l,file_dict):#调用where子句判断函数 如果返回为真
if tag:#如果为删除标示
line=''
list_l.append(line)#添加到文件列表
conut+=1
else:
line_list=line.split(',')#分割为列表
cq='\"'
if cq in set_l[0][2]:#判断是否有包含 ”
set_l[0][2]=cq_c(set_l[0][2],cq)
for index, i in enumerate(line_list):#判断替换
if i == file_dict[where_l[0][0]]:
line_list[index]=set_l[0][2]#对字典进行替换
line=','.join(line_list)
list_l.append(line)#添加到文件列表
conut+=1
else:
list_l.append(line)
write_file(list_l,file_name)#写入文件函数
if tag:
print('总共删除了 %s 条记录!'%conut)
else:
print('总共更新了 %s 条记录!'%conut)
return #返回处理后的信息
#去 " 函数
def cq_c(set_l,cq):
set__l=''
for i in set_l:
if i==cq:
pass
else:
set__l+=i
return set__l
#写文件函数
def write_file(list_l,file_name):#写文件函数
with open(file_name,'w',encoding='utf-8') as new_file:
for i in list_l:
new_file.write(i)#写入文件
new_file.flush() #执行insert操作的函数
def perform_insert(sql_dict,user_info,file_name,key):#执行insert操作的函数
list_user=sql_dict[values_]#提取要更新的列表
phone_=list_user[2]#提取电话号码
conut=1
tag=True
for line in user_info:
conut+=1#统计行数
file=line.strip().split(',')#每一行存为列表
file_dict=dict(zip(key,file))#用zip拉链成字典 file_dict
if phone_==file_dict['phone']:#如果有存在
tag=False
break
else:
pass
if tag:#如果检测结果为真才能添加\
list_user.insert(0,str(conut))#将字ID插入列表
str_user='\n%s'%','.join(list_user)#需要加回车
user_info.close()#关闭文件
with open(file_name,'a',encoding='utf-8') as file_a:
file_a.write(str_user)#
file_a.flush()
return print('信息已经更新!')
else:
return print('电话号码已经存在,请重新输入!') #执行delete操作的函数
def perform_delete(sql_dict):#执行delete操作的函数
select_dict=sql_dict
return select_dict#返回处理后的信息 #程序开始
print("\033[35;1m欢迎进入员工信息表查询系统\033[0m".center(60,'='))
if __name__ =='__main__':
while True:
print('查询修改示例'.center(50,'-').center(60,' '))
print('''
\033[32;1m1、【查】: select name,age from staff_table where age>22 and age<35 or name like li\033[0m
\033[33;1m2、【改】: UPDATE staff_table SET dept="Market" WHERE dept="IT"\033[0m
\033[34;1m3、【增】: insert into staff_table values Alex Li,22,13651054608,IT,2013-04-01\033[0m
\033[31;1m3、【删】: delete from staff_table where id=5 \033[0m
\033[37;1m4、【退】: exit\033[0m
''')
sql=input('sql->').strip()#定义显示提示符
if sql=='exit':break#如果输入exit退出
if sql==0:continue#如何没输入重新提示
sql_dict=sql_parsing(sql)#解析输入的sql语句 赋于变量
try:
sql_action=sql_perform(sql_dict)#执行解析后的语句 传入解析后的变量
except Exception as e:
print('你的输入格式有误,请重新输入!')

两天半时间才搞定,休息一下下

python第十六天,昨天来晚了,作业终于完成了的更多相关文章

  1. Python第二十六天 python装饰器

    Python第二十六天 python装饰器 装饰器Python 2.4 开始提供了装饰器( decorator ),装饰器作为修改函数的一种便捷方式,为工程师编写程序提供了便利性和灵活性装饰器本质上就 ...

  2. 孤荷凌寒自学python第二十六天python的time模块的相关方法

    孤荷凌寒自学python第二十六天python的time模块的相关方法 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 要使用time模块的相关方法,必须在文件顶端引用: import tim ...

  3. 孤荷凌寒自学python第十六天python的迭代对象

    孤荷凌寒自学python第十六天python的迭代对象 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 迭代也就是循环. python中的迭代对象有相关的如下几个术语: A容器 contrai ...

  4. Python第十六天 类的实例化

    首先 , 先定义一个 简单的 Person 类 class Person: head = 1 ear = 2 def eat(self): print('吃饭') 关于什么是类, 定义类, 类对象,类 ...

  5. python第九十六天 ---Django(1)

    django 模块 一  安装: pip3 install django 或 python -m pip install django 二  添加环境变量 相关命令: #cmd 下 django-ad ...

  6. 学习python第十六天,正则表达式

    正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配.采取动态模糊的匹配,最大的应用是爬虫. re 模块使 Python 语言拥有全部的正则表达式功能. compile 函 ...

  7. python第十六天

    一.包 1.什么是包? 一系列模块的集合 2.有什么用? 包通过文件夹来管理一系列功能相近的模块 3.包重点? 包中一定有一个专门用来管理包中所有模块的文件   __init__ 4.什么是包名? 包 ...

  8. 孤荷凌寒自学python第八十六天对selenium模块进行较详细的了解

    孤荷凌寒自学python第八十六天对selenium模块进行较详细的了解 (今天由于文中所阐述的原因没有进行屏幕录屏,见谅) 为了能够使用selenium模块进行真正的操作,今天主要大范围搜索资料进行 ...

  9. 孤荷凌寒自学python第七十六天开始写Python的第一个爬虫6

    孤荷凌寒自学python第七十六天开始写Python的第一个爬虫6 (完整学习过程屏幕记录视频地址在文末) 今天在上一天的基础上继续完成对我的第一个代码程序的书写. 不过由于对python-docx模 ...

随机推荐

  1. Spring Data JPA例子[基于Spring Boot、Mysql]

    关于Spring Data Spring社区的一个顶级工程,主要用于简化数据(关系型&非关系型)访问,如果我们使用Spring Data来开发程序的话,那么可以省去很多低级别的数据访问操作,如 ...

  2. Kafka实战-Storm Cluster

    1.概述 在<Kafka实战-实时日志统计流程>一文中,谈到了Storm的相关问题,在完成实时日志统计时,我们需要用到Storm去消费Kafka Cluster中的数据,所以,这里我单独给 ...

  3. rhel 配置centos源

    1.删除自带的yum包,清除/etc/yum.repos.d下面的文件 rpm -qa|grep yum|xargs rpm -e --nodeps(不检查依赖,直接删除rpm包) 2.安装cento ...

  4. linux有名管道fifo,进程间通信

    命名管道(FIFO)不同于无名管道之处在于它提供了一个路径名与之关联,以 FIFO 的文件形式存在于文件系统中,这样,即使与 FIFO 的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通 ...

  5. Windows系统环境下创建mysql主从数据库方法(双向主从复制)

    创建mysql主从数据库方法(双向主从复制) (一)Windows系统下的MySQL主从复制(单向复制) (1)环境说明: 1,Mysql版本:mysql5.7.20(主从机mysql版本必须一致) ...

  6. php生成mysql数据字典

    <?php /** * 生成mysql数据字典 */ // 配置数据库 $database = array(); $database['DB_HOST'] = '127.0.0.1'; $dat ...

  7. MySQL 解压缩版安装 2017-12-02(完整版,包括异常处理)

    一.安装 1.到mysql官网 http://dev.mysql.com/downloads/mysql/ 下载mysql 注:msi的是安装版     zip是压缩版 2.解压 解压到想安装的目录下 ...

  8. WEB安全:Tomcat 只可通过域名访问,禁止通过 IP 访问

    服务器为什么要禁止通过IP直接访问? 1.若公布于外网的服务器IP地址未备案,就有可能被工信部查封.这样备案的域名也会无法访问. 2.如果AppScan通过ip访问扫描,会有“发现内部ip泄露模式”的 ...

  9. netty源码解解析(4.0)-10 ChannelPipleline的默认实现--事件传递及处理

    事件触发.传递.处理是DefaultChannelPipleline实现的另一个核心能力.在前面在章节中粗略地讲过了事件的处理流程,本章将会详细地分析其中的所有关键细节.这些关键点包括: 事件触发接口 ...

  10. Vim 字符串替换命令

    命令模式下输入如下命令可实现替换: s/str1/str2/ 替换当前行第一个 str1 为 str2 s/str1/str2/g 替换当前行中所有的 str1 为 str2 m,ns/str1/st ...