Gibt es eine Software, mit der ich regelmäßig mentale Rechenübungen machen kann?


9

Ich bin mir meiner Faulheit bewusst und muss mich von Zeit zu Zeit dazu drängen, eine grundlegende mentale Arithmetik durchzuführen. Daher suche ich nach einer Software, die mich regelmäßig auffordert, eine kurze mentale Rechenübung durchzuführen (Plus, Minus, Multiplizieren, Teilen).

Kriterien:

  • Es sollte mir ermöglichen, die Intervallzeit anzupassen
  • Es sollte in den Ubuntu Desktop integriert sein, dh im Hintergrund versteckt sein und nur während der Trainingszeit angezeigt werden (Popup)

2
Ich bezweifle, dass solche Software existiert, aber sie könnte sehr einfach mit einer Shell oder einem Python-Skript erstellt werden. Ich werde morgen etwas kochen, bitte erinnere mich
Sergiy Kolodyazhnyy

Ja, bsdgames hat Arithmetik und so, aber Sie müssten die periodischen Popups selbst automatisieren.
Mchid

Lieber @Serg, ich erinnere Sie freundlich an Ihr Kochexperiment. :)
Orschiro

1
Daher habe ich eine laufende Antwort veröffentlicht, die ich im Laufe der Zeit bearbeiten werde. Bitte werfen Sie einen Blick darauf, lassen Sie mich wissen, was Sie denken, welche Funktionen hinzugefügt oder entfernt werden müssen. Bisher ist dies eine Konsolen-App, die sich jedoch irgendwann in ein kleines Popup-Fenster verwandeln wird.
Sergiy Kolodyazhnyy

2
Es stellt sich heraus, dass es eine schöne Frage ist, an der man arbeiten kann!
Jacob Vlijm

Antworten:


8

1. Einfache Version

Das folgende Skript erzeugt zufällige Zuweisungen, + , - , × und ÷ . Sie können (und sollten) eine maximale Anzahl festlegen, die das Skript verwenden darf, sowie das Zeitintervall zwischen den Zuweisungen.

Die Aufgaben

Die Aufgaben werden in einem Zenity-Eingabefenster angezeigt:

Geben Sie hier die Bildbeschreibung ein

wenn die Antwort falsch ist:

Geben Sie hier die Bildbeschreibung ein

Wenn die Antwort richtig ist:

Geben Sie hier die Bildbeschreibung ein

Das Skript

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

Wie benutzt man

  1. Kopieren Sie das Skript in eine leere Datei und speichern Sie es unter mindpractice.py
  2. Führen Sie es mit der maximal zulässigen Anzahl und der Intervallzeit (in Sekunden) zwischen den Zuweisungen als Argumente aus:

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

    z.B

    python3 /path/to/mindpractice.py 1000 300

    Berechnungen bis zu Zahlen von 1000, mit einer Pause von 5 Minuten zwischen den Aufgaben.

  3. Wenn alles gut funktioniert, können Sie es wie gewohnt zu Startanwendungen hinzufügen, oder es kann ein Starter zum Umschalten erstellt werden, den ich später hinzufügen könnte :)

Hinweis

  • Die Aufteilung bedarf möglicherweise einer Erklärung. Sie möchten wahrscheinlich nicht in Floats rechnen. Wenn es sich bei der Zuweisung um eine Division handelt, sucht das Skript nach den Zahlen, durch die es geteilt werden kann, und wählt eine (zufällig) aus. Wenn sich herausstellt, dass die (Haupt-) Nummer eine Primzahl ist, wird die Zuordnung in einen anderen Typ geändert.

2. Weitere Optionen

Sobald Sie mit der Berechnung beginnen, werden Sie feststellen, dass das Aufteilen auf Zahlen von (sagen wir) 100 viel einfacher ist als das Multiplizieren von Zahlen auf 100.

Mit dem folgenden Skript können (und sollten) Sie das Maximum der Zahlen pro Übungstyp festlegen (siehe Anweisungen unter dem Skript).

Das Skript

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

Wie benutzt man

  • Richten Sie das Skript genau wie das erste ein, führen Sie es jedoch mit den Argumenten aus (in beliebiger Reihenfolge verknüpft das Skript die richtigen Argumente mit dem richtigen Element):

    • p: Pause (Pause zwischen den Aufgaben, in Sekunden))
    • s: subtrahieren (maximale Anzahl, mit der berechnet werden soll)
    • a: add (maximale Anzahl)
    • m: multiplizieren (maximale Anzahl)
    • d: teilen (maximale Anzahl)

    Zum Beispiel:

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

    alle fünf Minuten eine Übung zeigen, Zahlen bis zu 10, außer bis zu 100 teilen.


3. Lassen Sie uns ein bisschen mitreißen

In der Lage sein, einige Statistiken zu sehen

Die folgende Version zeigt Ihnen die Statistiken nach jeweils 10 Übungen:

Geben Sie hier die Bildbeschreibung ein

