Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/ReckonPrimer.activity/exercises/exercise.py
blob: 37b8f5d4e650db896f44ec3a3608a43b405f3a7a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# -*- coding: utf-8 -*-
from functions import contain, collect_digits, make_line, make_input
from functions import make_line_remainder, make_input_remainder

class Exercise:
    
    EXERCISES = {}
  
    _intermediate_repetitions = 0
    _intermediate_count = 0

    _delayed_repetitions = 0
    _delayed_count = 0

    _error_list = []
    _current_calc = None
    _eval = {}
  
    """This is the base class for the individual exercises.
    An exercise is characterized by a topic. A topic determines the 
    fields of the settings self._sett and public methods of Exercise.
    The values of self._sett may vary between exercises within 1 topic.
    """
    def __init__(self):
        """ An Exercise stores data on evaluation, i.e date, duration TODO.
        The preliminary format deals with errors only and is
        [(None, errors), (settings, errors)], where None indicates, 
        that the settings are not changed by the Learner,
        and settings indicates updates done by the Learner.
        The list allows to append the current errors to the previous ones,
        and even to do an Exercise subsequently several times;
        thus the most recent errors are at the end of the list. """
        #self._eval = {} this statement does nothing
        """ The settings determine the generation of calculations.
        The fields of the settings are determined by self._sett['topic'];
        the values of the settings are different for different Exercises.
        self._sett['calclines'] determines the # of lines in a calculation."""
        self._sett = None
        """ Calculations are generated according to the settings. """
        self._calcs = None
        """ An Exercise needs the Display for updating the settings"""
        self._display = None

    def get_setting(self):
        return self._sett
        
    def update_setting(self, sett):
        """ Update the settings and generate calculations accordingly. """
        self._sett = sett
        self._calcs = self._generate_calcs()

    def get_calcs(self):
        """ Newly generate all calculations according to current settings
        and return all calculations. """
        self._calcs = self._generate_calcs()
        return self._calcs

    def get_next_calc(self):
        """ Get the next calculation from the Exercise.
        TODO.WN091123: handle exception after last exercise. """
        if self.count() == 0 and self._delayed_count > 0:
            self._delayed_count = self._delayed_count - 1
            self._calcs.extend(self._error_list)
            self._error_list = []
        self._current_calc = (self._calcs).pop()
        return self._current_calc
    
    def count(self):
        """ Return the number of calculations generated by
        the current settings """
        return len(self._calcs)

    def handle_calculation_error(self):
        if self._intermediate_count == self._intermediate_repetitions:
            self._error_list.insert(0, self._current_calc)
            try: self._eval[str(self._sett)].append(self._current_calc)
            except Exception: self._eval[str(self._sett)] = self._current_calc
        if self._intermediate_count > 0:
            self._intermediate_count = self._intermediate_count - 1
            self._calcs.append(self._current_calc)
        else:
            self._intermediate_count = self._intermediate_repetitions

    def reset_evaluation_data(self):
        self._eval = {}

    def get_evaluation_data(self):
        return self._eval

    def set_num_intermediate_repetitions(self, num_repetitions):
        self._intermediate_repetitions = num_repetitions
        self._intermediate_count = num_repetitions


    def set_num_delayed_repetitions(self, num_repetitions):
        self._delayed_repetitions = num_repetitions
        self._delayed_count = num_repetitions

    #END CHANGE

    #===== methods of subclasses different for topic-specific settings
    def format(self, calc):
        """ Prepare the representation of a calculation for Display.
        This method is public for eventual use on calculations
        coming through the net (TODO cooperative games, etc)"""
        pass

    def _generate_calcs(self):
        """ Generate calculations according to topic-specific settings.
        Called on each call of update_setting"""
        pass

    def define_buttons(self):
        """ Define buttons for update settings including callbacks.
        The widgets are local to exerc-instances and attached to the display:
        #   self.butt.connect('toggled',self.butt_callback)
        #   self._display.settings_table.attach(self.butt, 1,2,3,4)
        And the callbacks run locally, but read and write in the display:
        # def butt_callback(self, widget)
        #   if widget.get_active():
        #     self._display._sett['+'] = True
        """
        pass

    def set_buttons(self, sett):
        """ Display buttons according to the current setting sett. """
        pass

    #===== methods is used by more than one subclass
    def format_addsub_simp(self, (calc, linepos)):
        """ Prepare the representation of a calculation for Display
        on 1 line. Used within several subclasses. """
        #@print('in Display.format_addsub_simp: calc=', (calc, linepos))#@
        _ccs = collect_digits(calc)
        #print('in Exercise.format_addsub_simp: _ccs=',_ccs )
        _l0 = make_line(_ccs, linepos)
        _ip = make_input(_ccs, linepos)
        #@print('in Display.format_addsub_simp: return=', ([_l0], _ip)) #@
        return ([_l0], _ip)
#return ([[' ', '1', '0', ' ', '-', ' ', '7', ' ', '=', ' ', '_', ' ']], [(0, 10, '3', ' 10 - 7 = _ ', ' 10 - 7 = 3 ', [' ', '1', '0', ' ', '-', ' ', '7', ' ', '=', ' ', '3', ' '])])

#BEGIN LPCHANGE

    def get_settings_string(self):
        """
        This method returns the settings of the exercise as string.
        \return The settings-string.
        """ 
        return str(self._sett)           

#END LPCHANGE