为让小学生提高计算速度和准确率,我制作一个给小学生练习100以内四则运算的app,为防止小学生学习不自觉,在练习过程中,记录做题数量,答题速度(超过4分钟不计算),以提高小学生的数学运算能力。
一、制作数据库结构:
一个为ys,记录题目,其中fh0为+,1为-,2为*,3为除。
CREATE TABLE ys (
tid INTEGER PRIMARY KEY AUTOINCREMENT,
s1 INTEGER,
fh INTEGER,
s2 INTEGER,
dan INTEGER,
cs INTEGER,
cuo INTEGER
);
一个为record表:
CREATE TABLE record (
cid INTEGER PRIMARY KEY AUTOINCREMENT,
rq TEXT,
sj TEXT,
tid INTEGER REFERENCES ys (tid),
cuo INTEGER,
yt INTEGER
);
二、主程序:
from functools import partial
import toga
from toga.style.pack import COLUMN, LEFT, RIGHT, ROW, Pack
import sqlite3
import random
from time import time
from pathlib import Path
import datetime
import shutil
#导入必要的库
resources_folder = Path(__file__).joinpath("../resources/").resolve()
db_filepath = resources_folder.joinpath("qwsx.db")
#db_filepath = '/storage/emulated/0/Pictures/qwsx.db'
#上面是数据库的存放位置,生成手机app请参考我以前的文章
#oppo版 需要用电脑调试应删除下面5行
'''
if Path('/storage/emulated/0/Documents/qwsx.db').exists():
db_filepath = '/storage/emulated/0/Documents/qwsx.db'
else:
shutil.copy(db_filepath, "/storage/emulated/0/Documents/qwsx.db")
db_filepath = '/storage/emulated/0/Documents/qwsx.db'
'''
names = globals()
nd = 0
hd = 0 #回答为0为出题,回答为1为1位数答题,2为2位数答题,3为3位数答题,4为符号答题
dan = 101 #初始答案
dan1 = 0
dan2 = 0
dan3 = 0
tjcs = ''
def is_number(s):
try:
float(s)
return True
except ValueError:
pass
try:
import unicodedata
unicodedata.numeric(s)
return True
except (TypeError, ValueError):
pass
return False
#判断是不是数字
def gettid(s1,fh,s2,dan):
conn = sqlite3.connect(db_filepath, timeout=10, check_same_thread=False)
c = conn.cursor()
#如果公式存在,提取tid
cursor = c.execute("SELECT count(tid) from ys where s1 = ? and fh = ? and s2 = ?;", (s1,fh,s2,))
row = cursor.fetchone()
ctid = row[0]
#如果公式不存在,插入公式到数据库
if ctid == 0:
c.execute("INSERT INTO ys(s1,fh,s2,dan,cs,cuo) VALUES (?,?,?,?,0,0);", (s1,fh,s2,dan,))
conn.commit()
cursor = c.execute("SELECT tid from ys where s1 = ? and fh = ? and s2 = ? order by tid desc;", (s1,fh,s2,))
row = cursor.fetchone()
tid = row[0]
c.close()
conn.close()
return(tid)
#获取tid,题目的id
def settm(nd):
if nd ==1:
jj = random.randint(0,1)
elif nd ==2:
jj = random.randint(0,3)
if jj == 0:
#为加法
s1 = random.randint(0,100)
s2 = random.randint(0,(100 - s1))
cvalue = str(s1) + "+" + str(s2) + "="
dan = s1 + s2
hd = 1
tid = gettid(s1,jj,s2,dan)
ii = random.randint(0,4) #0为提交答案
if ii == 2:
cvalue = "□+" + str(s2) + "=" + str(dan) + ",□为"
dan = s1
elif ii == 3:
cvalue = str(s1) + "+□=" + str(dan) + ",□为"
dan = s2
elif ii ==4 and s2 > 0:#a+0=a,a-0=a,可以是+-
cvalue = str(s1) + "□" + str(s2) + "=" + str(dan) + ",□为"
dan = jj
hd = 4 #hd4为符号
elif jj ==1:
s1 = random.randint(0,100)
s2 = random.randint(0,s1)
cvalue = str(s1) + "-" + str(s2) + "="
dan = s1 - s2
hd = 1
tid = gettid(s1,jj,s2,dan)
ii = random.randint(0,4) #0为提交答案
if ii == 2:
cvalue = "□-" + str(s2) + "=" + str(dan) + ",□为"
dan = s1
elif ii == 3:
cvalue = str(s1) + "-□=" + str(dan) + ",□为"
dan = s2
elif ii ==4 and s2 > 0:#a+0=a,a-0=a,可以是+-
cvalue = str(s1) + "□" + str(s2) + "=" + str(dan) + ",□为"
dan = jj
hd = 4 #hd4为符号
elif jj ==2:
#乘法
s1 = random.randint(1,10)
s2 = random.randint(0,int(100 / s1))
cvalue = str(s1) + "×" + str(s2) + "="
dan = s1 * s2
hd = 1
tid = gettid(s1,jj,s2,dan)
ii = random.randint(0,4) #0为提交答案
if ii == 2:
cvalue = "□×" + str(s2) + "=" + str(dan) + ",□为"
dan = s1
elif ii == 3 and s2 > 0:#a*0=0,b*0=0
cvalue = str(s1) + "×□=" + str(dan) + ",□为"
dan = s2
elif ii ==4 and s2 !=1 and s1 != 0:#a*=a,a/1=a;0*a=0,0/a=0
cvalue = str(s1) + "□" + str(s2) + "=" + str(dan) + ",□为"
dan = jj
hd = 4 #hd4为符号
elif jj ==3:
s1 = random.randint(1,10)
s2 = random.randint(0,int(100 / s1))
s3 = s1
dan = s1 * s2
s1 = dan
s2 = s3
cvalue = str(s1) + "÷" + str(s2) + "="
dan = int(s1 / s2)
hd = 1
tid = gettid(s1,jj,s2,dan)
ii = random.randint(0,4) #0为提交答案
if ii == 2:
cvalue = "□÷" + str(s2) + "=" + str(dan) + ",□为"
dan = s1
elif ii == 3 and s1 > 0:#0/a=0
cvalue = str(s1) + "÷□=" + str(dan) + ",□为"
dan = s2
elif ii ==4 and s2 !=1 and s1 !=0:#a*=a,a/1=a;0*a=0,0/a=0
cvalue = str(s1) + "□" + str(s2) + "=" + str(dan) + ",□为"
dan = jj
hd = 4 #hd4为符号
current_date = datetime.datetime.now()
formatted_date = current_date.strftime("%Y-%m-%d")
formatted_time = current_date.strftime("%H:%M:%S")
conn = sqlite3.connect(db_filepath, timeout=10, check_same_thread=False)
c = conn.cursor()
c.execute("INSERT INTO record (rq,sj,tid,cuo,yt) VALUES (?,?,?,?,?);", (formatted_date,formatted_time,0,0,0))
conn.commit()
cursor = c.execute("SELECT cid from record order by cid desc")
row = cursor.fetchone()
cid = row[0]
c.close()
conn.close()
return(jj,dan,hd,cid,tid,cvalue)
#设置题目,并生成记录,用于记录错误,答题用时
def u_record(yt,cid,tid):
if yt > 0 and cid > 0 and tid >0:
conn = sqlite3.connect(db_filepath, timeout=10, check_same_thread=False)
c = conn.cursor()
c.execute("UPDATE record SET tid = ?, yt = ? WHERE cid = ?;", (tid,yt,cid))
conn.commit()
c.execute("UPDATE ys SET cs = cs + 1 WHERE tid = ?;", (tid,))
conn.commit()
c.close()
conn.close()
#记录答题用时,题目答对次数
def u_cuo(cid,tid):
if cid > 0 and tid > 0:
conn = sqlite3.connect(db_filepath, timeout=10, check_same_thread=False)
c = conn.cursor()
c.execute("UPDATE record SET cuo = cuo + 1 WHERE cid = ?;", (cid,))
conn.commit()
c.execute("UPDATE ys SET cuo = cuo + 1 WHERE tid = ?;", (tid,))
conn.commit()
c.close()
conn.close()
#记录错误记录
def tj_cs():
if globals()['hd'] == 4 or globals()['tjcs'] =='':
conn = sqlite3.connect(db_filepath, timeout=10, check_same_thread=False)
c = conn.cursor()
query_str = 'select rq,count(cid),sum(cuo),round(avg(yt),0) from record where yt > 0 and yt < 240000 group by rq order by rq desc limit 0,3;'
cursor = c.execute(query_str)
rows = cursor.fetchall()
stext3 = ""
for row in rows:
stext3 += "%s:做%d题,错%d次,平均用%d毫秒\n" % (row[0],row[1],row[2],row[3])
c.close()
conn.close()
globals()['tjcs'] = stext3
stext4 = stext3 + "(已更新)"
else:
stext3 = globals()['tjcs']
stext4 = stext3 + "(待更新)"
return(stext4)
#显示做题记录
def build(app):
# 定义组件
c_box = toga.Box()
b1_box = toga.Box()
b2_box = toga.Box()
b3_box = toga.Box()
b4_box = toga.Box()
box = toga.Box()
c_input = toga.TextInput(readonly=True,style=Pack(font_size=22))
c_label = toga.Label("请选择难、易开始学习...", style=Pack(text_align=LEFT))
c_label1 = toga.Label("", style=Pack(text_align=LEFT, font_size=12))
c_label2 = toga.Label("", style=Pack(text_align=LEFT))
c_label3 = toga.Label("", style=Pack(text_align=LEFT))
#界面设置
def bt1(bb, widget):
#选择难易,然后出题,答题,再出题
c_label3.text = tj_cs()
if bb == '难':
globals()['nd'] = 2
c_label.text = '100以内加减乘除。'
elif bb == '易':
globals()['nd'] = 1
c_label.text = '100以内加减。'
if nd >= 1 and hd == 0:
globals()['jj'],globals()['dan'],globals()['hd'],globals()['cid'],globals()['tid'],cvalue=settm(nd)
c_input.value = cvalue
globals()['begintime'] = time()
if bb in '+-×÷' and hd == 4:
if bb == '+' and jj == 0:
c_label1.text = '你答对了'
ytime = int((time() - begintime) * 1000)
u_record(ytime,cid,tid)
c_input.value = c_input.value + bb
c_label2.text = '复习:' + c_input.value
globals()['jj'],globals()['dan'],globals()['hd'],globals()['cid'],globals()['tid'],cvalue=settm(nd)
bb = ''
c_input.value = cvalue
globals()['begintime'] = time()
elif bb == '-' and jj == 1:
c_label1.text = '你答对了'
ytime = int((time() - begintime) * 1000)
u_record(ytime,cid,tid)
c_input.value = c_input.value + bb
c_label2.text = '复习:' + c_input.value
globals()['jj'],globals()['dan'],globals()['hd'],globals()['cid'],globals()['tid'],cvalue=settm(nd)
bb = ''
c_input.value = cvalue
globals()['begintime'] = time()
elif bb == '×' and jj == 2:
c_label1.text = '你答对了'
ytime = int((time() - begintime) * 1000)
u_record(ytime,cid,tid)
c_input.value = c_input.value + bb
c_label2.text = '复习:' + c_input.value
globals()['jj'],globals()['dan'],globals()['hd'],globals()['cid'],globals()['tid'],cvalue=settm(nd)
bb = ''
c_input.value = cvalue
globals()['begintime'] = time()
elif bb == '÷' and jj == 3:
c_label1.text = '你答对了'
ytime = int((time() - begintime) * 1000)
u_record(ytime,cid,tid)
c_input.value = c_input.value + bb
c_label2.text = '复习:' + c_input.value
globals()['jj'],globals()['dan'],globals()['hd'],globals()['cid'],globals()['tid'],cvalue=settm(nd)
bb = ''
c_input.value = cvalue
globals()['begintime'] = time()
else:
c_label1.text = '答错了,重新回答'
u_cuo(cid,tid)
globals()['hd'] = 4
if is_number(bb) and hd == 3:
dan3 = 0
if str(dan3) == bb:
c_label1.text = '你答对了'
ytime = int((time() - begintime) * 1000)
u_record(ytime,cid,tid)
c_input.value = c_input.value + bb
c_label2.text = '复习:' + c_input.value
globals()['jj'],globals()['dan'],globals()['hd'],globals()['cid'],globals()['tid'],cvalue=settm(nd)
bb = ''
c_input.value = cvalue
globals()['begintime'] = time()
else:
c_label1.text = '答错了,你只答对了2个数字,请输入下一个数字'
u_cuo(cid,tid)
globals()['hd'] = 3
if is_number(bb) and hd == 2:
if dan >= 10 and dan < 100:
dan2 = int(str(dan)[-1:])
if dan2 == int(bb):
c_label1.text = '你答对了'
ytime = int((time() - begintime) * 1000)
u_record(ytime,cid,tid)
c_input.value = c_input.value + bb
globals()['hd'] = 0 #答对重新出题
c_label2.text = '复习:' + c_input.value
globals()['jj'],globals()['dan'],globals()['hd'],globals()['cid'],globals()['tid'],cvalue=settm(nd)
bb = ''
c_input.value = cvalue
globals()['begintime'] = time()
else:
c_label1.text = '答错了,你只答对了1个数字,请输入下一个数字'
u_cuo(cid,tid)
#globals()['hd'] = 2
elif dan ==100:
dan2 = 0
if str(dan2) == bb:
c_input.value = c_input.value + bb
c_label1.text = '你又答对了1个数字,请输入下一个数字'
globals()['hd'] = 3
else:
c_label1.text = '你答错了,继续答题'
u_cuo(cid,tid)
if is_number(bb) and hd == 1:
if dan < 10:
if dan == int(bb):
c_label1.text = '你答对了'
ytime = int((time() - begintime) * 1000)
u_record(ytime,cid,tid)
c_input.value = c_input.value + bb
c_label2.text = '复习:' + c_input.value
globals()['jj'],globals()['dan'],globals()['hd'],globals()['cid'],globals()['tid'],cvalue=settm(nd)
bb = ''
c_input.value = cvalue
globals()['begintime'] = time()
else:
c_label1.text = '你答错了,继续答题'
u_cuo(cid,tid)
elif dan >= 10 and dan < 100:
dan1 = int(str(dan)[:1])
#print(dan1)
if dan1 == int(bb):
c_label1.text = '你答对了1个数字,请输入下一个数字'
c_input.value = c_input.value + bb
globals()['hd'] = 2
else:
u_cuo(cid,tid)
# c_label1.text = '你答错了,继续答题'
elif dan == 100:
dan1 = 1
if dan1 == int(bb):
c_input.value = c_input.value + bb
c_label1.text = '你答对了1个数字,请输入下一个数字'
globals()['hd'] = 2
else:
u_cuo(cid,tid)
aaa = '7 8 9 + 4 5 6 - 1 2 3 × 0 易 难 ÷'.split()
#print(aaa) 用字符串变为数组,这样代码比较简
for i in range(1,17):
names['button_' + str(i)] = toga.Button(aaa[i-1], on_press=partial(bt1, aaa[i-1]),style=Pack(font_size=25))
#初始界面
# 设置组件样式和布局
c_box.add(c_input)
box.add(c_box)
for i in range(1,5):
b1_box.add(names['button_' + str(i)])
for i in range(5,9):
b2_box.add(names['button_' + str(i)])
for i in range(9,13):
b3_box.add(names['button_' + str(i)])
for i in range(13,17):
b4_box.add(names['button_' + str(i)])
box.add(b1_box)
box.add(b2_box)
box.add(b3_box)
box.add(b4_box)
box.add(c_label)
box.add(c_label1)
box.add(c_label2)
box.add(c_label3)
# 设置 outer box 和 inner box 的样式
box.style.update(direction=COLUMN, padding=5)
b1_box.style.update(direction=ROW, padding=1)
b2_box.style.update(direction=ROW, padding=1)
b3_box.style.update(direction=ROW, padding=1)
b4_box.style.update(direction=ROW, padding=1)
c_box.style.update(direction=ROW, padding=5)
# 设置单个组件的样式
c_input.style.update(width=345, flex=1)
# button.style.update(padding=15)
c_label.style.update(width=345, padding_left=4)
c_label1.style.update(width=345, padding_left=4)
c_label2.style.update(width=345, padding_left=4)
c_label3.style.update(width=345, padding_left=4)
for i in range(1,17):
names['button_' + str(i)].style.update(width=85, height=85, padding=1)
return box
def main():
return toga.App("千纬数学", "org.qwsx", startup=build)
if __name__ == "__main__":
main().main_loop()
下载:链接:https://pan.baidu.com/s/1FVOXBINjvWfY6becbFbq7A
提取码:epvw
PS:与0有关的计算出现bug,已经修改