Existe-t-il un logiciel qui me permet périodiquement de faire des exercices d'arithmétique mentale?

9

Je suis conscient de ma nature paresseuse et j'ai besoin de me pousser de temps en temps à faire de l'arithmétique mentale de base. Par conséquent, je recherche un logiciel qui me demande périodiquement de faire un court exercice d'arithmétique mentale (plus, moins, multiplier, diviser).

Critères:

  • Cela devrait me permettre de personnaliser l'intervalle de temps
  • Il doit s'intégrer dans le bureau Ubuntu, c'est-à-dire être caché en arrière-plan et apparaître uniquement (pop-up) pendant le temps d'exercice
orschiro
la source
2
Je doute qu'un tel logiciel existe, mais pourrait être très facilement créé avec un script shell ou python. Je cuisinerai quelque chose demain, rappelez-moi s'il vous plaît
Sergiy Kolodyazhnyy
Oui, bsdgames a de l'arithmétique et autres, mais vous devez automatiser vous-même les popups périodiques.
mchid
Cher @Serg, je vous rappelle gentiment votre expérience culinaire. :)
orschiro
1
J'ai donc publié une réponse en cours, que je modifierai au fur et à mesure. Veuillez jeter un coup d'œil, faites-moi savoir ce que vous pensez, quelles fonctionnalités ajouter ou supprimer. Jusqu'à présent, il s'agit d'une application console, mais elle finira par se transformer en une petite fenêtre contextuelle.
Sergiy Kolodyazhnyy
2
Il s'avère que c'est une bonne question sur laquelle travailler!
Jacob Vlijm

Réponses:

8

1. Version simple

Le script ci-dessous produira des affectations au hasard, + , - , × et ÷ . Vous pouvez (et devez) définir un nombre maximum que le script peut utiliser, ainsi que l'intervalle de temps entre les affectations.

Les missions

Les affectations sont présentées dans une fenêtre de saisie Zenity:

entrez la description de l'image ici

si la réponse est fausse:

entrez la description de l'image ici

Si la réponse est correcte:

entrez la description de l'image ici

Le scénario

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

Comment utiliser

  1. Copiez le script dans un fichier vide, enregistrez-le sous mindpractice.py
  2. Exécutez-le avec le nombre maximal autorisé et l'intervalle de temps (en secondes) entre les affectations en tant qu'arguments:

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

    par exemple

    python3 /path/to/mindpractice.py 1000 300

    faire des calculs jusqu'aux chiffres de 1000, avec une pause de 5 minutes entre les devoirs.

  3. Si tout fonctionne bien, vous pouvez l'ajouter aux applications de démarrage de la manière habituelle, ou un lanceur à bascule peut être créé, que je pourrais ajouter plus tard :)

Remarque

  • La division pourrait nécessiter quelques explications. Vous n'aimeriez probablement pas calculer en flottants. Par conséquent, si l'affectation est une division, le script recherche les nombres par lesquels il peut être divisé et en sélectionne un (au hasard). Si le nombre (principal) s'avère être un nombre premier, l'affectation est changée en un autre type.

2. Plus d'options

Une fois que vous commencez à calculer, vous découvrirez que la division jusqu'à des chiffres de (disons) 100 est beaucoup plus facile que la multiplication de chiffres jusqu'à 100.

Avec le script ci-dessous, vous pouvez (et devriez) définir le maximum de nombres par type d'exercice (voir les instructions ci-dessous le script).

Le scénario

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

Comment utiliser

  • Configurez le script exactement comme le premier, mais exécutez-le avec les arguments (dans n'importe quel ordre, le script reliera les bons arguments au bon élément):

    • p: pause (pause entre les devoirs, en secondes))
    • s: soustraire (nombre maximum avec lequel calculer)
    • a: ajouter (nombre max)
    • m: multiplier (nombre max)
    • d: diviser (nombre max)

    Par exemple:

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

    pour montrer un exercice toutes les cinq minutes, les nombres jusqu'à 10, sauf la division jusqu'à la figure 100.


3. Emportons-nous un peu

Être capable de voir quelques statistiques

La version ci-dessous vous montre les statistiques après 10 exercices:

entrez la description de l'image ici

