1. 程式人生 > 其它 >python GUI介面程式設計 口算題生成系統

python GUI介面程式設計 口算題生成系統

問題描述

口算題生成系統

功能:

(1)口算:題目顯示在介面上(除法必須是整除),逐個顯示題目,使用者通過輸入框輸入計算結果。系統能實時統計正確率,將錯誤題目列印到檔案裡。
(2)生成題目:使用者選擇生成的題目數量,列印時的列數,運算子的數量,將題目生成到docx檔案裡。

設計說明

(1)擬設計的功能及實現思路、需要用到的知識
功能(1)的實現思路:
1.初始化視窗和幕布,為視窗命名
2.記錄用到的變數,兩個整數x、y,以及用到的符號op(+-*/)
3.將x,y,op列印到介面上,並且生成輸入框
4.新增按鈕,get_num表示生成題目,judge表示判斷結果是否正確,print_error表示將所有錯誤題目列印到檔案裡
5.為get_num編寫函式update_num,隨機生成新的x、y、op
6.為judge編寫函式judge,判斷答案是否正確。由於除法要用整除來判斷,而eval表示式判斷的是非整除,加了個特判,當op=/時,特判答案是否正確。
7.編寫函式save_error,儲存錯誤的題目,在judge函式中使用,如果回答錯誤,就將錯誤題目的字串形式儲存到列表
8.記錄變數cur_num表示正確題目的數量,sum表示一共回答問題的數量,每次都計算正確率列印到螢幕上
9.為print_error編寫函式 output_error(),將錯誤題目列印到txt檔案,一行一個題目。
10.增加鍵盤操作,用鍵盤迴車代替判斷按鈕,免去了每次檢驗結果時需要滑鼠操作的麻煩。
功能(2)的實現思路:


1.初始化視窗和幕布,為視窗命名
2.生成輸入框和說明文字,統計使用者想要生成的題數,使用者想要使用操作符的個數,使用者列印檔案的列數。
3.設計按鈕output,表示使用者提交意願
4.編寫output_all函式,根據使用者意願獲得相關資訊
5.根據題目數量生成題目,以字串格式儲存到列表
6.呼叫docx相關庫建立docx檔案,判斷表格的行數和列數,生成表格
7.從列表中讀取資訊到檔案
8.儲存檔案到rex.docx
(2)呼叫庫的說明
tkinter:GUI程式設計的相關庫
random:隨機數生成的相關庫
(3)定義及呼叫的函式及功能
Tk():建立應用程式主視窗
Frame():建立控制元件容器,可依附在視窗中
IntVar(),StringVar():初始化變數
.Label():顯示變數的標籤
set()為變數重新賦值
randint():生成某一範圍的隨機數
get():獲取變數的值
Button():設定按鈕
bind():設定鍵盤快捷鍵
mainloop():迴圈
自己定義的函式
update_num() :產生新的題目,即新的隨機的x,y和符號
save_error():#儲存錯誤題目
output_error():#列印錯誤題目到檔案
judge(event):判斷答案是否正確
output_all():列印所有題目到docx檔案

實現程式碼

功能(1)

# -*- coding: utf-8 -*-
"""
Created on Wed Jun 16 16:49:28 2021

@author: DELL
"""

#匯入GUI的包,以及隨機數的包
import tkinter as tk
import random
#初始化視窗和幕布
root = tk.Tk()
window = tk.Frame(root, bg ="lightgreen")
window.pack(expand = tk.YES,fill = tk.BOTH)
root.title('口算計算器')  #視窗名字

#初始化用到的變數,兩個數x,y和符號sym,sym限定在加號和減號之間,可以新增乘除
x = tk.IntVar()
y = tk.IntVar()
sym = tk.StringVar()
#顯示變數的標籤
tk.Label(window,textvariable =x).grid(row = 0,column = 0)
tk.Label(window,textvariable =sym).grid(row = 0,column = 2,ipadx=10)
tk.Label(window,textvariable =y).grid(row = 0,column = 3,ipadx=10)


lst=[]
symbol = ['+','-','*','/'] # sym符號的池子
flag = 1
sum=0
cur_num=0
#此函式產生新的題目,即新的隨機的x,y和符號
def update_num():
    global flag
    if flag:
        flag = 0
        x.set(random.randint(10,100))
        y.set(random.randint(10,100))
        sym.set(symbol[random.randint(0,3)])
    else:
        flag = 1
        x.set(random.randint(10, 100))
        y.set(random.randint(10, 100))
        sym.set(symbol[random.randint(0,3)])
    global sum
    sum=sum+1
