最近接了个小需求,用pandas处理csv文件,以前都是用其他库,这次特意学习了下pandas,果然很香~~~
读取的文件格式:
实现功能如下,涵盖了基本的增删改查,调整位置
"""
a) 当该数据集中没有找到自己想要的诗词,可以进行增加 操作
b)删除自己的不感兴趣或者不需要的诗词
c)对数据集的具体位置进行修改,例如修改列表索引
d) 查找自己想要的内容,例如查找所有 “李白”的诗词,查找所有“宋朝”的诗词等
e)诗词小游戏,内置李白的诗词库,每次闯关都可获得金币和分数,连续闯过的关卡越多,获得越多,金币可以用购买新的诗词库
"""
# 导入要用到的包
import pandas as pd
import random
GLOD_COINS_TO_BUY_NEW_POETRY = 10 # 设置猜诗词游戏中,购买新诗人的金币数量
GLOD_COINS_REWARD = 5 # 答对一次,增加的金币数
class PoetryProject:
"""
一个诗词小程序
"""
def __init__(self):
self.data_source = '古诗词数据集/all.csv' # 要读取的文件
self.data_frame = self.load_data() # 根据上面的文件,读取数据
self.gold_coins = 0 # 设置游戏一开始就拥有的金币数
def load_data(self):
"""
加载数据,从excel里面读取
:return:
"""
df = pd.read_csv(self.data_source)
return df
def save_data(self):
"""
存储数据,写入到文件中
:return:
"""
self.data_frame.to_csv(self.data_source, encoding='utf-8', index=False) # 保持数据,去掉索引
def filter(self, type, key):
"""
过滤数据
:param type: 1-搜索题目、2-搜索作者、3-搜索诗词内容、4-搜索朝代
:param key:
:return:
"""
result = None
if type == 1:
result = self.data_frame.query('题目.str.contains("{}", na=False)'.format(key))
if type == 2:
result = self.data_frame.query('作者.str.contains("{}", na=False)'.format(key))
if type == 3:
result = self.data_frame.query('内容.str.contains("{}", na=False)'.format(key))
if type == 4:
result = self.data_frame.query('朝代.str.contains("{}", na=False)'.format(key))
self.format_print(result)
def add(self, title, dynasty, author, content):
"""
增加数据
:return:
"""
last_index = self.data_frame.index[-1] + 1 # 计算出最新的索引
# 对内容进行处理,替换英文符合
content = content.replace(',', ',').replace('.', '。')
# 最后一个字符要为句号
if content[-1] != '。':
content += '。'
self.data_frame.loc[last_index] = [title, dynasty, author, content] # 赋值给最后的索引
self.save_data() # 保存数据
def delete(self, index):
"""
删除数据
:param id:
:return:
"""
self.data_frame.drop(self.data_frame.index[index], inplace=True) # 删除数据
self.save_data() # 保存数据
def update(self, old_index, new_index):
"""
修改索引
:return:
"""
old_values = self.data_frame.loc[old_index].values # 保持旧位置的数据
self.delete(old_index) # 删除旧位置的数据
self.data_frame.reset_index(inplace=True, drop=True) # 重置索引
# 切割插入数据
df1 = self.data_frame.iloc[:new_index] # 取前面的数据
df1.loc[new_index] = old_values # 对应索引更新为最新的值
df2 = self.data_frame.iloc[new_index:] # 取后面的数据
self.data_frame = df1.append(df2) # 合并两个数据
self.data_frame.reset_index(inplace=True, drop=True) # 重置索引
# print(self.data_frame)
def game(self):
"""
进入游戏
:return:
"""
all_authors = ['李白']
while True:
choice = input('输入1进入游戏,输入2购买其他诗人诗词,输入3退出游戏 \n >>')
if choice == '1':
# 初始化文件
# game_file = 'game_log.csv'
poetry_statements = {} # 以上句为key,下句为value
print('小游戏中默认已有 {} 的诗词, 如需更多诗人的诗词,通关后可以累计金币进行购买,游戏说明:\n'
'1、系统随机给出上句,玩家写出下句\n'
'2、答对可得{}个金币,答错则没有金币\n'
'3、当金币大于{}个时,可购买其他诗人的诗词\n'
''.format(all_authors, GLOD_COINS_REWARD, GLOD_COINS_TO_BUY_NEW_POETRY))
poetrys = self.data_frame[self.data_frame.作者.isin(all_authors)] # 根据当前已有的作者,查询出他们的诗词
for value in poetrys['内容']: # 循环查询出来的诗句
# print(value)
contents = value.split('。') # 根据句号分隔出一对一对的诗歌
for con in contents: # 循环分隔出来的每一对诗歌
if not con: # 排除空值
continue
print(con)
try:
c1, c2 = con.split(',') # 每一对诗歌,根据逗号,分离出上句和下句
if c1 not in poetry_statements: # 上句为key,下句为value,存入到字典中
poetry_statements[c1] = c2
except Exception as e:
pass
# print(poetrys)
random_pre = random.sample(poetry_statements.keys(), 1)[0] # 从字典中随机获取一条数据
answer = input('请输入 {} 的下一句: >>'.format(random_pre)).strip() # 给出上句,提示输入下句
if answer == poetry_statements[random_pre]: # 答对,则增加金币
self.gold_coins += GLOD_COINS_REWARD
print('回答正确,金币加{} ,当前拥有金币 {} 个'.format(GLOD_COINS_REWARD, self.gold_coins))
else:
print('输入错误,正确答案为 "{}", 本次不得金币, 当前金币 {} 个!'.format( # 回答错误,则给出正确答案
poetry_statements[random_pre], self.gold_coins))
if choice == '2': # 购买新的诗人的诗词
if self.gold_coins < GLOD_COINS_TO_BUY_NEW_POETRY:
print('当前金币{}个,不足10个,无法购买'.format(self.gold_coins))
continue
authors_can_buy = set(self.data_frame['作者'].values.tolist()) # 查询出所有的诗人后,进行去重
print('可选作者有 :{}'.format(authors_can_buy))
author_to_buy = input('输入要购买的诗人姓名: \n >>')
if author_to_buy not in authors_can_buy:
author_to_buy = input('输入有误,请重新输入要购买的诗人姓名: \n >>')
if author_to_buy not in all_authors: # 如果诗人不在当前列表中,可以购买
all_authors.append(author_to_buy)
self.gold_coins -= 10
print('购买成功,当前剩余金币{}个'.format(self.gold_coins))
print('当前已有诗人: {}'.format(all_authors))
else: # 诗人已经存在了,则不需要再买了
print('{} 已存在,无需购买'.format(author_to_buy))
continue
if choice == '3':
break
def format_print(self, data_frame):
"""
格式化一下输出
:return:
"""
print('格式化后输出如下: \n')
print('*' * 100)
print('{}\n'.format(data_frame))
print('*' * 100)
if __name__ == '__main__':
while True:
while True:
num = input('欢迎使用本程序,请选择对应的操作项: \n 输入 1 进行搜索 \n 输入 2 进行新增 \n 输入 3 进行删除 \n 输入 4 进行修改位置 \n '
'输入 5 进行诗词对一对游戏 \n 输入 6 进行退出 \n>>')
try:
num = int(num)
except Exception as e:
print('输入了非数字,请重新输入~')
continue
if num not in [1, 2, 3, 4, 5, 6]:
print('输入了非法操作项,请重新输入~')
else:
break
poetry_game = PoetryProject()
if num == 1: # 查询
while True:
type = input('请选择对应的操作项: \n 输入 1 搜索题目 \n 输入 2 搜索作者 \n 输入 3 搜索诗词内容 \n >>')
try:
type = int(type)
except Exception as e:
print('输入了非数字,请重新输入~')
continue
if type not in [1, 2, 3, 4, 5, 6]:
print('输入了非法操作项,请重新输入~')
else:
break
content = input('请输入搜索内容>> ')
poetry_game.filter(type, content)
if num == 2: # 新增
title = input('请输入题目>> ').strip()
if not title:
title = input('题目不能为空, 请重新输入>> ').strip()
dynasty = input('请输入朝代>> ').strip()
if not dynasty:
dynasty = input('朝代不能为空, 请重新输入>> ').strip()
author = input('请输入作者>> ').strip()
if not author:
author = input('作者不能为空, 请重新输入>> ').strip()
content = input('请输入内容>> ').strip()
if not content:
content = input('内容不能为空, 请重新输入>> ').strip()
poetry_game.add(title, dynasty, author, content)
print('新增诗词成功!')
if num == 3: # 删除
poetry_game.format_print(poetry_game.data_frame)
index = input('请输入诗词索引进行删除>> ').strip()
if not index:
index = input('索引不能为空, 请重新输入>> ').strip()
if int(index) not in poetry_game.data_frame.index.to_list():
index = input('索引不存在, 请重新输入>> ').strip()
index = int(index)
poetry_game.delete(index)
print('删除诗词成功!')
poetry_game.format_print(poetry_game.data_frame)
if num == 4: # 修改位置
poetry_game.format_print(poetry_game.data_frame)
old_index = input('输入旧诗词的索引值>> ')
new_index = input('输入新诗词的索引值>> ')
poetry_game.update(int(old_index), int(new_index))
print('更新位置成功!')
poetry_game.format_print(poetry_game.data_frame)
if num == 5: # 游戏
poetry_game.game()
if num == 6:
break