使用python制作题库软件且调用智谱api,并打包成exe文件

引言

        俗话说得好,学以致用,不去实践,又怎会体验理论知识是否真的掌握,还有一句话,叫实践是检验真理的唯一标准,所以老师给我们一个选择,是选择制作软件还是写试卷。
        众所周知,当代大学生,从小考到大,确实不爱考试,因此基于以上两个原因,我选择做这个大作业。
        这就是需求分析,但是在软件开发中,大部分的需求都来源于客户,而非我们开发者,这也就意味着,就软件危机问题来说,我们具有更强的优势,我们熟知软件运行的内部规律。
        其实关于需求分析和可行性分析这一块,我有这自己的理解,我个人认为这没有绝对的先后顺序,就以上例子来说,我先做需求分析,我要确定我为什么要做这个,接着考虑做什么,是否可行。
        我期待制作一个题库软件,最开始的时候,我在网上找到了两个很好的例子,一个是纯前端的,另一个是基于Python。
        这里有一个不幸的消息和一个幸运的消息。幸运地是作者基于好奇心,学过一点Python和前端三大件。不幸地是作者学艺不精,是个半桶水,看着这一坨代码(会理解这个量词的,对吧),想死的心熊熊燃烧。最后也扯出来了,但是只能说不完美,时间有限,很多远大的抱负,终究只能留在以后了。
        我们上一次课老师说,一定要做出来吗?老师和我们说她读研的时候,做了9个月的实验,却没有结果,她去问她老师,她老师反问一定要做出来吗?做不出来其实没有关系,重要的是这个过程,你的理解,你的总结,你的反思。当你明白了为什么会失败,为什么做不到,这也是一种修行,一种学习,也可以毕业。其实有的时候,反思与总结更难写。

不扯废话了,下面开始正题

1.Python代码

这个代码不长,我就直接粘贴复制过来了,最开始是自建数据库,而我想要做到的是使用文件

来自 《Python项目案例开发从入门到实战》(清华大学出版社 郑秋生 夏敏捷主编)中 数据库应用--智力问答测试

注意: 要使代码运行成功,需要先看上一篇文章 python生成数据库(python generate database) 先生成 test_bank.db 数据库才可以运行成功

来自:https://www.cnblogs.com/ttweixiao-IT-program/p/13469412.html

import sqlite3   # 导入数据库相关的包

# 连接到sqlite3数据库,数据库的名称是 test_bank.db ,如果该数据库不存在,则会自动创建
conn = sqlite3.connect('test_bank.db')
# 创建一个cursor
cursor = conn.cursor()
# 删除test_bank中的exam表格,如果不存在则会报错,所以本地如果没有test_bank.db数据库则需要注释这一条语句
cursor.execute("drop table exam")
# 创建exam表格并且定义它的格式
cursor.execute('create table [exam] ([question] varchar(80) null,   \
                [Answer_A] varchar(1) null, [Answer_B] varchar(1) null,  \
                [Answer_C] varchar(1) null, [Answer_D] varchar(1) null, [right_Answer] varchar(1) null)')
# 继续执行一条SQL语句,插入一条记录
cursor.execute("insert into exam (question, Answer_A, Answer_B, Answer_C, Answer_D, right_Answer) \
                values ('哈雷彗星的平均周期为', '54年', '56年', '73年', '83年', 'C')")
cursor.execute("insert into exam (question, Answer_A, Answer_B, Answer_C, Answer_D, right_Answer) \
                values ('夜郎自大中“夜郎”指的是现在哪个地方', '贵州', '云南', '广西', '福建', 'A')")
cursor.execute("insert into exam (question, Answer_A, Answer_B, Answer_C, Answer_D, right_Answer) \
                values ('在中国历史上是谁发明了麻药', '孙思邈', '华佗', '张仲景', '扁鹊', 'A')")
cursor.execute("insert into exam (question, Answer_A, Answer_B, Answer_C, Answer_D, right_Answer) \
                values ('京剧中花旦是指', '年轻男子', '年轻女子', '年长男子', '年长女子', 'B')")
cursor.execute("insert into exam (question, Answer_A, Answer_B, Answer_C, Answer_D, right_Answer) \
                values ('篮球比赛每队几人', '4', '5', '6', '7', 'B')")
