【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()
相关文章
|
20天前
|
小程序
微信小程序如何实现进入小程序自动连WiFi功能
微信小程序如何实现进入小程序自动连WiFi功能
|
6天前
|
存储 Java C#
使用Python实现简易的用户登录验证功能
这篇文章将向你展示如何使用Python语言进行程序设计,实现一个简易的用户登录验证功能。 该功能允许用户输入由字母和数字任意组合而成的用户名和密码,并通过while循环不断地提示用户输入,直到凭证正确为止。所有凭证信息将被存储在一个字典中,以便进行匹配验证。
|
11天前
|
小程序 前端开发 JavaScript
使用CSS的媒体查询功能在小程序中实现自适应布局
使用CSS的媒体查询功能在小程序中实现自适应布局
|
20天前
|
小程序
微信小程序用户登陆和获取用户信息功能实现
微信小程序用户登陆和获取用户信息功能实现
26 0
|
20天前
|
IDE Java 开发工具
讨论 Python 中泛型(或类似泛型的功能)的优点和缺点
【5月更文挑战第8天】Python虽无显式泛型系统,但可通过类型注解和工具实现类似功能。优点包括提升代码可读性、静态类型检查、更好的IDE支持、灵活性和可逐渐引入。缺点涉及运行时性能开销、学习成本、非强制性及与旧代码集成问题。适当使用工具和实践可管理这些挑战。
23 2
|
20天前
|
弹性计算 运维 Shell
设置Python 支持自动命令补齐功能
【4月更文挑战第29天】
14 0
|
20天前
|
弹性计算 运维 Shell
设置 Python 支持自动命令补齐功能
【4月更文挑战第29天】
8 1
|
20天前
|
小程序 Python
python背单词小程序
python背单词小程序
|
20天前
|
存储 搜索推荐 开发者
django-haystack,具有全文搜索功能的 Python 库!
django-haystack,具有全文搜索功能的 Python 库!
34 0
|
20天前
|
缓存 监控 Python
Python中的装饰器:一种强大的功能增强工具
装饰器是Python中一个独特且强大的功能,它允许在不修改原有函数或类代码的情况下,为其添加额外的功能或行为。本文将深入探讨Python装饰器的原理、用法以及在实际开发中的应用场景,帮助读者更好地理解和应用这一技术。