Esiste un software che mi consente periodicamente di fare esercizi di aritmetica mentale?


9

Sono consapevole della mia natura pigra e di tanto in tanto ho bisogno di spingermi a fare qualche aritmetica mentale di base. Pertanto, sto cercando un software che periodicamente mi chieda di fare un breve esercizio di aritmetica mentale (più, meno, moltiplica, dividi).

criteri:

  • Dovrebbe permettermi di personalizzare l'intervallo di tempo
  • Dovrebbe integrarsi nel desktop di Ubuntu, cioè essere nascosto in background e apparire (pop-up) solo durante il tempo di allenamento

2
Dubito che tale software esista, ma potrebbe essere facilmente creato con uno script shell o python. Io cucino qualcosa di domani, per favore mi ricordano
Sergiy Kolodyazhnyy

Sì, bsdgames ha un'aritmetica e simili, ma dovresti automatizzare i popup periodici da solo.
mchid

Caro @Serg, ti ricordo gentilmente del tuo esperimento di cucina. :)
Orschiro,

1
Quindi ho pubblicato una risposta in corso, che modificherò man mano che procederò. Dai un'occhiata, fammi sapere cosa ne pensi, quali funzionalità aggiungere o rimuovere. Finora si tratta di un'app console, ma alla fine si trasformerà in una piccola finestra popup.
Sergiy Kolodyazhnyy,

2
Risulta essere una bella domanda su cui lavorare!
Jacob Vlijm,

Risposte:


8

1. Versione semplice

Lo script seguente produrrà compiti a caso, + , - , × e ÷ . Puoi (e dovresti) impostare un numero massimo che lo script può usare, così come l'intervallo di tempo tra le assegnazioni.

I compiti

I compiti sono presentati in una finestra di entrata Zenity:

inserisci qui la descrizione dell'immagine

se la risposta è sbagliata:

inserisci qui la descrizione dell'immagine

Se la risposta è corretta:

inserisci qui la descrizione dell'immagine

Il copione

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

Come usare

  1. Copia lo script in un file vuoto, salvalo come mindpractice.py
  2. Eseguilo con il numero massimo consentito e l'intervallo di tempo (in secondi) tra le assegnazioni come argomenti:

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

    per esempio

    python3 /path/to/mindpractice.py 1000 300

    fare calcoli fino a cifre di 1000, con una pausa di 5 minuti tra i compiti.

  3. Se tutto funziona bene, puoi aggiungerlo alle applicazioni di avvio nel solito modo, oppure è possibile creare un launcher per attivare, che potrei aggiungere in seguito :)

Nota

  • La divisione potrebbe aver bisogno di qualche spiegazione. Probabilmente non ti piacerebbe calcolare in float. Pertanto, se l'assegnazione è una divisione, lo script cerca i numeri per i quali può essere diviso e ne seleziona uno (a caso). Se il numero (principale) risulta essere un numero primo, l'assegnazione viene modificata in un altro tipo.

2. Altre opzioni

Una volta che inizi a calcolare, scoprirai che dividere per cifre di (diciamo) 100 è molto più facile che moltiplicare cifre fino a 100.

Con lo script qui sotto puoi (e dovresti) impostare il numero massimo di numeri per tipo di esercizio (vedi istruzioni sotto lo script).

Il copione

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

Come usare

  • Imposta lo script esattamente come il primo, ma eseguilo con gli argomenti (in qualsiasi ordine, lo script collegherà gli argomenti giusti all'elemento giusto):

    • p: pausa (pausa tra i compiti, in secondi))
    • s: sottrai (numero massimo con cui calcolare)
    • a: aggiungi (numero massimo)
    • m: moltiplicare (numero massimo)
    • d: dividere (numero massimo)

    Per esempio:

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

    per mostrare un esercizio ogni cinque minuti, numeri fino a 10, tranne per la divisione fino a 100.


3. Lasciamoci trasportare un po '

Essere in grado di vedere alcune statistiche

La versione seguente mostra le statistiche ogni 10 esercizi:

inserisci qui la descrizione dell'immagine