cursor.execute("insert into exam (question, Answer_A, Answer_B, Answer_C, Answer_D, right_Answer) \
                values ('在天愿作比翼鸟,在地愿为连理枝。讲述的是谁的爱情故事', '焦仲卿和刘兰芝', '梁山伯与祝英台', '崔莺莺和张生', '杨贵妃和唐明皇', 'D')")

# 通过rowcount获得插入的行数
print(cursor.rowcount)

# 关闭游标对象
cursor.close()
# 事务提交
conn.commit()
# 关闭数据库链接对象
conn.close()
import tkinter  # Tkinter模块是python的标准Tk GUI工具包的接口
# from tkinter import *
# from tkinter.messagebox import *
from tkinter import messagebox
import sqlite3


# 调用下一道题目函数
def callNext():
    # 设置k和score为全局变量
    global k
    global score
    # 得到单选按钮的结果
    useranswer = r.get()
    print(r.get())

    # 判断答案是否为空
    if useranswer == 'E':
        messagebox.showinfo("出错", "请先完成本题")
    # 判断答案是否等于正确答案
    elif useranswer == values[k][5]:
        # 如果相同则提示答对信息,messagebox是消息窗口组件
        messagebox.showinfo("恭喜", "恭喜你对了")
        # 添加分数
        score += 10
        # 跳转到下一题
        k = k + 1
    else:
        # 打错了则提示错误提示
        messagebox.showinfo("遗憾", "遗憾你错了")
        # 跳转到下一题
        k = k + 1

    # 判断是否是最后一道题目
    if k >= len(values):
        messagebox.showinfo("提示", "题目做完了")
        return
    # 修改timu, radio1, radio2, radio3, radio4中的文本值
    timu["text"] = values[k][0]
    radio1["text"] = values[k][1]
    radio2["text"] = values[k][2]
    radio3["text"] = values[k][3]
    radio4["text"] = values[k][4]
    # 默认值还是设置为没有选中
    r.set('E')


# 查看结果函数
def callResult():
    tkinter.messagebox.showinfo("你的得分", str(score))


# 连接到 test_bank 数据库
conn = sqlite3.connect('test_bank.db')
# 创建游标对象
cursor = conn.cursor()
# 查询 exam 数据库表
cursor.execute('select * from exam')
# 提取查询到的数据存在values变量中
values = cursor.fetchall()
# 关闭cursor对象
cursor.close()
# 关闭connect对象
conn.close()

# 创建窗口对象
root = tkinter.Tk()
# 设置窗口标题
root.title('Python 智力问答游戏')
# 设置初始窗口大小为500*200
root.geometry("500x200")
# 创建一个StringVar()对象
r = tkinter.StringVar()
# 设置初始值为'E',即没有选中
r.set('E')
# 记录当前的题目指数
k = 0
# 记录得到的分数值
score = 0
# Label是标签组件,可以显示文本和位图
# 新建timu标签组件,标签的文本值是values中的[k][0]
timu = tkinter.Label(root, text=values[k][0])
# 将timu标签组件添加到窗口中显示
timu.pack()
# Frame是框架控件,在屏幕上显示一个矩形区域,多用来作为容器
# 新建第一个Frame组件
f1 = tkinter.Frame(root)
# 将组件添加到窗口中显示
f1.pack()
# Radiobutton是单选按钮控件,显示一个单选的按钮状态
# 用户可以使用variable属性为Radiobutton组件指定一个对应的变量。如果将多个Radiobutton组件绑定到同一个变量,则这些Radiobutton组件
# 属于一个分组,分组后需要使用value设置每个Radiobutton的值,以标识该项目是否被选中。
# 在框架控件f1中新建一个单选的按钮控件,并且指定单选按钮按下的变量值,单选按钮选中时变量的值value和单选按钮显示的文本内容text
radio1 = tkinter.Radiobutton(f1, variable=r, value='A', text=values[k][1])
# 将组件添加到窗口中显示
radio1.pack()
# 在框架控件f1中新建一个单选的按钮控件,并且指定单选按钮按下的变量值,单选按钮选中时变量的值value和单选按钮显示的文本内容text
radio2 = tkinter.Radiobutton(f1, variable=r, value='B', text=values[k][2])
# 将组件添加到窗口中显示
radio2.pack()
# 在框架控件f1中新建一个单选的按钮控件,并且指定单选按钮按下的变量值,单选按钮选中时变量的值value和单选按钮显示的文本内容text
radio3 = tkinter.Radiobutton(f1, variable=r, value='C', text=values[k][3])
# 将组件添加到窗口中显示
radio3.pack()
# 在框架控件f1中新建一个单选的按钮控件,并且指定单选按钮按下的变量值,单选按钮选中时变量的值value和单选按钮显示的文本内容text
radio4 = tkinter.Radiobutton(f1, variable=r, value='D', text=values[k][4])
# 将组件添加到窗口中显示
radio4.pack()

