Python可视化训练
(一)、设计实现电子算盘,并完成测试
【题目描述】
给小朋友设计一个电子算盘。要求绘制电子算盘界面,设计并实现打珠算过程(界面参考如下图示)。
界面右侧要求以图形绘制的方式绘制自画像,注意不能是图像文件显示的形式。
from tkinter import * def initWindow(): rect = canvas.create_rectangle(25, 40, 450, 400, width=3) # 算盘边框 x0, y0, x1, y1 = 0, 0, 0, 0 for i in range(5): # 生成串算珠的线 line_shu = canvas.create_line(70 + x0, 40 + y0, 70 + x1, 400 + y1, width=3) x0 += 80 x1 += 80 line_fenge = canvas.create_line(25, 100, 450, 100, width=3) # 生成上下珠的分割线 x0, y0, x1, y1 = 0, 0, 0, 0 for i in range(5): # 生成5个上珠 top_oval[i] = canvas.create_oval(40 + x0, 60 + y0, 100 + x1, 90 + y1, fill='orange', tags=f"top{i}") x0 += 80 x1 += 80 x0, y0, x1, y1 = 0, 0, 0, 0 for i in range(4): # 生成4*5个下珠 for j in range(5): below_oval[i][j] = canvas.create_oval(40 + x0, 160 + y0, 100 + x1, 190 + y1, fill='yellow', tags=f"below{i}{j}") chushi[i][j] = canvas.coords(below_oval[i][j]) x0 += 80 x1 += 80 x0 = 0 x1 = 0 y0 += 60 y1 += 60 print(chushi) num = [[0 for i in range(5)] for j in range(4)] # 五个下珠分别对应的数值 num2 = [0 for i in range(5)] # 五个上珠分别对应的数值 canvas.create_oval(750, 370, 470, 90, fill='yellow') canvas.create_oval(500, 170, 560, 200, fill='black') canvas.create_oval(650, 170, 710, 200, fill='black') canvas.create_arc(500, 200, 700, 300, start=-150, extent=120, style=ARC, width=3) def get_empty(): empty = [[0 for j in range(5)] for i in range(4)] for i in range(4): for j in range(5): if canvas.coords(below_oval[i][j]) != chushi[i][j]: empty[i][j] = 1 print(empty) return empty def bind(): def handler_adaptor(handler, fun, row, col): """事件处理函数的适配器,相当于中介,可以帮助tag_bind函数传递参数""" return lambda event, handler=handler, fun=fun, col=col, row=row: handler(event=event, fun=fun, row=row, col=col) def handler_adaptor2(handler2, fun, row): """事件处理函数的适配器,相当于中介,可以帮助tag_bind函数传递参数""" return lambda event, handler2=handler2, fun=fun, row=row: handler2(event=event, fun=fun, row=row) def handler(event, fun, row, col): """下珠上划""" content = fun # 这个就是被点击的算珠id empty = get_empty() if row == 0: if float(canvas.coords(content)[1]) - 40 >= 100: canvas.move(content, 0, -40) else: if empty[row - 1][col] == 1: if float(canvas.coords(content)[1]) - 40 >= 110 + 10 * (row + 1): canvas.move(content, 0, -40) def handler2(event, fun, row): """上珠上划""" content = fun # 这个就是被点击的算珠id if float(canvas.coords(content)[1]) - 20 >= 40: canvas.move(content, 0, -20) def handler3(event, fun, row, col): """下珠下划""" content = fun # 这个就是被点击的算珠id empty = get_empty() if row == 3: if float(canvas.coords(content)[1]) + 40 <= 350: canvas.move(content, 0, 40) else: if empty[row][col] == 1: canvas.move(content, 0, 40) def handler4(event, fun, row): """上珠下划""" content = fun # 这个就是被点击的算珠id if float(canvas.coords(content)[1]) + 20 <= 60: canvas.move(content, 0, 20) for i in range(5): canvas.tag_bind(top_oval[i], "<Button-1>", handler_adaptor2(handler2, fun=top_oval[i], row=i)) canvas.tag_bind(top_oval[i], "<Button-3>", handler_adaptor2(handler4, fun=top_oval[i], row=i)) for i in range(4): for j in range(5): canvas.tag_bind(below_oval[i][j], "<Button-1>", handler_adaptor(handler, fun=below_oval[i][j], row=i, col=j)) canvas.tag_bind(below_oval[i][j], "<Button-3>", handler_adaptor(handler3, fun=below_oval[i][j], row=i, col=j)) if __name__ == "__main__": window = Tk() window.title("电子算盘") window.geometry("800x500") canvas = Canvas(window, width="800", height="500", bg="white") canvas.pack() top_oval = [int for i in range(5)] # 定义列表存储5个上珠 below_oval = [[int for i in range(5)] for i in range(4)] # 定义列表存储4*5个下珠 chushi = [[0 for j in range(5)] for i in range(4)] # 所有下珠的初始坐标 initWindow() bind() window.mainloop()
(二)、以(一)中的电子算盘为基础,设计并实现珠算测试器,并完成测试。
【题目描述】
给小朋友设计一个珠算测试器,要求能够完成珠算加减法的测试。具体的要求功能如下:
(1) 用户启动测试,输入用户名后系统随机生成特定数目的加减法测试题;
(2) 要求测试使用表盘式或数字时秒表进行界面计时显示(参考如上图示);
(3) 对于每道测试题目,要求用户使用电子算盘完成珠算过程,当按下确认键时,将珠算结果与正确答案比对,并在界面上显示总题数、已答题数和已做对题数;
(4) 当测试完成,界面显示本次测试情况(包括用户名、测试题目及答题明细、对错情况、测试用时和测试成绩)
from tkinter import * import tkinter.messagebox as msg from random import randint def initWindow(): rect = canvas.create_rectangle(25, 40, 450, 400, width=3) # 算盘边框 x0, y0, x1, y1 = 0, 0, 0, 0 for i in range(5): # 生成串算珠的线 line_shu = canvas.create_line(70 + x0, 40 + y0, 70 + x1, 400 + y1, width=3) x0 += 80 x1 += 80 line_fenge = canvas.create_line(25, 100, 450, 100, width=3) # 生成上下珠的分割线 x0, y0, x1, y1 = 0, 0, 0, 0 for i in range(5): # 生成5个上珠 top_oval[i] = canvas.create_oval(40 + x0, 60 + y0, 100 + x1, 90 + y1, fill='orange', tags=f"top{i}") x0 += 80 x1 += 80 x0, y0, x1, y1 = 0, 0, 0, 0 for i in range(4): # 生成4*5个下珠 for j in range(5): below_oval[i][j] = canvas.create_oval(40 + x0, 160 + y0, 100 + x1, 190 + y1, fill='yellow', tags=f"below{i}{j}") chushi[i][j] = canvas.coords(below_oval[i][j]) x0 += 80 x1 += 80 x0 = 0 x1 = 0 y0 += 60 y1 += 60 global start_button, label_sum, username, entry_username, username_text, window_showusername global label_time, window_time, window_question global var_username, var_question, var_msg, window_answer, window_msg sum = Label(window, width=20, height=2, bg="grey", textvariable=var, font=('Arial', 14)) label_sum = canvas.create_window(750, 80, window=sum, anchor=NE) canvas.itemconfigure(label_sum, state="hidden") button = Button(window, width=30, height=4, bg="grey", text="开始测试吧!", command=adjust) start_button = canvas.create_window(750, 300, window=button, anchor=NE) text = Label(window, text="用户名:", width=10, height=2, bg="white") username_text = canvas.create_window(500, 200, window=text, anchor=CENTER) username = Entry(window, font=('Arial', 14)) entry_username = canvas.create_window(640, 200, window=username, anchor=CENTER) label_showusername = Label(window, textvariable=var_username, width=15, height=2, bg="grey", font=('Arial', 14)) window_showusername = canvas.create_window(770, 0, window=label_showusername, anchor=NE) canvas.itemconfigure(window_showusername, state="hidden") label_time = Label(window, width=10, height=2, bg="grey", font=('Arial', 14)) window_time = canvas.create_window(600, 0, window=label_time, anchor=NE) canvas.itemconfigure(window_time, state="hidden") label_question = Label(window, width=30, height=2, bg="grey", font=('Arial', 14), textvariable=var_question) window_question = canvas.create_window(630, 180, window=label_question, anchor=CENTER) canvas.itemconfigure(window_question, state="hidden") answer_button = Button(window, width=10, height=2, bg="grey", text="提交答案", command=judge, font=('Arial', 14)) window_answer = canvas.create_window(630, 400, window=answer_button, anchor=CENTER) canvas.itemconfigure(window_answer, state="hidden") msg_label = Label(window, width=30, height=6, bg="grey", font=('Arial', 14), textvariable=var_msg) window_msg = canvas.create_window(630, 260, window=msg_label, anchor=CENTER) canvas.itemconfigure(window_msg, state="hidden") def run_time(target): def counting(): global time time += 1 global li print(li) if li != 5: target.config(text=f"所用时间:{str(time)}s") else: target.config(text="游戏结束") target.after(1000, counting) # 间隔1000毫秒再次执行counting函数 counting() def adjust(): global ques, li, true, false, all_username myusername = username.get() all_username = myusername if myusername != "": """对画布中的部件进行一些调整""" for i in range(5): ques[i] = get_question() canvas.itemconfigure(label_sum, state="normal") canvas.itemconfigure(window_showusername, state="normal") canvas.itemconfigure(window_time, state="normal") canvas.itemconfigure(window_question, state="normal") canvas.itemconfigure(window_answer, state="normal") canvas.itemconfigure(window_msg, state="normal") var_question.set(f"问题:{ques[0][0]}") run_time(label_time) var_username.set(f"用户名:{myusername}") sum = get_sum() var.set(f"当前数值:{sum}") var_msg.set(f"总题数:5\n已经做了0题\n已做对0题\n已做错0题") canvas.itemconfigure(start_button, state="hidden") canvas.itemconfigure(entry_username, state="hidden") canvas.itemconfigure(username_text, state="hidden") else: msg.showinfo("错误", "用户名不能为空白") def judge(): def next(): var_question.set(f"问题:{ques[li][0]}") global li, false, true sum = get_sum() myanw[li][0] = ques[li][0] myanw[li][1] = sum if sum == int(ques[li][1]): true += 1 msg.showinfo("答案正确", f"恭喜你做对了") else: false += 1 msg.showinfo("答案错误", f"做错了!正确答案是{ques[li][1]}") li += 1 var_msg.set(f"总题数:5\n已经做了{li}题\n已做对{true}题\n已做错{false}题") if li != 5: next() else: msg.showinfo("游戏结束", f"以下是你的战绩\n总题数:5\n总用时:{time}s\n总成绩:{true * 20}分\n做对了{true}题\n做错了{false}题") msg.showinfo("游戏结束", f"{all_username},你好\n以下是你的答题明细\n总题数:5\n1.{myanw[0][0]}={myanw[0][1]}\n" f"2.{myanw[1][0]}={myanw[1][1]}\n3.{myanw[2][0]}={myanw[2][1]}\n" f"4.{myanw[3][0]}={myanw[3][1]}\n5.{myanw[4][0]}={myanw[4][1]}\n") exit() def get_question(): answer, num1, num2 = 0, 0, 0 operator = "" temp = randint(1, 2) if temp == 1: while 1: num1 = randint(0, 99999) num2 = randint(0, 99999) if num1 + num2 <= 99999: break answer = num1 + num2 operator = "+" elif temp == 2: while 1: num1 = randint(0, 99999) num2 = randint(0, 99999) if num1 - num2 > 0: break answer = num1 - num2 operator = "-" equation = str(num1) + operator + str(num2) return equation, answer def get_sum(): sum = 0 temp = 5 for i in range(5): temp -= 1 if num2[i] == 1: sum += 10 ** temp * 5 temp = 5 for j in range(5): temp -= 1 for i in range(4): if num[i][j] == 1: sum += 10 ** temp return sum def bind(): def handler_adaptor(handler, fun, row, col): """事件处理函数的适配器,相当于中介,可以帮助tag_bind函数传递参数""" return lambda event, handler=handler, fun=fun, col=col, row=row: handler(event=event, fun=fun, row=row, col=col) def handler_adaptor2(handler2, fun, row): """事件处理函数的适配器,相当于中介,可以帮助tag_bind函数传递参数""" return lambda event, handler2=handler2, fun=fun, row=row: handler2(event=event, fun=fun, row=row) def handler(event, fun, row, col): """下珠上划""" content = fun # 这个就是被点击的算珠id if row == 0: if float(canvas.coords(content)[1]) - 40 >= 100 and num[row][col] == 0: canvas.move(content, 0, -40) num[row][col] = 1 else: if num[row - 1][col] == 1: if float(canvas.coords(content)[1]) - 40 >= 110 + 10 * (row + 1) and num[row][col] == 0: canvas.move(content, 0, -40) num[row][col] = 1 sum = get_sum() var.set(f"当前数值:{sum}") def handler2(event, fun, row): """上珠上划""" content = fun # 这个就是被点击的算珠id if float(canvas.coords(content)[1]) - 20 >= 40: canvas.move(content, 0, -20) num2[row] = 1 sum = get_sum() var.set(f"当前数值:{sum}") def handler3(event, fun, row, col): """下珠下划""" content = fun # 这个就是被点击的算珠id if row == 3: if num[row][col] == 1: canvas.move(content, 0, 40) num[row][col] = 0 else: if num[row + 1][col] == 0 and num[row][col] == 1: canvas.move(content, 0, 40) num[row][col] = 0 sum = get_sum() var.set(f"当前数值:{sum}") def handler4(event, fun, row): """上珠下划""" content = fun # 这个就是被点击的算珠id if float(canvas.coords(content)[1]) + 20 <= 60: canvas.move(content, 0, 20) num2[row] = 0 sum = get_sum() var.set(f"当前数值:{sum}") for i in range(5): canvas.tag_bind(top_oval[i], "<Button-1>", handler_adaptor2(handler2, fun=top_oval[i], row=i)) canvas.tag_bind(top_oval[i], "<Button-3>", handler_adaptor2(handler4, fun=top_oval[i], row=i)) for i in range(4): for j in range(5): canvas.tag_bind(below_oval[i][j], "<Button-1>", handler_adaptor(handler, fun=below_oval[i][j], row=i, col=j)) canvas.tag_bind(below_oval[i][j], "<Button-3>", handler_adaptor(handler3, fun=below_oval[i][j], row=i, col=j)) if __name__ == "__main__": window = Tk() window.title("电子算盘") window.geometry("800x500") canvas = Canvas(window, width="800", height="500", bg="white") canvas.pack() ques = [0 for i in range(5)] myanw = [[0, 0]for i in range(5)] li = 0 time, true, false = 0, 0, 0 start_button, label_sum, username, entry_username = 0, 0, 0, 0 username_text, window_showusername, window_time = 0, 0, 0 label_time, window_question, window_answer = 0, 0, 0 all_username = "" window_msg = 0 var = StringVar() var_username = StringVar() var_question = StringVar() var_msg = StringVar() top_oval = [int for i in range(5)] # 定义列表存储5个上珠 below_oval = [[int for i in range(5)] for i in range(4)] # 定义列表存储4*5个下珠 chushi = [[0 for j in range(5)] for i in range(4)] # 所有下珠的初始坐标 num = [[0 for i in range(5)] for j in range(4)] # 4*5个下珠分别是否被拨动 num2 = [0 for i in range(5)] # 五个上珠分别是否被拨动 initWindow() bind() window.mainloop()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