【Python】- 实现一个小程序,随机出题、判题、打分功能

简介: 最近在学习python,刚好看到一个需求,尝试实现下,题目如下文章最后面会有完整的代码
作者:小5聊基础
简介:一只喜欢全栈方向的程序员,欢迎咨询,尽绵薄之力答疑解惑
编程原则:Write Less Do More
  • 效果如下

image.png

【开发信息】

1)python版本:3.6
2)开发工具:VS 2017
3)操作系统:windows11

【题目信息】

  • 实现一个小程序,有如下功能

1)随机出题(30以内整数加减乘除法的算术题)<br/>
2)判题,<br/>
3)打分,<br/>

  • 要求如下

1)使用tkinter库绘制界面 <br/>
绘制生成图形界面窗口,高宽度大小为800x600 <br/>
2)界面元素 <br/>
若干标签控件Label、<br/>
若干文本框控件Entry、<br/>
三个命令按钮控件Button、<br/>
以及其他个性化控件元素,根据自己觉得不错的控件<br/>
3)标签、文本框、按钮<br/>
label_name=姓名(标签),input_name=请输入姓名(文本框)<br/>
label_no=学号(标签),input_no=请输入学号(文本框)<br/>
label_questionId=题号(标签)<br/>
label_question_num=题目数字(标签)<br/>
label_operator=运算符+-* /(标签) <br/>
label_equal=等号(标签)<br/>
label_result=结果(文本框)<br/>
button_random=随机生成试题(按钮)<br/>
button_confirm=提交(按钮)<br/>
button_answer=查看答案(按钮)<br/>
4)随机生成10个题目,且是简单的单步运算题目,如下<br/>
比如:5+8=__ 7-3=__ 2 * 4=__ 5÷2=__ <br/>
注:除法结果为整数即可 <br/>

  • 程序流程

1)学生在界面上输入自己的姓名、学号信息 <br/>
使用字典学号和姓名键值对保存多组数据,点击随机生成试题按钮时判断是否存在当前输入的学社会功能信息 <br/>
如果输入信息为空,那么使用messagebox弹出提示信息:“请注意:姓名或学号不能为空” <br/>
如果存在学生信息,那么自动生成10道简单的加减乘除运算题目,否则弹出对话框窗口提示“姓名或学号有误,请重新输入!” <br/>
2)学生在每个题目对应的文本框中输入对应答案 <br/>
3)答题结束之后,点击提交按钮,页面给出学生的测试成绩(成绩为百分制) <br/>
4)最后,可以点击查看答案按钮,查看本次测试的正确答案 <br/>
注意:在提交按钮按下之前,查看答案按钮应该是灰色、不可用的状态。或者,如果没有做完全部题目就点击查看答案按钮,则自动提交现有题目,并显示分数 <br/>
5)当点击提交按钮时,根据实际答案情况给出成绩,并将本次测试页面的全部基础信息(含:学生信息/题目/结果/成绩等),存入磁盘文件【学生姓名-学生学号.txt】;多次运行此程序测试、做题,磁盘文件根据测试时间,内容应能顺序记录追加(可正序,也可逆序);【注意:文件中不能只有最后一次的测试信息记录】
6)设计窗口中各种元素的布局

【tkinter库信息】

1)tkinter是python自带的GUI界面模块 <br/>
2)导入模块 <br/>
import tkinter as tk <br/>
as后面的是别名,和sql字段as别名一样 <br/>
3)使用TK方法创建一个窗口 <br/>
main_windows = tk.Tk() <br/>
还需要添加一个主方法才能显示 <br/>
main_windows.mainloop() <br/>
4)设置标题 <br/>
必须再主方法之前 <br/>
main_windows.title('计算器')
5)设置长宽以及窗口坐标 <br/>

【有趣知识点】

1)方法外定义变量,在方法内赋值,结果值不变<br/>
以下代码value值不变,还是2<br/>
image.png

value=2
def test():
    value=value*10
  • 解决方法

在方法内,使用global关键词声明<br/>
global value<br/>
image.png

【完整代码】

可以根据需求情况,精简代码

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# 2022.06.08 11:23
import tkinter as tk
from tkinter import *
from tkinter import messagebox
import random as rd
import math

my_name = ''
my_no = ''
entry_no_value = ''
entry_name_value = ''
my_info={
    "my_no":"",
    "my_name":"",
    "my_score":0,
    "answer":{},
    "my_answer":{}
}
operator=['+','-','*','÷']
student_info = [{'no':1,'name': '张三'},{'no':2,'name': '李四'},{'no':3,'name': '王五'}]

# 随机生成试题 - 点击事件
def randomCreateQuestion():
    my_no = entry_no_value.get()
    my_name = entry_name_value.get()
    my_info['my_no']=my_no
    my_info["my_name"]=my_name
    flag = 0
    for item in student_info:
        if str(item['no']) == my_no and item['name'] == my_name:
            flag = 1
            break
    if my_no.strip() == '' and my_name.strip() == '':
        messagebox.askyesno("温馨提示","请注意:姓名或学号不能为空!", icon='info', default='no')
    elif flag == 0:
        messagebox.askyesno("温馨提示","姓名或学号有误,请重新输入!", icon='info', default='no')
    else:
        button_random.config(state=tk.DISABLED)
        createQuestion()