# 创建第2个Frame框架组件
f2 = tkinter.Frame(root)
# 将组件添加到窗口中显示
f2.pack()
# 在f2框架上新建Button组件,text表示按钮显示的内容,command表示点击按钮时执行的函数,side表示将Button组件添加到窗口中显示,左停靠
tkinter.Button(f2, text='下一题', command=callNext).pack(side=tkinter.LEFT)
# 在f2框架上新建Button组件,text表示按钮显示的内容,command表示点击按钮时执行的函数,side表示将Button组件添加到窗口中显示,左停靠
tkinter.Button(f2, text='结 果', command=callResult).pack(side=tkinter.LEFT)

# 进入消息循环,也就是显示窗口
root.mainloop()

生成试题库以及界面代码:

23450bc047fa4868809f87a991404b12.png

2.改动后代码

import csv
import tkinter as tk
from tkinter import messagebox, simpledialog, LEFT, FLAT, W
import zhipuai


# 接入智谱api
zhipuai.api_key ="29eded8046fdf6594c116dc72fb9b4b3.vaVMYwhEKYsRVV1Y"#填写控制台中获取的 APIKey 信息
model ="chatglm_std"#用于配置大模型版本

text_area = None
# 读取CSV文件并初始化数据
with open('22.csv', 'r') as file:
    csv_reader = csv.reader(file)
    next(csv_reader)  # 跳过标题行
    data = list(csv_reader)
    print(data)
    rowcount = len(data)
    print(rowcount)
# 定义一个函数来获取用户输入并调用 zhipuai API 并显示结果
def call_zhipuai_api():
    # 使用 simpledialog 来获取用户输入
    user_input = simpledialog.askstring("输入", "请输入您的问题:", parent=root)
    if user_input is None:
        messagebox.showinfo("提示", "输入被取消")
        return

    # 调用 API 并显示结果
    question = getText("user", user_input)
    response = zhipuai.model_api.invoke(
        model=model,
        prompt=question
    )

    response = response.get('data', {}).get('choices', [{}])[0].get('content', '')

    messagebox.showinfo("问题回答", response)  # 显示响应
    print(response)
def getText(role, content):
    # 创建字典来存储角色和内容
    text = {"role": role, "content": content}
    return text
# 定义一个函数来显示响应


# 定义上一题函数
def callPrevious():
    global k
    if k == 0:
        messagebox.showinfo("提示", "已经是第一题了")
    else:
        k -= 1
        timu["text"] = data[k][0]
        radio1["text"] = data[k][1]
        radio2["text"] = data[k][2]
        radio3["text"] = data[k][3]
        radio4["text"] = data[k][4]
        r.set('E')

# 定义下一题函数
def callNext():
    global k
    global score
    useranswer = r.get()
    if useranswer == 'E':
        messagebox.showinfo("出错", "请先完成本题")
    elif useranswer == data[k][5]:
        messagebox.showinfo("恭喜", "恭喜你对了")
        score += 1
        k += 1
    else:
        messagebox.showinfo("遗憾", "遗憾你错了")
        k += 1

    if k >= rowcount:
        messagebox.showinfo("提示", "题目做完了")
    else:
        timu["text"] = data[k][0]
        radio1["text"] = data[k][1]
        radio2["text"] = data[k][2]
        radio3["text"] = data[k][3]
        radio4["text"] = data[k][4]
        r.set('E')

# 查看结果函数
def callResult():
    messagebox.showinfo("你的得分", f"你的得分是:{score}")
