Don't like ads? PRO users don't see any ads ;-)

Ein Mal Eins Lernscript 1.0.0.2

By: Linux-Fan on Jun 2nd, 2012  |  syntax: Python  |  size: 6.21 KB  |  hits: 22  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #!/usr/bin/python
  2. #
  3. #-----------------------------------------------------------------------
  4. # Ma_Sys.ma EinMalEins 1.0.0.2, Copyright (c) 2012 Ma_Sys.ma.
  5. # For further info send an e-mail to Ma_Sys.ma@web.de.
  6. # Or visit http://masysma.ohost.de/ alternatively.
  7. #
  8. # This program is free software: you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation, either version 3 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License
  19. # along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20. #-----------------------------------------------------------------------
  21. #
  22.  
  23. import gtk
  24. import gtk.gdk
  25. import pango
  26. import random
  27. import sys
  28. import threading
  29. import time
  30.  
  31. STATUS_NORMAL = 1
  32. STATUS_ERROR = 2
  33. STATUS_INCORRECT = 3
  34.  
  35. class MaSysMaEinMalEinsBackgroundMode(threading.Thread):
  36.  
  37.         SLEEP_TIME = 60 * 2 # Seconds between questions
  38.         CHECK_INTERVAL = 10 # Seconds between terminate checks (this does not seem to be a good solution)
  39.  
  40.         def __init__(self,main):
  41.                 threading.Thread.__init__(self)
  42.                 self.main = main
  43.                 self.terminated = False
  44.  
  45.         def term(self):
  46.                 self.terminated = True
  47.  
  48.         def run(self):
  49.                 time_passed = 0
  50.                 while not self.terminated:
  51.                         if time_passed >= self.SLEEP_TIME:
  52.                                 gtk.gdk.threads_enter()
  53.                                 self.main.show()
  54.                                 gtk.gdk.threads_leave()
  55.                                 time_passed = 0
  56.                         time.sleep(self.CHECK_INTERVAL)
  57.                         time_passed += self.CHECK_INTERVAL
  58.  
  59. class MaSysMaEinMalEinsExercise:
  60.  
  61.         LIMIT_LOWER = 3
  62.         LIMIT_UPPER = 10 # Should be enlarged to 20
  63.         PROBABILITY_OF_DIVISION = 0.5
  64.  
  65.         def __init__(self):
  66.                 self.initialize()
  67.  
  68.         def initialize(self, reinitialize_list = True):
  69.                 if reinitialize_list:
  70.                         self.exercises = []
  71.                 for i in range(self.LIMIT_LOWER, self.LIMIT_UPPER):
  72.                         for j in range(self.LIMIT_LOWER, self.LIMIT_UPPER):
  73.                                 self.exercises.append((i, j, i * j))
  74.         def exercise(self, gui):
  75.                 if gui.is_background_mode:
  76.                         gui.hide()
  77.                 factor_1, factor_2, result = self.select_random_element()
  78.                 if self.do_division():
  79.                         self.calculate_formula(result, "/", self.divide_by(factor_1, factor_2))
  80.                 else:
  81.                         self.calculate_formula(factor_1, "*", factor_2)
  82.                 gui.set_text(self.formula + "?")
  83.  
  84.         def select_random_element(self):
  85.                 exercise = self.exercises.pop(random.randint(0, len(self.exercises) - 1))
  86.                 if len(self.exercises) == 0:
  87.                         self.initialize(False)
  88.                 return exercise
  89.  
  90.         def do_division(self):
  91.                 if random.random() < self.PROBABILITY_OF_DIVISION:
  92.                         return True
  93.                 else:
  94.                         return False
  95.  
  96.         def calculate_formula(self, number_1, symbol, number_2):
  97.                 self.calculate_result(number_1, symbol, number_2)
  98.                 self.formula = str(number_1) + " " + symbol + " " + str(number_2) + " = "
  99.  
  100.         def calculate_result(self, number_1, symbol, number_2):
  101.                 if symbol == "*":
  102.                         self.result = number_1 * number_2
  103.                 elif symbol == "/":
  104.                         self.result = number_1 / number_2
  105.                 else:
  106.                         self.result = -1
  107.  
  108.         def divide_by(self, factor_1, factor_2):
  109.                 if random.random() < 0.5:
  110.                         return factor_1
  111.                 else:
  112.                         return factor_2
  113.  
  114.         def check(self, gui):
  115.                 """Returns: True: Next exercise; False: Keep exercise."""
  116.                 if not gui.get_text() == "":
  117.                         try:
  118.                                 parsed_input = int(gui.get_text())
  119.                                 if parsed_input == self.result:
  120.                                         return True
  121.                         except:
  122.                                 gui.set_status(STATUS_ERROR)
  123.                                 gui.set_text("Invalid Input!")
  124.                                 return False
  125.  
  126.                 gui.set_status(STATUS_INCORRECT)
  127.                 gui.set_text(self.formula + str(self.result))
  128.                 return False
  129.  
  130. class MaSysMaEinMalEins(gtk.Window):
  131.  
  132.         def __init__(self):
  133.                 gtk.gdk.threads_init()
  134.                 self.layout()
  135.                 self.initialize_data()
  136.                 self.background_mode_check()
  137.                 self.exercise.exercise(self)
  138.                 self.initialize_frame_data_post()
  139.                 gtk.gdk.threads_enter()
  140.                 gtk.main()
  141.                 gtk.gdk.threads_leave()
  142.  
  143.         def layout(self):
  144.                 gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
  145.                 self.set_title("Ma_Sys.ma EinMalEins")
  146.                 self.connect("destroy", self.destroy)
  147.                 self.set_border_width(5)
  148.                 self.description = gtk.Label("No exercise yet.")
  149.                 # http://faq.pygtk.org/index.py?req=show&file=faq04.001.htp
  150.                 self.description.modify_font(pango.FontDescription("sans 22"))
  151.                 self.result_input = gtk.Entry()
  152.                 self.result_input.connect("key_press_event", self.key_event)
  153.                 layout = gtk.VBox()
  154.                 layout.add(self.description)
  155.                 layout.add(self.result_input)
  156.                 self.add(layout)
  157.  
  158.         def initialize_data(self):
  159.                 self.status = STATUS_NORMAL
  160.                 self.exercise = MaSysMaEinMalEinsExercise()
  161.  
  162.         def background_mode_check(self):
  163.                 if len(sys.argv) == 2 and sys.argv[1] == "-b":
  164.                         self.is_background_mode = True
  165.                         self.background_mode = MaSysMaEinMalEinsBackgroundMode(self)
  166.                         self.background_mode.start()
  167.                 else:
  168.                         self.is_background_mode = False
  169.  
  170.         def initialize_frame_data_post(self):
  171.                 self.resize(300, 200)
  172.                 self.set_gravity(gtk.gdk.GRAVITY_CENTER)
  173.                 self.show_all()
  174.  
  175.         def key_event(self, widget, event):
  176.                 key = gtk.gdk.keyval_name(event.keyval)
  177.                 if key == "Return":
  178.                         self.user_accepted()
  179.                         self.result_input.set_text("")
  180.                 elif key == "q":
  181.                         self.destroy()
  182.                 else:
  183.                         return (not event.string.isdigit()) and event.string.isalnum()
  184.                 return False
  185.  
  186.         def user_accepted(self):
  187.                 if self.status == STATUS_NORMAL:
  188.                         if self.exercise.check(self):
  189.                                 self.exercise.exercise(self)
  190.                         return # Important: We do not want to reset status as it might have been changed while checking
  191.                 elif self.status == STATUS_ERROR:
  192.                         self.description.set_text(self.exercise.formula)
  193.                 elif self.status == STATUS_INCORRECT:
  194.                         self.exercise.exercise(self)
  195.  
  196.                 self.status = STATUS_NORMAL
  197.  
  198.         def destroy(self, widget = None, data = None):
  199.                 if self.is_background_mode:
  200.                         self.background_mode.term()
  201.                 gtk.main_quit()
  202.  
  203.         def set_text(self, text):
  204.                 self.description.set_text(text)
  205.  
  206.         def get_text(self):
  207.                 return self.result_input.get_text()
  208.  
  209.         def set_status(self, status):
  210.                 self.status = status
  211.  
  212.         def get_status(self):
  213.                 return self.status
  214.  
  215. if __name__ == '__main__':
  216.         MaSysMaEinMalEins()