使用python的turtle库给小学生出题
@开发环境说明:turtle界面在2k的2560*1440分辨率下开发,其它分辨率不一定完全兼容
1 设计过程
1.1 设计验证题目是否合理的函数
根据出题条件,出题时要验证题目是否合理,这里已经保证了左边的值,右边的值和运算符都符合要求。具体的判断如下即可保证题目一定正确:
- 针对加法:如果结果result>99则不符合出题条件,返回False
- 针对减法:如果结果result<0则不符合出题条件,返回False
- 针对乘法:如果结果result>99则不符合出题条件,返回False
- 针对除法:如果分母=0,或者除了后不是整数,返回False
- 其它情况返回True,result
完整的代码如下:
def check_problem(left_value, math_operation, right_value):
"""
检查是否符合出题条件
:param left_value: 左边的值
:param math_operation: 运算符
:param right_value: 右边的值
:return: 如果符合则返回True,不符合返回Flase,以及计算结果result
"""
result = None
if math_operation == "+":
result = left_value + right_value
if result > 99:
return False, result
elif math_operation == "-":
result = left_value - right_value
if result < 0:
return False, result
elif math_operation == "x":
result = left_value * right_value
if result > 99:
return False, result
elif math_operation == "÷":
if (right_value == 0) or (left_value % right_value != 0):
return False, result
result = int(left_value / right_value)
return True, result
1.2 生成试卷
因为试卷是5行3列的关系,所以可以使用二维列表保存5行3列结构的数据,左边的值、右边的值、运算符和计算结果都用二维列表表示。
使用python的random库的chioce方法:
for i in range(5):
for j in range(3):
(针对第i行第j列)
step 1——从("+", "-", "x", "÷")中使用random.choice()方法选择运算符,并且把运算符保存到二维列表math_operation_list中
step 2——确定运算符后,使用random.choice(range(0, 100))随机生成左边的值和右边的值,并且对取值进行验证是否合理,直到 生成合理的值为止。
step 3——保存左边的值到二维列表left_list中,保存右边的值到二维列表right_list中,对应的计算结果也保存到二维列表result_list 中。
step 4——返回左边的值、右边的值、运算符和计算结果的二维列表left_list, right_list, math_operation_list, result_list,试卷生成 完毕!
完整代码如下:
def gennerate_test_paper():
"""生成试卷"""
left_list = [] # 左边的值
right_list = [] # 右边的值
math_operation_list = [] # 运算符
result_list = [] # 计算结果
for i in range(5):
left_list.append([])
right_list.append([])
math_operation_list.append([])
result_list.append([])
for j in range(3):
_temp_math_operation = random.choice(("+", "-", "x", "÷"))
math_operation_list[i].append(_temp_math_operation)
while True:
_temp_left_list_value = random.choice(range(0, 100))
_temp_right_list_value = random.choice(range(0, 100))
check_problem_state, _temp_result = check_problem(left_value=_temp_left_list_value,
math_operation=_temp_math_operation,
right_value=_temp_right_list_value)
if check_problem_state:
result_list[i].append(_temp_result)
break
left_list[i].append(_temp_left_list_value)
right_list[i].append(_temp_right_list_value)
return left_list, right_list, math_operation_list, result_list
1.3 检查试卷是否有重复项
检查试卷是否有重复项是用的“暴力查找的方式”,把所有的题目都两两检索一遍(除了自身),检查是否完全一样,时间复杂度是
时间复杂度虽然很高,但考虑到这里的i=5和j=3很小,所以暴力查找检查是否有重复项即可。
完整的代码如下:
def check_duplicate_problems(left_list, math_operation_list, right_list):
"""
检查是否有重复题目
:param left_list:
:param math_operation_list:
:param right_list:
:return: 如果没有重复返回True,否则返回False
"""
for i in range(5):
for j in range(3):
for k in range(5):
for l in range(3):
if i != k and j != l:
if left_list[i][j] == left_list[k][l] and math_operation_list[i][j] == math_operation_list[k][
l] and \
right_list[i][j] == right_list[k][l]:
return False
return True
while not check_duplicate_problems_state:
"""检查试卷是否有重复项"""
left_list, right_list, math_operation_list, result_list = gennerate_test_paper()
check_duplicate_problems_state = check_duplicate_problems(left_list, math_operation_list, right_list)
1.4 使用turtle库画出试卷
-
step 1——画标题
goto到坐标(-450,500)画标题
-
step 2——画“试卷”和下划线,“答案”和下划线
goto到坐标(-450,400)画“试题“和对应下划线;goto到坐标(-450,0)画“答案“和对应下划线;
-
step 3——画具体的试卷内容和答案内容
初始化试卷内容和答案内容的坐标
for i in range(5):
每画一行纵坐标下移
for j in range(3):
每画一列横坐标右移
画对应i行j列的“左边的值 运算符 右边的值”
画"="号
画“方框”
对于答案的区域,还要在“方框”区域画上答案
完整的代码如下:
"""标题"""
penup()
goto(x=-450, y=500)
write(arg="某小学数学试卷 姓名:_________ 成绩:_________", move=True, align='left',
font=('微软雅黑', 20, 'normal'))
"""试卷"""
penup()
goto(x=-450, y=400)
write(arg="试题", move=True, align='left', font=('微软雅黑', 20, 'normal'))
penup()
goto(x=-450, y=400)
write(arg="______________________________________________________________________________", move=True, align='left',
font=('微软雅黑', 20, 'normal'))
"""答案"""
penup()
goto(x=-450, y=0)
write(arg="答案", move=True, align='left', font=('微软雅黑', 20, 'normal'))
penup()
goto(x=-450, y=0)
write(arg="______________________________________________________________________________", move=True, align='left',
font=('微软雅黑', 20, 'normal'))
y_paper = 400
y_answer = 0
for i in range(5):
"""5行"""
x_paper = -700
y_paper = y_paper - 50
x_answer = -700
y_answer = y_answer - 50
for j in range(3):
x_paper = x_paper + 300
x_answer = x_answer + 300
"""3列"""
arg = f"{left_list[i][j]} {math_operation_list[i][j]} {right_list[i][j]}"
"""试卷"""
penup()
goto(x=x_paper, y=y_paper)
write(arg=arg, move=True, align='left', font=('微软雅黑', 20, 'normal'))
# =号
penup()
goto(x=x_paper + 150, y=y_paper)
write(arg="=", move=True, align='left', font=('微软雅黑', 20, 'normal'))
# 方框
goto(x=x_paper + 200, y=y_paper)
pendown()
plow_n(n=4, forward_len=45)
penup()
"""答案"""
penup()
goto(x=x_answer, y=y_answer)
write(arg=arg, move=True, align='left', font=('微软雅黑', 20, 'normal'))
# =号
penup()
goto(x=x_answer + 150, y=y_answer)
write(arg="=", move=True, align='left', font=('微软雅黑', 20, 'normal'))
# 方框
goto(x=x_answer + 200, y=y_answer)
pendown()
plow_n(n=4, forward_len=45)
penup()
# 答案
penup()
goto(x=x_answer + 210, y=y_answer)
write(arg=f"{result_list[i][j]}", move=True, align='left', font=('微软雅黑', 20, 'normal'))
exitonclick()
2 结果展示
3 完整代码为
"""
使用Python的海龟库完成小学数学题试卷的出题工作,要求:
(1)上半部分为题目,下半部分为答案。
(2)试题中,计算结果显示为方框。答案中,在方框中出现结果。题目和答案的顺序对应。
(3)题目每行3题,共5行。答案数量相同。
(4)题目随机生成。(建议使用random库中的sample, choice函数)
(5)不得有重复的题目(即两道题目的运算符相同、运算符左/右的操作数分别相同,结果也相同的题目)。
(6)题目分为加减乘除四类,运算过程和结果均为两位以内的整数(0到99)。
(7)完成上述代码功能(提交py代码),同时完成较为简单的软件设计文档(提交pdf即可),文档包括设计思路、关键代码解释、效果图等。
"""
from turtle import *
import random
screensize(1000, 1000)
speed(0)
def plow_n(n, forward_len):
"""
画N边形
:param forward_len: 决定画的大小
:param n:决定N变形
:return:
"""
angle = 360 / n
for i in range(n):
forward(forward_len)
left(angle)
def check_problem(left_value, math_operation, right_value):
"""
检查是否符合出题条件
:param left_value: 左边的值
:param math_operation: 运算符
:param right_value: 右边的值
:return: 如果符合则返回True,不符合返回Flase,以及计算结果result
"""
result = None
if math_operation == "+":
result = left_value + right_value
if result > 99:
return False, result
elif math_operation == "-":
result = left_value - right_value
if result < 0:
return False, result
elif math_operation == "x":
result = left_value * right_value
if result > 99:
return False, result
elif math_operation == "÷":
if (right_value == 0) or (left_value % right_value != 0):
return False, result
result = int(left_value / right_value)
return True, result
def check_duplicate_problems(left_list, math_operation_list, right_list):
"""
检查是否有重复题目
:param left_list:
:param math_operation_list:
:param right_list:
:return: 如果没有重复返回True,否则返回False
"""
for i in range(5):
for j in range(3):
for k in range(5):
for l in range(3):
if i != k and j != l:
if left_list[i][j] == left_list[k][l] and math_operation_list[i][j] == math_operation_list[k][
l] and \
right_list[i][j] == right_list[k][l]:
return False
return True
def gennerate_test_paper():
"""生成试卷"""
left_list = [] # 左边的值
right_list = [] # 右边的值
math_operation_list = [] # 运算符
result_list = [] # 计算结果
for i in range(5):
left_list.append([])
right_list.append([])
math_operation_list.append([])
result_list.append([])
for j in range(3):
_temp_math_operation = random.choice(("+", "-", "x", "÷"))
math_operation_list[i].append(_temp_math_operation)
while True:
_temp_left_list_value = random.choice(range(0, 100))
_temp_right_list_value = random.choice(range(0, 100))
check_problem_state, _temp_result = check_problem(left_value=_temp_left_list_value,
math_operation=_temp_math_operation,
right_value=_temp_right_list_value)
if check_problem_state:
result_list[i].append(_temp_result)
break
left_list[i].append(_temp_left_list_value)
right_list[i].append(_temp_right_list_value)
return left_list, right_list, math_operation_list, result_list
left_list = [] # 左边的值
right_list = [] # 右边的值
math_operation_list = [] # 运算符
result_list = [] # 计算结果
check_duplicate_problems_state = False # 刚开始是False
while not check_duplicate_problems_state:
"""检查试卷是否有重复项"""
left_list, right_list, math_operation_list, result_list = gennerate_test_paper()
check_duplicate_problems_state = check_duplicate_problems(left_list, math_operation_list, right_list)
print(f"left_list:{left_list}")
print(f"right_list:{right_list}")
print(f"math_operation_list:{math_operation_list}")
"""标题"""
penup()
goto(x=-450, y=500)
write(arg="某小学数学试卷 姓名:_________ 成绩:_________", move=True, align='left',
font=('微软雅黑', 20, 'normal'))
"""试卷"""
penup()
goto(x=-450, y=400)
write(arg="试题", move=True, align='left', font=('微软雅黑', 20, 'normal'))
penup()
goto(x=-450, y=400)
write(arg="______________________________________________________________________________", move=True, align='left',
font=('微软雅黑', 20, 'normal'))
"""答案"""
penup()
goto(x=-450, y=0)
write(arg="答案", move=True, align='left', font=('微软雅黑', 20, 'normal'))
penup()
goto(x=-450, y=0)
write(arg="______________________________________________________________________________", move=True, align='left',
font=('微软雅黑', 20, 'normal'))
y_paper = 400
y_answer = 0
for i in range(5):
"""5行"""
x_paper = -700
y_paper = y_paper - 50
x_answer = -700
y_answer = y_answer - 50
for j in range(3):
x_paper = x_paper + 300
x_answer = x_answer + 300
"""3列"""
arg = f"{left_list[i][j]} {math_operation_list[i][j]} {right_list[i][j]}"
"""试卷"""
penup()
goto(x=x_paper, y=y_paper)
write(arg=arg, move=True, align='left', font=('微软雅黑', 20, 'normal'))
# =号
penup()
goto(x=x_paper + 150, y=y_paper)
write(arg="=", move=True, align='left', font=('微软雅黑', 20, 'normal'))
# 方框
goto(x=x_paper + 200, y=y_paper)
pendown()
plow_n(n=4, forward_len=45)
penup()
"""答案"""
penup()
goto(x=x_answer, y=y_answer)
write(arg=arg, move=True, align='left', font=('微软雅黑', 20, 'normal'))
# =号
penup()
goto(x=x_answer + 150, y=y_answer)
write(arg="=", move=True, align='left', font=('微软雅黑', 20, 'normal'))
# 方框
goto(x=x_answer + 200, y=y_answer)
pendown()
plow_n(n=4, forward_len=45)
penup()
# 答案
penup()
goto(x=x_answer + 210, y=y_answer)
write(arg=f"{result_list[i][j]}", move=True, align='left', font=('微软雅黑', 20, 'normal'))
exitonclick()
本文来自博客园,作者:JaxonYe,转载请注明原文链接:https://www.cnblogs.com/yechangxin/articles/17240296.html
侵权必究