Zusätzlich (kann nützlich sein, wenn es für Kinder verwendet wird) können Sie sehen, was in den letzten 100 falsch beantworteten Übungen schief gelaufen ist. In einer versteckten Datei werden sowohl die Zuweisungen als auch ihre (falschen) Antworten geschrieben:

Geben Sie hier die Bildbeschreibung ein

Diese Protokolldatei befindet sich:

~/.calculog

Das Skript

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

Wie benutzt man

Die Verwendung ist ziemlich genau wie bei Option 2, aber Sie haben die Protokolldatei und die Ergebnisse nach jeweils 10 Aufgaben zur Verfügung.


4. Ultimative Version

Die folgende Version entspricht Option 3 (einschließlich Protokolldatei und Berichten), bietet jedoch einige zusätzliche Funktionen:

  • fügt die berechnende Quadratwurzel hinzu

    Geben Sie hier die Bildbeschreibung ein

  • fügt eine Verwendung Bereich von Zahlen, sondern maximal einfach eingestellt

  • fügt die Option hinzu, nur bestimmte Berechnungstypen auszuführen (z. B. nur dividieren und multiplizieren).
  • Erinnert sich an die Argumente, die beim letzten Mal ausgeführt wurden, wenn sie ohne Argumente ausgeführt wurden (nur beim ersten Mal müssen Argumente festgelegt werden). Wenn beim ersten Ausführen keine Argumente festgelegt wurden, sendet das Skript eine Nachricht:

    Geben Sie hier die Bildbeschreibung ein

Das Skript

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

Wie benutzt man

  • Kopieren Sie das Skript in eine leere Datei und speichern Sie es (erneut) unter mindpractice.py. Führen Sie es mit den folgenden Optionen aus (als Beispiele)

    Muss eingestellt werden:

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

    Optional (Auswahl treffen):

    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
    
  • Beispielbefehl:

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

    zu setzen:

    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
    

    beim Addieren und Multiplizieren werden nicht verwendet.

Wenn das Skript dann das nächste Mal ausgeführt wird mit:

python3 '/path/to/mindpractice.py'

Es werden die zuletzt verwendeten Argumente gespeichert


Verwenden Sie die Version, die Ihren Anforderungen am besten entspricht ...



Diese Version funktioniert bisher hervorragend. Ich danke dir sehr!
Orschiro

1
@orschiro hat eine erweiterte Version hinzugefügt, um die Schwierigkeit zu unterscheiden.
Jacob Vlijm

Die Protokolldatei ist eine sehr schöne Idee! Ich versuche gerade, mich mit einigen der dreistelligen Multiplikationen und Divisionen auseinanderzusetzen. Sie sind nicht so einfach. :)
Orschiro

Nur eine Idee: Manchmal konzentriere ich mich so auf die Arbeit, dass ich das Think HardFenster ignoriere , um die Arbeit vorher zu beenden (z. B. einen Satz fertig zu schreiben). Ich vergesse dann das Fenster. Wäre es möglich, dass das Think HardFenster nach 5 Minuten automatisch wieder scharf wird?
Orschiro

1
@orschiro absolut! Ich habe auch noch an einer vollständig GUI-Version gekaut (es ist nicht erforderlich, irgendetwas über die Befehlszeile festzulegen , nicht einmal beim ersten Durchlauf), aber ich bin nicht sicher, ob wir der Antwort weitere Meter hinzufügen können :)
Jacob Vlijm

3

Einführung:

Die folgende Anwendung erzeugt zufällige ganzzahlige Ausdrücke, die vom Benutzer ausgewertet werden. Der Bereich zufällig generierter Ausdrücke hängt von den Benutzereinstellungen im Hauptfenster ab. Wenn Sie auf die Lets BeginSchaltfläche klicken , wird die Sitzung auf unbestimmte Zeit gestartet, bis der Benutzer auf die Schaltfläche Abbrechen klickt .

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Quellcode:

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

Lieber @Serg, ich möchte mich auch persönlich bei Ihnen für Ihre erweiterte GUI-Version bedanken. Eine Frage, ich hatte gerade die Übung 15/14 = 1. Ich bin mir nicht sicher, wie nützlich eine solche Übung ist. Was denken Sie?
Orschiro

@orschiro das ist integer arithmetic. Das heißt, das Ergebnis ist nur ein ganzer Teil, kein Rest. Wenn Sie möchten, könnte ich auch versuchen, decimalArithmetik zu implementieren . Bitte lassen Sie mich auch wissen, welche anderen Optionen ich implementieren und hinzufügen soll. Derzeit versuche ich, die agile developmentMethode zu üben , und die Kommunikation mit dem Kunden ist der Schlüssel für eine solche Methode. Lass es mich wissen, bitte.
Sergiy Kolodyazhnyy

Das ist schön zu hören! Ich würde Ihnen gerne mehr Feedback geben, z. B. eine bessere Integration in Ubuntu Desktop (Skript mehr im Hintergrund ausführen, dh nach Benutzereingabe minimieren). Wie kann ich Ihnen am besten weiteres Feedback geben?
Orschiro
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.