mw = tk.Tk()

# 创建窗口
def createWindows():
    mw.title('简单运算试题') # 设置标题
    mw.geometry("800x600") # 绘制窗口的长宽
createWindows()

# 创建学号 - 标签和输入文本框
def createNoLabelEntry():
    global entry_no_value
    label_no = tk.Label(mw, text="学号:")
    label_no.place(x=100,y=100)
    entry_no_value = _entry_no_value = StringVar()
    entry_no = tk.Entry(mw, bd =1,textvariable=_entry_no_value)
    entry_no.place(x=140,y=100)
createNoLabelEntry()

# 创建姓名标签和输入文本框
def createNameLabelEntry():
    global entry_name_value
    label_name = tk.Label(mw, text="姓名:")
    label_name.place(x=100,y=130)
    entry_name_value = _entry_name_value = StringVar()
    entry_name = tk.Entry(mw, bd =1,textvariable=_entry_name_value)
    entry_name.place(x=140,y=130)
createNameLabelEntry()

# 随机生成试题 - 按钮
button_random={}
def createRandomButton():
    global button_random
    button_random=_button_random = tk.Button(mw, text="随机生成试题",command=randomCreateQuestion)
    _button_random.place(x=140,y=160)
createRandomButton()

# 提交 - 按钮
confirm_button={}
def createConfirmButton():
    global confirm_button
    button = tk.Button(mw, text="提交",command=getScore)
    button.place(x=100,y=190+10*30,w=60)
    confirm_button=button

# 计算成绩
def getScore():
    index=0
    my_score=0
    for value in answer:
        _v=my_answer[index].get()
        if _v=='':
            continue
        my_value=int(_v)
        index+=1
        if value==my_value:
            my_score+=10 # 回答正确一题加10分
        else:
            continue
    my_info["my_score"]=my_score
    confirm_button.config(state=tk.DISABLED)       # 提交按钮不可点击状态
    answer_button.config(state=tk.ACTIVE)          # 查看按钮可点击状态
    button_random.config(state=tk.ACTIVE)          # 随机生成试题
    testScoreLabel() # 显示成绩
    writeTxt()       # 将本次信息写入到txt
    
# 测试成绩 - 标签
def testScoreLabel():
    label = tk.Label(mw, text="您的本次测试成绩为:%s" % my_info["my_score"])
    label.place(x=100,y=200+11*30)
    
# 按钮 - 查看答案
answer_button={}
def createAnswerButton():
    global answer_button
    button = tk.Button(mw, text="查看答案",command=displayAnswer)
    button.place(x=180,y=190+10*30,w=60)
    button.config(state=tk.DISABLED)
    answer_button=button

# 标签 - 显示答案 
def displayAnswer():
    index=0
    for value in answer:
        color='#f60'
        _v=my_answer[index].get()
        if _v!='':
            my_value=int(_v)
            if value==my_value:
                color='#099dff'
        label = tk.Label(mw, text="%s" % str(value),fg=color)
        label.place(x=300,y=190+index*30)
        index+=1
    answer_button.config(state=tk.DISABLED)          # 查看答案按钮不可点击状态

# 输出信息到txt
def writeTxt():
    file_name='%s/%s-%s.txt' % ("calculator",my_info['my_name'],my_info['my_no'])
    with open(file_name, 'a', newline='') as write_f:
        write_f.write('学号:%s\n姓名:%s\n本次测试成绩:%s\n' % (my_info["my_no"],my_info["my_name"],str(my_info['my_score'])))
        index=0
        my_score=0
        for value in answer:
            line_str='[%s]、%s' % (str(index+1),my_info["question"][index])
            _v=my_answer[index].get()
            if _v!='':
                my_value=int(_v)
                if value==my_value:
                    color='#099dff'
                line_str+=' %s (%s)' % (my_value,value)
            else:
                line_str+=' %s (%s)' % ('',value)
            index+=1
            write_f.write('%s\n' % (line_str))
        write_f.write('\n')

# 循环生成10道试题
answer=[]
question=[]
my_answer=[]
def createQuestion():
    answer.clear();
    my_answer.clear();
    max_num=30      # 最大整数30
    max_count=10    # 10道题目
    unit_value=30   # 控件之间的间距
    for index in range(max_count):
        # 题号 - 标签
        new_str="[%s]、" % (str(index+1))
        label = tk.Label(mw, text=new_str)
        label.place(x=100,y=190+index*unit_value)
        # 题目数字和运算符 - 标签
        left_num=math.floor(rd.random()*30)+1
        right_num=math.floor(rd.random()*30)+1
        operator_index=math.floor(rd.random()*4)
        operator_index=math.floor(rd.random()*4)
        operator_value=operator[operator_index]
        new_str="%-5s%-5s%-5s = " % (str(left_num),str(operator_value),str(right_num))
        question.append(new_str)
        label_q = tk.Label(mw, text=new_str)
        label_q.place(x=130,y=190+index*unit_value)
        if operator_index==0:
            answer.append(left_num+right_num)
        elif operator_index==1:
            answer.append(left_num-right_num)
        elif operator_index==2:
            answer.append(left_num*right_num)
        elif operator_index==3:
            answer.append(math.floor(left_num/right_num))
        # 答案 - 文本框
        entry_answer_value = StringVar()
        my_answer.append(entry_answer_value)
        entry_answer = tk.Entry(mw, bd =1,textvariable=entry_answer_value)
        entry_answer.place(x=240,y=190+index*unit_value,w=50)
        my_info["answer"]=answer
        my_info["question"]=question
        my_info["my_answer"]=my_answer
        # 创建提交和查看答案按钮
        createConfirmButton()
        createAnswerButton()