Inoltre (potrebbe essere utile quando usato per i bambini), puoi vedere cosa è andato storto negli ultimi 100 esercizi con risposta errata. In un file nascosto vengono scritti sia i compiti che le risposte (errate):

inserisci qui la descrizione dell'immagine

Questo file di registro si trova:

~/.calculog

Il copione

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

Come usare

L'utilizzo è praticamente identico all'opzione 2, ma avrai il file di registro disponibile e i punteggi dopo ogni 10 assegnazioni.


4. Versione definitiva

La versione seguente è come l'opzione 3 (inclusi file di registro e report), ma ha alcune funzionalità aggiuntive:

  • aggiunge il calcolo della radice quadrata

    inserisci qui la descrizione dell'immagine

  • aggiunge utilizzando un intervallo di numeri, anziché semplicemente impostare un massimo

  • aggiunge l'opzione per eseguire solo tipi di calcolo specifici (ad esempio solo dividere e moltiplicare).
  • ricorda gli argomenti con cui è stata eseguita l'ultima volta, quando eseguito senza argomenti (solo la prima volta, è necessario impostare gli argomenti ). Se non sono stati impostati argomenti alla prima esecuzione, lo script invia un messaggio:

    inserisci qui la descrizione dell'immagine

Il copione

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

Come usare

  • Copia lo script in un file vuoto, salvalo (di nuovo) come mindpractice.py. Eseguilo con le seguenti opzioni (come esempi)

    Deve essere impostato:

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

    Opzionale (effettuare una selezione):

    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
  • Esempio di comando:

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

    impostare:

    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

    mentre l' aggiunta e la moltiplicazione non vengono utilizzate.

Quindi la volta successiva, se lo script viene eseguito con:

python3 '/path/to/mindpractice.py'

Ricorderà gli ultimi argomenti usati


Usa la versione più adatta alle tue esigenze ...



Questa versione funziona alla grande finora. Grazie mille!
Orschiro,

1
@orschiro ha aggiunto una versione estesa, per differenziare le difficoltà.
Jacob Vlijm,

il file di registro è un'ottima idea! Attualmente sto cercando di aggirare alcune delle moltiplicazioni e divisioni a tre cifre. Non sono così semplici. :)
Orschiro,

solo un'idea: a volte sono così concentrato sul lavoro che ignoro la Think Hardfinestra per finire il lavoro prima (es. finire di scrivere una frase). Poi mi dimentico della finestra. Sarebbe possibile che dopo 5 minuti la Think Hardfinestra riacquisti automaticamente la messa a fuoco?
Orschiro,

1
@orschiro assolutamente! Stavo ancora masticando una versione completamente GUI (non è necessario impostare nulla dalla riga di comando, nemmeno la prima esecuzione), ma non sono sicuro che ci consentiranno di aggiungere più metri alla risposta :)
Jacob Vlijm

3

Introduzione:

La seguente applicazione produce espressioni intere casuali che devono essere valutate dall'utente. L'intervallo di espressioni generate casualmente dipende dalle impostazioni dell'utente nella finestra popup principale. Facendo clic sul Lets Beginpulsante, la sessione si avvia indefinitamente, fino a quando l'utente non preme il pulsante Annulla.

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

Codice sorgente:

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

Caro @Serg, voglio anche ringraziarti personalmente per la tua versione estesa della GUI. Una domanda, ho appena fatto l'esercizio 15/14 = 1. Non sono sicuro di quanto sia utile un tale esercizio. Cosa ne pensi?
Orschiro,

@orschiro questo è integer arithmetic. Questo significa che il risultato è solo una parte intera, nessun resto. Se vuoi, potrei provare a implementare anche l' decimalaritmetica. Inoltre, per favore fatemi sapere che tipo di altre opzioni vorreste che implementassi e aggiungessi. Attualmente, sto cercando di esercitarmi con il agile developmentmetodo e la comunicazione con il cliente è fondamentale in tale metodo. Per favore mi faccia sapere.
Sergiy Kolodyazhnyy

buono a sapersi! Mi piacerebbe fornirti più feedback, ad es. Una migliore integrazione con Ubuntu Desktop (esegui più script in background, ovvero minimizza dopo l'input dell'utente). Come posso fornire ulteriori feedback?
Orschiro,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.