# 定义弹出正确答案的函数
def showAnswer():
    messagebox.showinfo("正确答案", data[k][5])


# 创建窗口对象
root = tk.Tk()
root.title('软件工程期末备考题库')
root.geometry("1000x600")

# 创建一个StringVar()对象
r = tk.StringVar()
r.set('E')

# 初始化题目索引和得分
k = 0
score = 0

# 创建题目标签
timu1 = tk.Label(root, text="温馨提示:本题库包含第一章到第七章一共50道的课后习题之单选题,其中第三章不是重点内容", font=('宋体', 10),  fg='red',justify=LEFT)
timu1.pack(anchor=W)
timu = tk.Label(root, text=data[k][0], font=('黑体', 20, 'bold'), wraplength=1000, justify=LEFT)
timu.pack(anchor=W, pady=(100, 0), padx=30)


# 创建选项框架
f1 = tk.Frame(root, relief=FLAT, borderwidth=10)
f1.pack(fill='x', expand=True)

# 创建单选按钮
radio1 = tk.Radiobutton(f1, variable=r, value='A', text=data[k][1], font=('宋体', 18), relief=FLAT, borderwidth=10)
radio1.pack(anchor=W, pady=(10, 0), padx=30)

radio2 = tk.Radiobutton(f1, variable=r, value='B', text=data[k][2], font=('宋体', 18), relief=FLAT, borderwidth=10)
radio2.pack(anchor=W, pady=(10, 0), padx=30)

radio3 = tk.Radiobutton(f1, variable=r, value='C', text=data[k][3], font=('宋体', 18), relief=FLAT, borderwidth=10)
radio3.pack(anchor=W, pady=(10, 0), padx=30)

radio4 = tk.Radiobutton(f1, variable=r, value='D', text=data[k][4], font=('宋体', 18), relief=FLAT, borderwidth=10)
radio4.pack(anchor=W, pady=(10, 0), padx=30)

# 创建按钮框架
f2 = tk.Frame(root, relief=FLAT, borderwidth=10)
f2.pack(fill='x', expand=True)

# 创建上一题按钮,设置椭圆样式和背景颜色
previous_button = tk.Button(f2, text='上一题', font=('黑体', 20), command=callPrevious, bg='lightgreen', fg='white', relief=FLAT, borderwidth=0, compound='c')
previous_button.pack(side=tk.LEFT, padx=10, pady=20)

# 创建下一题按钮,设置椭圆样式和背景颜色
next_button = tk.Button(f2, text='下一题', font=('黑体', 20), command=callNext, bg='lightblue', fg='white', relief=FLAT, borderwidth=0, compound='c')
next_button.pack(side=tk.LEFT, padx=10, pady=20)

# 创建答案按钮,设置椭圆样式和背景颜色
answer_button = tk.Button(f2, text='答 案', font=('黑体', 20), command=showAnswer, bg='lightcoral', fg='white', relief=FLAT, borderwidth=0, compound='c')
answer_button.pack(side=tk.RIGHT, padx=10, pady=20)

# 创建查看得分按钮,设置椭圆样式和背景颜色
result_button = tk.Button(f2, text='得 分', font=('黑体', 20), command=callResult, bg='mediumpurple', fg='white', relief=FLAT, borderwidth=0, compound='c')
result_button.pack(side=tk.RIGHT, padx=10, pady=20)
# 创建调用 API 的按钮
api_button = tk.Button(root, text='解答疑问', command=call_zhipuai_api,  font=('黑体', 15), bg='mediumvioletred', fg='white', relief=FLAT, borderwidth=0)
api_button.pack()

# 进入消息循环
root.mainloop()

        原理的话,就是最开始需要自己生成数据库,我嫌弃太麻烦了,就尝试着,引入csv文件,然后读取相关数据赋予不同的变量,然后通过tkinter包来设计页面,这里非常感谢我的同学,提供了一个很有意思的网站Tkinter布局助手 ~ 一款在线设计仅需拖拽就能生成Tkinter布局的小工具。可以自动生成页面布局代码,奈何作者水平有限,不太会代入,老是报错。最后丢给了kimi#小程序://Kimi/05B57TWwNgj3dJg帮我优化页面,效果如下:

