作业 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. Sublime Text3自定义全部字体大小、字体类型和背景颜色

    一.定义侧栏的背景颜色.字体大小和间距 Sublime Text3的Afterglow主题链接为:https://github.com/YabataDesign/afterglow-theme 1.按 ...

  2. Android应用内实现视频播放--腾讯浏览服务(TBS)

    TBS视频播放 TBS视频播放器可以支持市面上几乎所有的视频格式,包括mp4, flv, avi, 3gp, webm, ts, ogv, m3u8, asf, wmv, rm, rmvb, mov, ...

  3. leetCode(寻找峰值)-二分查找

    题目: 峰值元素是指其值大于左右相邻值的元素. 给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引. 数组可能包含多个峰值,在这种情况下,返回任何一个峰 ...

  4. Angular2入门:TypeScript的类型 - 对象解构

  5. Java可以像Python一样方便爬去世间万物

    前言: 之前在大二的时候,接触到了Python语言,主要是接触Python爬虫那一块 比如我们常用的requests,re,beautifulsoup库等等 当时为了清理数据和效率,还专门学了正则表达 ...

  6. [POI2006] PRO-Professor Szu

    Description \(n\) 个别墅以及一个主建筑楼,从每个别墅都有很多种不同方式走到主建筑楼,其中不同的定义是(每条边可以走多次,如果走边的顺序有一条不同即称两方式不同). 询问最多的不同方式 ...

  7. Git Extensions system.invalidoperationexception尚未提供文件名,因此无法启动进程

    根据别人的博客按照步骤安装,地址如下:http://www.cnblogs.com/sorex/archive/2011/08/10/2132359.html 但是安装Git Extensions后生 ...

  8. 基于Visual Studio .NET2015的单元测试

    基于Visual Studio .NET2015的单元测试 1.    在Visual Studio .NET2015中创建任意项目. 2.    在某个公共类的公共方法的名称上面点击右键,选择“创建 ...

  9. 2、买卖股票的最佳时机 II

    2.买卖股票的最佳时机 II 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖一支股票). 注意:你不能 ...

  10. 【协议】4、http状态码

    10.4 客户错误 4xx 状态代码4xx类是专门使用在客户看上去错误的情形下的.除非当应答一个HEAD请求时,服务器因该有一个包括错误情形的解释的实体,以及它是否一个临时或者终了的条件.这些状态编码 ...