def save_error():#儲存錯誤題目
    c = str(x.get())+sym.get()+str(y.get())+"=\n"
    lst.append(c)
def output_error():#列印錯誤題目到檔案
    with open('error_題目.txt',mode='w',encoding='utf-8') as tf:
        for i in lst:
            tf.write(i)


tk.Button(window,text = 'gen_num', width = 10,height = 4,bg = 'blue', command = update_num).grid(row = 5,column = 10,sticky=tk.W)
tk.Button(window,text="print_error",width = 10,height = 4,bg = 'red',command=output_error).grid(row = 7,column = 10,sticky=tk.W)
# 生成輸入框
e = tk.Entry(window)
e.grid(row = 0, column = 4)
result = tk.StringVar()

def judge(event):
    global cur_num
    c = str(x.get())+sym.get()+str(y.get())
    if len(e.get()) !=0:
        if(sym.get()=='/'):
            tx=int(x.get())
            ty=int(y.get())
            if(tx//ty==int(e.get())):
                cur_num=cur_num+1
                result.set("回答正確!"+"正確率為:"+str(cur_num/sum))
                update_num()
                e.delete(0,'end')
            else:
                result.set("回答錯誤"+"正確率為:"+str(cur_num/sum))
                save_error()
                update_num()
                e.delete(0, 'end')
        else:
            if int(e.get()) == eval(c):
                
                cur_num=cur_num+1
                result.set("回答正確!"+"正確率為:"+str(cur_num/sum))
                update_num()
                e.delete(0,'end')
            else:
                result.set("回答錯誤"+"正確率為:"+str(cur_num/sum))
                save_error()
                update_num()
                e.delete(0, 'end')
    else:
        result.set("請輸入答案")

#鍵盤迴車按鍵代替判斷按鈕,免去了每次檢驗結果時都需要滑鼠操作的麻煩
root.bind('<Return>', judge)
button = tk.Button(window,text="judge",width = 10,height = 4,bg = 'pink')
button.grid(row = 6,column = 10)
button.bind('<Button-1>',judge)
tk.Label(window,textvariable =result).grid(row = 1,column = 0)

#敞口迴圈必須有
root.mainloop()

功能(2)



# -*- coding: utf-8 -*-
"""
Created on Wed Jun 16 17:35:59 2021

@author: DELL
"""
import tkinter as tk
import random
from docx import Document
root_all = tk.Tk()
window_all = tk.Frame(root_all, bg ="green")
window_all.pack(expand = tk.YES,fill = tk.BOTH)
root_all.title('生成題目')  #視窗名字
tk.Label(window_all,text='題目數量:').grid(row=0,column=0)
tk.Label(window_all,text='運算子個數:').grid(row=1,column=0)
tk.Label(window_all,text='列印到檔案裡的列數:').grid(row=2,column=0)



num = tk.Entry(window_all)
num.grid(row = 0, column = 1)
oper_num=tk.Entry(window_all)
oper_num.grid(row=1,column=1)
col_num=tk.Entry(window_all)
col_num.grid(row=2,column=1)

symbol = ['+','-','*','/']
lst=[]


def output_all():
    num_cnt=int(num.get())
    oper_cnt=int(oper_num.get())
    col_cnt=int(col_num.get())
    #print(type(num_cnt))
    for i in range(num_cnt):
        x=random.randint(10,100)
        y=random.randint(10,100)
        op=symbol[random.randint(0,oper_cnt-1)]
        c = str(x)+op+str(y)+"=      "
        lst.append(c)
    wordfile=Document()
    cnt_row=num_cnt//col_cnt
    if num_cnt % col_cnt == 0:
        cnt_row=cnt_row+1
    table=wordfile.add_table(rows=cnt_row,cols=col_cnt,)
    row_idx=0
    col_idx=0
    for i in lst:
       table.rows[row_idx].cells[col_idx].text=i
       col_idx=col_idx+1
       if col_idx == col_cnt  :
           col_idx=0
           row_idx=row_idx+1
    wordfile.save("res.docx")
tk.Button(window_all,text="output",width = 10,height = 4,bg = 'orange',command=output_all).grid(row = 8,column = 10,sticky=tk.W)

root_all.mainloop()

參考部落格找到了加上