mw.mainloop()
相关文章
|
19天前
|
开发框架 数据建模 中间件
Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器是那些静悄悄的幕后英雄。它们不张扬,却能默默地为函数或类增添强大的功能。本文将带你了解装饰器的魅力所在,从基础概念到实际应用,我们一步步揭开装饰器的神秘面纱。准备好了吗?让我们开始这段简洁而富有启发性的旅程吧!
26 6
|
29天前
|
IDE 数据挖掘 开发工具
Python作为一种广受欢迎的高级编程语言,以其简洁的语法和强大的功能吸引了众多初学者和专业开发者
Python作为一种广受欢迎的高级编程语言,以其简洁的语法和强大的功能吸引了众多初学者和专业开发者
37 7
|
1月前
|
存储 缓存 测试技术
Python中的装饰器:功能增强与代码复用的利器
在Python编程中,装饰器是一种强大而灵活的工具,它允许开发者以简洁优雅的方式增强函数或方法的功能。本文将深入探讨装饰器的定义、工作原理、应用场景以及如何自定义装饰器。通过实例演示,我们将展示装饰器如何在不修改原有代码的基础上添加新的行为,从而提高代码的可读性、可维护性和复用性。此外,我们还将讨论装饰器在实际应用中的一些最佳实践和潜在陷阱。
|
21天前
|
测试技术 Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界中,装饰器是那些能够为我们的代码增添魔力的小精灵。它们不仅让代码看起来更加优雅,还能在不改变原有函数定义的情况下,增加额外的功能。本文将通过生动的例子和易于理解的语言,带你领略装饰器的奥秘,从基础概念到实际应用,一起开启Python装饰器的奇妙旅程。
34 11
|
17天前
|
Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器就像是给函数穿上了一件神奇的外套,让它们拥有了超能力。本文将通过浅显易懂的语言和生动的比喻,带你了解装饰器的基本概念、使用方法以及它们如何让你的代码变得更加简洁高效。让我们一起揭开装饰器的神秘面纱,看看它是如何在不改变函数核心逻辑的情况下,为函数增添新功能的吧!
|
26天前
|
设计模式 监控 程序员
Python中的装饰器:功能增强与代码复用的利器####
本文深入探讨了Python中装饰器的工作原理、应用场景及其在提升代码可读性、减少重复劳动方面的优势。不同于传统方法的冗长和复杂,装饰器提供了一种优雅且高效的方式来增强函数或方法的功能。通过具体实例,我们将揭示装饰器如何简化错误处理、日志记录及性能监控等常见任务,使开发者能够专注于核心业务逻辑的实现。 ####
|
27天前
|
机器人 计算机视觉 Python
Python作为一种高效、易读且功能强大的编程语言,在教育领域的应用日益广泛
Python作为一种高效、易读且功能强大的编程语言,在教育领域的应用日益广泛
42 5
|
3天前
|
小程序 安全 搜索推荐
陪玩小程序的搭建解析与功能需求
陪玩小程序是为玩家提供专业陪玩服务的应用,嵌入社交或游戏平台,具备智能匹配、实时聊天、预约服务等功能,支持便捷高效的游戏体验。源码交付时需提供详细文档、技术支持及定制开发服务,确保客户能顺利维护和升级。选择陪玩小程序时应关注功能需求、用户体验、安全性和成本效益,以确保最佳使用效果。
23 0
|
1月前
|
开发框架 缓存 测试技术
Python中的装饰器:魔法般的功能增强
在Python编程中,装饰器是一种强大而灵活的工具,它允许开发者修改或扩展函数和类的行为。本文将深入探讨Python装饰器的工作原理,并通过实例演示如何创建和使用自定义装饰器来增强代码的功能性和可读性。我们将从基础概念讲起,逐步深入到高级应用,揭示装饰器背后的“魔法”,并展示它们在实际开发中的多种用途。
|
27天前
|
Python
探索Python中的装饰器:简化代码,增强功能
本文将引导你了解Python装饰器的奇妙世界。我们将从基础概念入手,逐步深入到装饰器的应用实例,展示如何通过这一强大工具简化代码并增加新功能。文章不仅介绍理论知识,还将提供实用的代码示例,帮助你在实际项目中运用装饰器提升开发效率。