Apakah ada perangkat lunak yang secara berkala memungkinkan saya melakukan latihan aritmatika mental?

9

Saya menyadari sifat malas saya dan perlu mendorong diri saya untuk melakukan beberapa aritmatika mental dasar dari waktu ke waktu. Oleh karena itu, saya mencari perangkat lunak yang secara berkala meminta saya untuk melakukan latihan aritmatika mental singkat (plus, minus, gandakan, bagi).

Kriteria:

  • Seharusnya saya dapat menyesuaikan waktu interval
  • Itu harus berintegrasi di Desktop Ubuntu, yaitu disembunyikan di latar belakang dan hanya muncul (pop-up) selama waktu latihan
orschiro
sumber
2
Saya ragu perangkat lunak seperti itu ada, tetapi bisa sangat mudah dibuat dengan shell atau skrip python. Saya akan memasak sesuatu besok, tolong ingatkan saya
Sergiy Kolodyazhnyy
Ya, bsdgames memiliki aritmatika dan semacamnya, tetapi Anda harus mengotomatiskan popup berkala sendiri.
mchid
Dear @Serg, saya mengingatkan Anda tentang eksperimen memasak Anda. :)
orschiro
1
Jadi saya telah memposting jawaban yang sedang dalam proses, yang akan saya edit saat saya melanjutkan. Silakan lihat, beri tahu saya apa pendapat Anda, fungsionalitas apa yang harus ditambahkan atau dihapus. Sejauh ini ini adalah aplikasi konsol, tetapi pada akhirnya akan berubah menjadi jendela sembulan kecil.
Sergiy Kolodyazhnyy
2
Ternyata menjadi pertanyaan yang bagus untuk dikerjakan!
Jacob Vlijm

Jawaban:

8

1. Versi sederhana

Skrip di bawah ini akan menghasilkan tugas secara acak, + , - , × dan ÷ . Anda dapat (dan harus) menetapkan jumlah maksimum yang dapat digunakan skrip, serta interval waktu antara penugasan.

Tugas

Tugas disajikan dalam jendela entri Zenity:

masukkan deskripsi gambar di sini

jika jawabannya salah:

masukkan deskripsi gambar di sini

Jika jawabannya benar:

masukkan deskripsi gambar di sini

Naskah

#!/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()

Cara Penggunaan

  1. Salin skrip ke file kosong, simpan sebagai mindpractice.py
  2. Jalankan dengan jumlah maksimum yang diizinkan dan waktu interval (dalam detik) antara penugasan sebagai argumen:

    python3 /path/to/mindpractice.py <max_number> <interval>

    misalnya

    python3 /path/to/mindpractice.py 1000 300

    untuk melakukan perhitungan hingga angka 1000, dengan istirahat 5 menit di antara tugas.

  3. Jika semua berfungsi dengan baik, Anda dapat menambahkannya ke aplikasi startup dengan cara biasa, atau peluncur untuk beralih dapat dibuat, yang mungkin saya tambahkan nanti :)

Catatan

  • The pemisah mungkin perlu beberapa penjelasan. Anda mungkin tidak ingin menghitung dalam pelampung. Oleh karena itu, jika tugasnya adalah pembagian, skrip mencari angka yang dapat dibagi dengan, dan mengambil satu (secara acak). Jika nomor (utama) ternyata menjadi bilangan prima, penugasan diubah menjadi tipe lain.

2. Opsi lainnya

Setelah Anda mulai menghitung, Anda akan mengetahui bahwa membagi hingga angka (katakanlah) 100 jauh lebih mudah daripada mengalikan angka hingga 100.

Dengan skrip di bawah ini Anda dapat (dan harus) mengatur jumlah maksimum per jenis latihan (lihat instruksi di bawah skrip).

Naskah

#!/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()

Cara Penggunaan

  • Siapkan skrip persis seperti yang pertama, tetapi jalankan dengan argumen (dalam urutan apa pun, skrip akan menautkan argumen yang benar ke item yang tepat):

    • p: jeda (istirahat di antara tugas, dalam detik))
    • s: kurangi (jumlah maksimal untuk dihitung dengan)
    • a: tambah (jumlah maksimal)
    • m: berkembang biak (jumlah maks)
    • d: bagi (jumlah maks)

    Sebagai contoh:

    python3 '/home/jacob/Desktop/num.py' a:10 d:100 s:10 m:10 p:300

    untuk menunjukkan latihan setiap lima menit, angka hingga 10, kecuali dibagi hingga angka 100.


3. Mari kita terbawa sedikit

Mampu melihat beberapa statistik

Versi di bawah ini menunjukkan statistik setelah setiap 10 latihan:

masukkan deskripsi gambar di sini

