![有没有一个软件可以让我定期做心算练习?](https://linux22.com/image/987375/%E6%9C%89%E6%B2%A1%E6%9C%89%E4%B8%80%E4%B8%AA%E8%BD%AF%E4%BB%B6%E5%8F%AF%E4%BB%A5%E8%AE%A9%E6%88%91%E5%AE%9A%E6%9C%9F%E5%81%9A%E5%BF%83%E7%AE%97%E7%BB%83%E4%B9%A0%EF%BC%9F.png)
我知道自己很懒,需要时不时地强迫自己做一些基本的心算。因此,我正在寻找一款可以定期要求我进行简短心算练习(加、减、乘、除)的软件。
标准:
- 它应该允许我自定义间隔时间
- 它应该集成在 Ubuntu 桌面中,即隐藏在后台,仅在锻炼时间显示(弹出)
答案1
1. 简单版
下面的脚本将随机产生任务,+,-,×和÷。您可以(并且应该)设置脚本可以使用的最大数量,以及分配之间的时间间隔。
任务
任务显示在 Zenity 输入窗口中:
如果答案错误:
如果答案正确:
剧本
#!/usr/bin/env python3
from random import randint
import sys
import subprocess
import time
# maximum number & interval
max_n = int(sys.argv[1]); pause = int(sys.argv[2])
def fix_float(n):
"""
if the assignment is a division, the script divides the random number by a
number (integer) it can be divided by. it looks up those numbers, and picks
one of them (at random). if the number is a prime number the assignment is
changed into another type
"""
try:
divs = [i for i in range(2, n) if n%i == 0]
pick = randint(1, len(divs))
div_by = divs[pick-1]
return [str(n)+" : "+str(div_by), int(n/div_by)]
except (ValueError, IndexError):
pass
def get_assignment():
"""
get a random number within the user defined range, make the assignment and
the textual presentation
"""
n1 = randint(2, max_n); n2 = randint(2, max_n)
assignments = [
[str(n1)+" + "+str(n2), n1+n2],
[str(n1)+" - "+str(n2), n1-n2],
[str(n1)+" x "+str(n2), n1*n2],
fix_float(n1),
]
# pick an assignment (type) at random
assignment = assignments[randint(0, 3)]
# if the random number is a prime number and the assignment a division...
assignment = assignment if assignment != None else assignments[1]
# run the interface job
try:
answer = int(subprocess.check_output(["/bin/bash", "-c",
'zenity --entry --title="Think hard:" --text='+'"'+assignment[0]+'"'
]).decode("utf-8"))
if answer == assignment[1]:
subprocess.Popen(["notify-send", "Coolcool"])
else:
subprocess.Popen([
"notify-send", "Oooops, "+assignment[0]+\
" = "+str(assignment[1])])
except (subprocess.CalledProcessError, ValueError):
pass
while True:
time.sleep(pause)
get_assignment()
如何使用
- 将脚本复制到一个空文件中,另存为
mindpractice.py
以允许的最大数量和分配之间的间隔时间(以秒为单位)作为参数来运行它:
python3 /path/to/mindpractice.py <max_number> <interval>
例如
python3 /path/to/mindpractice.py 1000 300
进行最多为的计算
1000
,作业之间有5分钟的休息时间。如果一切正常,您可以按照通常的方式将其添加到启动应用程序中,或者可以制作一个可切换的启动器,我可能会稍后添加:)
笔记
- 这分割可能需要一些解释。您可能不喜欢用浮点数进行计算。因此,如果分配是除法,脚本会查找可以除以的数字,并(随机)选择一个。如果(主)数字是素数,则分配将更改为另一种类型。
2. 更多选择
一旦你开始计算,你会发现分割比方说,100 这个数字要容易得多倍增数字最多为 100。
使用下面的脚本,你可以(并且应该)设置数字的最大值每种运动类型(请参阅脚本下方的说明)。
剧本
#!/usr/bin/env python3
from random import randint
import sys
import subprocess
import time
levels = sys.argv[1:]
pause = [int(arg.replace("p:", "")) for arg in levels if "p:" in arg][0]
def fix_float(n):
"""
if the assignment is a division, the script divides the random number by a
number (integer) it can be divided by. it looks up those numbers, and picks
one of them (at random). if the number is a prime number the assignment is
changed into another type
"""
try:
divs = [i for i in range(2, n) if n%i == 0]
pick = randint(1, len(divs))
div_by = divs[pick-1]
return [str(n)+" : "+str(div_by), int(n/div_by)]
except (ValueError, IndexError):
pass
def get_assignment():
"""
get a random number within the user defined range, make the assignment and
the textual presentation
"""
# pick an assignment (type) at random
track = randint(0, 3)
arg = ["a:", "s:", "m:", "d:"][track]
max_n = [int(item.replace(arg, "")) for item in levels if arg in item][0]
n1 = randint(2, max_n); n2 = randint(2, max_n)
assignments = [
[str(n1)+" + "+str(n2), n1+n2],
[str(n1)+" - "+str(n2), n1-n2],
[str(n1)+" x "+str(n2), n1*n2],
fix_float(n1),
]
assignment = assignments[track]
# if the random number is a prime number and the assignment a division...
assignment = assignment if assignment != None else assignments[1]
# run the interface job
try:
answer = int(subprocess.check_output(["/bin/bash", "-c",
'zenity --entry --title="Think hard:" --text='+'"'+assignment[0]+'"'
]).decode("utf-8"))
if answer == assignment[1]:
subprocess.Popen(["notify-send", "Coolcool"])
else:
subprocess.Popen([
"notify-send", "Oooops, "+assignment[0]+\
" = "+str(assignment[1])])
except (subprocess.CalledProcessError, ValueError):
pass
while True:
time.sleep(pause)
get_assignment()
如何使用
像第一个一样设置脚本,但使用参数运行它(无论以何种顺序,脚本都会将正确的参数链接到正确的项目):
p:
暂停(作业之间的停顿,以秒为单位)s:
减去(计算的最大数)a:
添加(最大数量)m:
乘以(最大数)d:
除法(最大数)
例如:
python3 '/home/jacob/Desktop/num.py' a:10 d:100 s:10 m:10 p:300
每五分钟显示一次锻炼,数字最多为 10,除了除以 100。
3. 让我们有点忘乎所以
能够看到一些统计数据
以下版本显示每 10 次锻炼后的统计数据:
此外(对儿童来说可能有用),您可以看到最近 100 个错误回答的练习中出了什么问题。在隐藏文件中,作业及其(错误)答案都写在:
该日志文件位于:
~/.calculog
剧本
#!/usr/bin/env python3
from random import randint
import sys
import subprocess
import time
import os
log = os.environ["HOME"]+"/.calculog"
levels = sys.argv[1:]
pause = [int(arg.replace("p:", "")) for arg in levels if "p:" in arg][0]
def fix_float(n):
"""
if the assignment is a division, the script divides the random number by a
number (integer) it can be divided by. it looks up those numbers, and picks
one of them (at random). if the number is a prime number the assignment is
changed into another type
"""
try:
divs = [i for i in range(2, n) if n%i == 0]
pick = randint(1, len(divs))
div_by = divs[pick-1]
return [str(n)+" : "+str(div_by), int(n/div_by)]
except (ValueError, IndexError):
pass
def get_assignment():
"""
get a random number within the user defined range, make the assignment and
the textual presentation
"""
# pick an assignment (type) at random
track = randint(0, 3)
arg = ["a:", "s:", "m:", "d:"][track]
max_n = [int(item.replace(arg, "")) for item in levels if arg in item][0]
n1 = randint(2, max_n); n2 = randint(2, max_n)
assignments = [
[str(n1)+" + "+str(n2), n1+n2],
[str(n1)+" - "+str(n2), n1-n2],
[str(n1)+" x "+str(n2), n1*n2],
fix_float(n1),
]
assignment = assignments[track]
# if the random number is a prime number and the assignment a division...
assignment = assignment if assignment != None else assignments[1]
# run the interface job
try:
answer = int(subprocess.check_output(["/bin/bash", "-c",
'zenity --entry --title="Think hard:" --text='+'"'+assignment[0]+'"'
]).decode("utf-8"))
if answer == assignment[1]:
subprocess.Popen(["notify-send", "Coolcool"])
return "ok"
else:
subprocess.Popen([
"notify-send", "Oooops, "+assignment[0]+\
" = "+str(assignment[1])])
open(log, "+a").write(assignment[0]+"\t\t"+str(answer)+"\n")
try:
history = open(log).read().splitlines()
open(log, "wt").write(("\n").join(history[-100:])+"\n")
except FileNotFoundError:
pass
return "mistake"
except (subprocess.CalledProcessError, ValueError):
return None
results = []
while True:
time.sleep(pause)
results.append(get_assignment())
if len(results) >= 10:
score = results.count("ok")
subprocess.call([
"zenity", "--info",
'--title=Latest scores',
'--text='+str(score)+' out of 10',
'--width=160',
])
results = []
如何使用
使用方法与选项 2 几乎完全相同,但是您将获得日志文件以及每 10 次作业后的分数。
4. 终极版
下面的版本与选项 3 类似(包括日志文件和报告),但有一些附加功能:
添加计算平方根
添加使用范围而不是简单地设置最大值
- 添加仅运行的选项具体的计算类型(例如仅除法和乘法)。
记住上次运行时使用的参数,当不带参数运行时(仅限第一次,参数必须无需设置)。如果第一次运行时未设置任何参数,脚本将发送一条消息:
剧本
#!/usr/bin/env python3
from random import randint
import sys
import subprocess
import time
import os
"""
Use this script to practice head count. Some explanation might be needed:
The script can be used for the following types of calculating:
Type argument example explanation
-------------------------------------------------------------------------------
add a:30-100 to add in numbers from 30-100
subtract s:10-100 to subtract in numbers from 10-100
multiply m:10-20 to multiply in numbers from 10-20
divide d:200-400 to divide in numbers from 200-400
square root r:1-1000 to find square root in numbers from 1-1000
N.B.
-------------------------------------------------------------------------------
- The argument p: (pause in seconds; break between the assignments) *must* be
set, for example: p:300 to launch an assignment every 5 minutes
- A calculation type will only run *if* the argument is set for the
corresponding type. An example: python3 /path/to/script p:60 s:30-60
will run a subtract- assignment every minute.
Miscellaneous information:
-------------------------------------------------------------------------------
- On first run, arguments *must* be set. After first run, when no arguments
are used the last set arguments will run, until the script is run with a new
set of arguments.
- A log file of the last 100 incorrectly answered questions is kept in
~/.calculog
- After 10 assignments, the score of the last 10 pops up.
"""
log = os.environ["HOME"]+"/.calculog"
prefs = os.environ["HOME"]+"/.calcuprefs"
levels = sys.argv[1:]
if levels:
open(prefs, "wt").write(str(levels))
else:
try:
levels = eval(open(prefs).read())
except FileNotFoundError:
subprocess.call([
"zenity", "--info",
'--title=Missing arguments',
'--text=On first run, the script needs to be run with arguments\n'
])
def fix_float(n):
"""
if the assignment is a division, the script divides the random number by a
number (integer) it can be divided by. it looks up those numbers, and picks
one of them (at random). if the number is a prime number the assignment is
changed into another type
"""
try:
divs = [i for i in range(2, n) if n%i == 0]
pick = randint(1, len(divs))
div_by = divs[pick-1]
return [str(n)+" : "+str(div_by), int(n/div_by)]
except (ValueError, IndexError):
pass
def fix_sqr(f1, f2):
"""
If the assignment is calculating a square root, this function finds the sets
of numbers (integers) that make a couple, within the given range.
"""
q = f1; r = q**(.5); sets = []
while q < f2:
r = q**(.5)
if r == int(r):
sets.append([int(r), int(q)])
q = q+1
if sets:
pick = sets[randint(0, len(sets)-1)]
return ["√"+str(pick[1]), pick[0]]
def get_assignment():
"""
get a random number within the user defined range, make the assignment and
the textual presentation
"""
args = ["a:", "s:", "m:", "d:", "r:"]
indc = []
for i, item in enumerate(args):
if item in str(levels):
indc.append(i)
index = indc[randint(0, len(indc)-1)]
name = args[index]
minmax = [
[int(n) for n in item.replace(name, "").split("-")] \
for item in levels if name in item][0]
assignment = None
# if the random number is a prime number *and* the assignment a division
# or a square root...
while assignment == None:
n1 = randint(minmax[0], minmax[1]); n2 = randint(minmax[0], minmax[1])
assignment = [
[str(n1)+" + "+str(n2), n1+n2],
[str(n1)+" - "+str(n2), n1-n2],
[str(n1)+" x "+str(n2), n1*n2],
fix_float(n1),
fix_sqr(minmax[0], minmax[1]),
][index]
# run the interface job
try:
answer = int(subprocess.check_output(["/bin/bash", "-c",
'zenity --entry --title="Think hard:" --text='+'"'+assignment[0]+'"'
]).decode("utf-8"))
if answer == assignment[1]:
subprocess.Popen(["notify-send", "Coolcool"])
return "ok"
else:
subprocess.Popen([
"notify-send", "Oooops, "+assignment[0]+\
" = "+str(assignment[1])])
open(log, "+a").write(assignment[0]+"\t\t"+str(answer)+"\n")
try:
history = open(log).read().splitlines()
open(log, "wt").write(("\n").join(history[-100:])+"\n")
except FileNotFoundError:
pass
return "mistake"
except (subprocess.CalledProcessError, ValueError):
return None
if levels:
pause = [int(arg.replace("p:", "")) for arg in levels if "p:" in arg][0]
[levels.remove(item) for item in levels if "p:" in item]
results = []
while True:
time.sleep(pause)
results.append(get_assignment())
if len(results) >= 10:
score = results.count("ok")
subprocess.call([
"zenity", "--info",
'--title=Latest scores',
'--text='+str(score)+' out of 10',
'--width=160',
])
results = []
如何使用
将脚本复制到一个空文件中,再次将其另存为
mindpractice.py
。使用以下选项运行它(作为示例)必须设置:
p:300 to set the interval between assignments to 5 minutes
可选(做出选择):
a:30-100 to add in numbers from 30-100 (optional) s:10-100 to subtract in numbers from 10-100 m:10-20 to multiply in numbers from 10-20 d:200-400 to divide in numbers from 200-400 r:1-1000 to find square root in numbers from 1-1000
示例命令:
python3 '/path/to/mindpractice.py' p:300 d:10-100 s:10-30 r:300-600
设置:
p:300 to set the interval between assignments to 5 minutes d:10-100 to divide in numbers from 10-100 s:10-30 to subtract in numbers from 10-30 r:300-600 to calculate square roots from 300-600
尽管添加和倍增未被使用。
然后下一次,如果使用以下命令运行脚本:
python3 '/path/to/mindpractice.py'
它会记住最后使用的参数
使用最适合您需求的版本...
答案2
介绍:
以下应用程序生成随机整数表达式供用户评估。随机生成的表达式的范围取决于用户在主弹出窗口中的设置。单击Lets Begin按钮后,会话将无限期启动,直到用户点击“取消”按钮。
源代码:
#!/usr/bin/env python
# Author: Serg Kolo
# Date: Jan 30,2016
# Purpose: A graphical utility for practicing
# random arithmetic operations
# Written for: http://askubuntu.com/q/725287/295286
# Copyright: Serg Kolo , 2016
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
import time
import random
from PyQt4 import QtGui
class mathApp(QtGui.QWidget):
def __init__(self):
super(mathApp,self).__init__()
self.mainMenu()
def mainMenu(self):
self.setGeometry(300, 300, 400, 200)
self.btn = QtGui.QPushButton("Let's begin",self)
self.btn.move(20,150)
self.btn.clicked.connect(self.askQuestions)
self.lbl1 = QtGui.QLabel(self)
self.lbl1.move(20,25)
self.lbl1.setText("Numbers From")
self.lbl2 = QtGui.QLabel(self)
self.lbl2.move(20,55)
self.lbl2.setText("Numbers To")
self.lbl2 = QtGui.QLabel(self)
self.lbl2.move(20,85)
self.lbl2.setText("Repeat (seconds)")
self.le1 = QtGui.QLineEdit(self)
self.le1.move(150,20)
self.le2 = QtGui.QLineEdit(self)
self.le2.move(150,50)
self.le3 = QtGui.QLineEdit(self)
self.le3.move(150,80)
self.lbl3 = QtGui.QLabel(self)
self.lbl3.move(20,105)
self.setWindowTitle('Random Integer Arithmetic')
self.show()
def askQuestions(self):
rangeStart = int(self.le1.text())
rangeEnd = int(self.le2.text())
sleepTime = int(self.le3.text())
done=False
while not done:
self.show()
expression = self.generateOperation(rangeStart,rangeEnd)
correctAnswer = eval(expression)
prompt = QtGui.QInputDialog()
text,ok = prompt.getText(self,"Don't think too hard",expression)
if ok:
if int(text) == correctAnswer:
self.showAnswer("CORRECT,YOU ROCK !")
else :
self.showAnswer("Nope");
else:
done=True
if done==True:
self.close()
time.sleep(sleepTime)
def generateOperation(self,start,end):
a = random.randint(start,end)
b = random.randint(start,end)
oplist = ['+','-','/','*']
op = oplist[random.randint(0,3)]
expr = str(a) + op + str(b) + ''
return expr
def showAnswer(self,result):
popup = QtGui.QMessageBox()
popup.setText(result)
popup.exec_()
def main():
root = QtGui.QApplication(sys.argv)
app = mathApp()
sys.exit(root.exec_())
if __name__ == '__main__':
main()