044c32c03f5f4ce89e821a0e840fd230.png

接着往下说,使用智谱的效果。

a4178b2086f445589f0c8bf48f814f1a.png

187d9d39636b4cf5859b50835371f663.png
结语

我想讲一下关于智谱api的调用,这个最烦恼。但是成功后还是很有成就感的。

1.安装

        pip install -i https://pypi.douban.com/simple/ zhipuai

不推荐这种,建议去pycharm里面下载,选择版本1.0.7
因为新版本把model_api这个用法改了,会报错,怪难受的

2.注册

        进入智普AI:https://open.bigmodel.cn/,然后实名认证送一个月的token

3.复制代码,运行

4.重点,程序打包(如何多文件打包并成功运行)

        安装包:pip install -i https://pypi.douban.com/simple/pyinstaller

        找到py文件所在的文件夹,在        68950e9c72854f8e8b51146b9c099ccc.png

        上述地址栏,敲cmd,即将D:\MATLAB\pythonProject5替换成cmd,进入终端。

        输入:pyinstaller -F -w -i chengzi.ico --add-data "22.csv;." 33.py

        注意:如果你没有多文件,就不必有--add-data "22.csv;,如果你不想软件有图标,就不必有-i chengzi.ico,如果你想有记得保存图片在同一个文件夹且确定好后缀

        最重要的是多文件,最后生成的在一个dist文件中,需要将你引用的文件存放进去!!!

82c43dde689946dba77983a427cad4f9.png

        否则,将无法运行!

5.页面优化

        用户是看不见你的后端写得怎么样,所以判断的依据就是你的前端是否美观(装逼一下)

附录

以下是一些 Tkinter 预定义的颜色名称的例子:

```plaintext
'white', 'black', 'red', 'green', 'yellow', 'blue',
'magenta', 'cyan', 'gray', 'grey', 'darkred', 'darkgreen',
'darkblue', 'lightgrey', 'lightgray', 'antiquewhite', 'aqua',
'aquamarine', 'azure', 'beige', 'bisque', 'blanchedalmond',
'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse',
'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson',
'darkgoldenrod', 'darkgray', 'darkgreen', 'darkgrey', 'darkkhaki',
'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darksalmon',
'darkseagreen', 'darkslateblue', 'darkslategray', 'darkslategrey', 'darkturquoise',
'darkviolet', 'deeppink', 'deepskyblue', 'dimgray', 'dimgrey',
'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen', 'fuchsia',
'gainsboro', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'grey',
'greenyellow', 'honeydew', 'hotpink', 'indianred', 'indigo',
'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon',
'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrodyellow', 'lightgray',
'lightgrey', 'lightgreen', 'lightpink', 'lightsalmon', 'lightseagreen',
'lightskyblue', 'lightslategray', 'lightslategrey', 'lightsteelblue', 'lightyellow',
'lime', 'limegreen', 'linen', 'maroon', 'mediumaquamarine', 'mediumblue',
'mediumorchid', 'mediumpurple', 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen',
'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose',
'moccasin', 'navajowhite', 'navy', 'oldlace', 'olive', 'olivedrab',
'orange', 'orangered', 'orchid', 'palegoldenrod', 'palegreen',
'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru',
'pink', 'plum', 'powderblue', 'purple', 'rebeccapurple', 'red',
'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown',
'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue',
'slategray', 'slategrey', 'snow', 'springgreen', 'steelblue',
'tan', 'teal', 'thistle', 'tomato', 'turquoise', 'violet',
'wheat', 'whitesmoke', 'yellow', 'yellowgreen'

#以下是好心人分享的,作者没有玩过就不推荐了,大家自行体验。

截至目前,已经上线GPT4o的国内镜像站:

https://chat.aigc.rent/auth?type=register&invite=MTc4

www.woka.chat

www.hulibot.com

https://key.wenwen-ai.com
key:sk-NYsoG3VBKDiTuvdtC969F95aFc4f45379aD3854a93602327

https://www.atalk-ai.com/talk

https://chat.moshuai.cc/

http://nova-ai.me/

www.aijuli.com

https://jfchatai.cn

https://bbbchat.com/

 

 

  • 22
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值