Selain itu (mungkin berguna ketika digunakan untuk anak-anak), Anda dapat melihat apa yang salah dalam 100 latihan yang salah menjawab. Dalam file tersembunyi, tugas dan jawaban mereka (salah) ditulis:

masukkan deskripsi gambar di sini

File log ini berada:

~/.calculog

Naskah

#!/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 = []

Cara Penggunaan

Penggunaannya hampir sama dengan opsi 2, tetapi Anda akan memiliki file log yang tersedia dan skor setelah setiap 10 tugas.


4. Versi terakhir

Versi di bawah ini seperti opsi 3 (termasuk file log dan laporan), tetapi memiliki beberapa fitur tambahan:

  • menambahkan penghitungan akar kuadrat

    masukkan deskripsi gambar di sini

  • menambahkan menggunakan rentang angka, bukan hanya mengatur maksimum

  • menambahkan opsi untuk hanya menjalankan tipe perhitungan tertentu (mis. hanya bagikan dan gandakan).
  • ingat argumen yang dijalankan dengan terakhir kali, ketika dijalankan tanpa argumen (hanya pertama kali, argumen harus disetel). Jika tidak ada argumen yang ditetapkan saat dijalankan pertama kali, skrip mengirim pesan:

    masukkan deskripsi gambar di sini

Naskah

#!/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 = []

Cara Penggunaan

  • Salin skrip ke file kosong, simpan (lagi) sebagai mindpractice.py. Jalankan dengan opsi berikut (sebagai contoh)

    Harus diatur:

    p:300                to set the interval between assignments to 5 minutes

    Opsional (pilih):

    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
  • Contoh perintah:

    python3 '/path/to/mindpractice.py' p:300 d:10-100 s:10-30  r:300-600

    untuk mengatur:

    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

    saat menambahkan dan mengalikan tidak digunakan.

Kemudian waktu berikutnya, jika skrip dijalankan dengan:

python3 '/path/to/mindpractice.py'

Ini akan mengingat argumen yang terakhir digunakan


Gunakan versi yang paling sesuai dengan kebutuhan Anda ...


Yakub Vlijm
sumber
Versi ini berfungsi dengan baik sejauh ini. Terima kasih banyak!
orschiro
1
@orschiro menambahkan versi yang diperluas, untuk menyulitkan kesulitan.
Jacob Vlijm
file log adalah ide yang sangat bagus! Saat ini saya mencoba untuk mendapatkan beberapa penggandaan dan pembagian tiga digit. Mereka tidak begitu mudah. :)
orschiro
hanya sebuah ide: Kadang-kadang saya sangat fokus pada pekerjaan sehingga saya mengabaikan Think Hardjendela untuk menyelesaikan pekerjaan sebelumnya (mis. selesai menulis kalimat). Saya kemudian lupa tentang jendela. Mungkinkah setelah 5 menit, Think Hardjendela secara otomatis mendapatkan kembali fokus?
orschiro
1
@orschiro benar-benar! Saya juga masih mengunyah versi GUI yang sepenuhnya (tidak perlu mengatur apa pun dari baris perintah, bahkan tidak menjalankan pertama), tetapi saya tidak yakin mereka akan memungkinkan kita untuk menambahkan lebih banyak meter ke jawaban :)
Jacob Vlijm
3

Pengantar:

Aplikasi berikut ini menghasilkan ekspresi integer acak untuk dievaluasi oleh pengguna. Kisaran ekspresi yang dibuat secara acak tergantung pada pengaturan pengguna di jendela sembulan utama. Setelah mengklik Lets Begintombol, sesi dimulai tanpa batas waktu, hingga pengguna menekan tombol Batal.

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

Kode sumber:

#!/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()
Sergiy Kolodyazhnyy
sumber
Dear @Serg, saya juga ingin mengucapkan terima kasih secara pribadi untuk versi GUI Anda yang diperluas. Satu pertanyaan, saya baru saja latihan 15/14 = 1. Saya tidak yakin seberapa bermanfaat latihan semacam itu. Bagaimana menurut anda?
orschiro
@orschiro ini integer arithmetic. Itu berarti hasil hanya sebagian, tidak ada sisa. Jika Anda mau, saya bisa mencoba menerapkan decimalaritmatika juga. Selain itu, beri tahu saya opsi apa yang ingin Anda terapkan dan tambahkan. Saat ini, saya mencoba untuk berlatih agile developmentmetode, dan komunikasi dengan klien adalah kunci dalam metode tersebut. Tolong beritahu saya.
Sergiy Kolodyazhnyy
senang mendengar! Saya ingin memberi Anda lebih banyak umpan balik, misalnya integrasi yang lebih baik ke Desktop Ubuntu (jalankan skrip lebih banyak di latar belakang, yaitu meminimalkan setelah input pengguna). Bagaimana saya bisa memberikan Anda umpan balik lebih lanjut?
orschiro