De plus (peut être utile lorsqu'il est utilisé pour les enfants), vous pouvez voir ce qui s'est mal passé dans les 100 derniers exercices mal répondus. Dans un fichier caché, les affectations et leurs réponses (incorrectes) sont écrites:

entrez la description de l'image ici

Ce fichier journal se trouve:

~/.calculog

Le scénario

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

Comment utiliser

L'utilisation est à peu près exactement comme l'option 2, mais vous aurez le fichier journal disponible et les scores après 10 affectations.


4. Version ultime

La version ci-dessous ressemble à l'option 3 (y compris le fichier journal et les rapports), mais possède quelques fonctionnalités supplémentaires:

  • ajoute le calcul de la racine carrée

    entrez la description de l'image ici

  • ajoute en utilisant une plage de nombres, au lieu de simplement définir un maximum

  • ajoute la possibilité d'exécuter uniquement des types de calcul spécifiques (par exemple, uniquement diviser et multiplier).
  • se souvient des arguments avec lesquels il a été exécuté la dernière fois, lorsqu'il est exécuté sans arguments (uniquement la première fois, les arguments doivent être définis). Si aucun argument n'a été défini lors de la première exécution, le script envoie un message:

    entrez la description de l'image ici

Le scénario

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

Comment utiliser

  • Copiez le script dans un fichier vide, enregistrez-le (à nouveau) sous mindpractice.py. Exécutez-le avec les options suivantes (comme exemples)

    Doit être réglé:

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

    Facultatif (faites une sélection):

    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
  • Exemple de commande:

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

    mettre en place:

    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

    tout en ajoutant et en multipliant ne sont pas utilisés.

Ensuite, la prochaine fois, si le script est exécuté avec:

python3 '/path/to/mindpractice.py'

Il se souviendra des derniers arguments utilisés


Utilisez la version qui répond le mieux à vos besoins ...


Jacob Vlijm
la source
Cette version fonctionne très bien jusqu'à présent. Merci beaucoup!
orschiro
1
@orschiro a ajouté une version étendue, pour différencier les difficultés.
Jacob Vlijm
le fichier journal est une très bonne idée! J'essaie actuellement de comprendre certaines des multiplications et divisions à trois chiffres. Ils ne sont pas si simples. :)
orschiro
juste une idée: Parfois, je suis tellement concentré sur le travail que j'ignore la Think Hardfenêtre pour terminer le travail avant (par exemple, finir d'écrire une phrase). J'oublie alors la fenêtre. Serait-il possible qu'après 5 minutes, la Think Hardfenêtre retrouve automatiquement le focus?
orschiro
1
@orschiro absolument! Je mâchais également une version entièrement graphique (pas besoin de définir quoi que ce soit à partir de la ligne de commande, pas même la première manche), mais je ne suis pas sûr qu'ils nous permettront d'ajouter plus de mètres à la réponse :)
Jacob Vlijm
3

Introduction:

L'application suivante produit des expressions entières aléatoires à évaluer par l'utilisateur. La plage d'expressions générées de manière aléatoire dépend des paramètres de l'utilisateur dans la fenêtre contextuelle principale. En cliquant sur le Lets Beginbouton, la session démarre indéfiniment, jusqu'à ce que l'utilisateur clique sur le bouton Annuler.

entrez la description de l'image ici

entrez la description de l'image ici

Code source:

#!/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
la source
Cher @Serg, je tiens également à vous remercier personnellement pour votre version GUI étendue. Une question, je viens de faire l'exercice 15/14 = 1. Je ne sais pas à quel point un tel exercice est utile. Qu'est-ce que tu penses?
orschiro
@orschiro c'est integer arithmetic. Cela signifie que le résultat n'est qu'une partie entière, pas de reste. Si vous le souhaitez, je pourrais également essayer d'implémenter l' decimalarithmétique. Aussi, faites-moi savoir quel type d'autres options aimeriez-vous que j'implémente et ajoute. Actuellement, j'essaie de pratiquer la agile developmentméthode, et la communication avec le client est la clé d'une telle méthode. S'il vous plaît, faites-moi savoir.
Sergiy Kolodyazhnyy
c'est bon à entendre! Je serais ravi de vous fournir plus de commentaires, par exemple une meilleure intégration dans Ubuntu Desktop (exécuter le script plus en arrière-plan, c'est-à-dire minimiser après la saisie de l'utilisateur). Comment puis-je mieux vous fournir d'autres commentaires?
orschiro