~kevang/mnemosyne-proj/grade-shortcuts-improvements

« back to all changes in this revision

Viewing changes to mnemosyne/mnemosyne/libmnemosyne/card.py

  • Committer: Peter Bienstman
  • Date: 2008-08-01 18:33:05 UTC
  • Revision ID: peter.bienstman@ugent.be-20080801183305-vadbiuurs4t86egc
Work on card (in progress).

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
#
5
5
##############################################################################
6
6
 
7
 
import md5, time, logging
8
 
 
9
 
from mnemosyne.libmnemosyne.plugin_manager import *
10
 
from mnemosyne.libmnemosyne.config import config
11
 
#from mnemosyne.libmnemosyne.card_type import *
12
 
from mnemosyne.libmnemosyne.start_date import start_date
13
 
#from mnemosyne.libmnemosyne.scheduler import *
14
 
#from mnemosyne.libmnemosyne.database import *
15
 
 
16
 
log = logging.getLogger("mnemosyne")
17
 
 
 
7
import md5, time
 
8
 
 
9
from mnemosyne.libmnemosyne.plugin_manager import get_database, get_scheduler
18
10
 
19
11
 
20
12
 
22
14
#
23
15
# Card
24
16
#
25
 
# We store q and a in strings to cache them, instead of regenerating them
26
 
# each time from its Fact. This could take too much time, e.g. on a mobile
27
 
# platform. Also useful for searching in an SQL database.
28
 
#
29
17
# Note that we store a card_type_id, as opposed to a card_type, because
30
18
# otherwise we can't use pickled databases, as the card_types themselves are
31
19
# not stored in the database. It is also closer the SQL implementation.
34
22
# like reverse cards. TODO: do we need a mapping from this integer to a
35
23
# description?
36
24
#
37
 
# If the user deletes a subcard from a fact, we don't delete it, in case
38
 
# the user later reactivates it. We can either employ a 'hidden'
39
 
# variable here, or move it to a different container (perhaps more
40
 
# efficient?). TODO: implement and benchmark
 
25
# For UI simplicity reasons, the user is not allowed to deleted one of a set
 
26
# of related cards, only to deactivate them. This is a second, orthogonal
 
27
# selection mechanism to see if cards are active, together with not being
 
28
# in a deactivated category.
41
29
#
42
30
##############################################################################
43
31
 
51
39
            
52
40
    def __init__(self, grade, card_type, fact, fact_view, cat_names, id=None):
53
41
 
54
 
        db = get_database()
55
 
        sch = get_scheduler()
56
 
 
57
42
        self.card_type_id = card_type.id
58
43
        self.fact         = fact
59
44
        self.fact_view    = fact_view
60
 
        self.q            = self.filtered_q()
61
 
        self.a            = self.filtered_a()
62
 
        self.hidden       = False
 
45
        self.active       = True
 
46
 
 
47
        db = get_database()
63
48
 
64
49
        self.cat = []
65
50
        for cat_name in cat_names:
77
62
 
78
63
        self.easiness = db.average_easiness()
79
64
 
80
 
        if id == None:
 
65
        if id is not None:
81
66
            self.new_id()
82
67
        else:
83
 
            self.id = id 
 
68
            self.id = id
84
69
 
 
70
        sch = get_scheduler()
 
71
        
85
72
        new_interval  = sch.calculate_initial_interval(grade)
86
73
        new_interval += sch.calculate_interval_noise(new_interval)
87
74
        self.next_rep = start_date.days_since_start() + new_interval
90
77
 
91
78
    ##########################################################################
92
79
    #
93
 
    # filtered_q
 
80
    # question
94
81
    #
95
82
    ##########################################################################
96
83
 
97
 
    def filtered_q(self):
 
84
    def question(self):
98
85
 
99
86
        card_type = get_card_type_by_id(self.card_type_id)
100
87
 
104
91
 
105
92
        return q
106
93
 
 
94
 
 
95
 
107
96
    ##########################################################################
108
97
    #
109
 
    # filtered_a
 
98
    # answer
110
99
    #
111
100
    ##########################################################################
112
101
    
113
 
    def filtered_a(self):
 
102
    def answer(self):
114
103
        
115
104
        card_type = get_card_type_by_id(self.card_type_id)
116
105
        
138
127
        self.acq_reps_since_lapse = 0
139
128
        self.ret_reps_since_lapse = 0
140
129
 
141
 
        # TODO: store as float for minute level scheduling
 
130
        # TODO: store as float for minute level scheduling.
142
131
        
143
132
        self.last_rep  = 0 # In days since beginning.
144
133
        self.next_rep  = 0 #
145
134
 
146
 
        
147
 
    ##########################################################################
148
 
    #
149
 
    # save
150
 
    #
151
 
    ##########################################################################
152
 
    
153
 
    def save(self):
154
 
 
155
 
        get_database().add_card(self)
156
 
        
157
 
        new_interval = start_date.days_since_start() - self.next_rep
158
 
 
159
 
        log.info("New card %s %d %d", self.id, self.grade, new_interval)
160
 
 
161
 
        print 'new card', self.q, self.a
162
 
 
163
135
 
164
136
        
165
137
    ##########################################################################
208
180
 
209
181
    ##########################################################################
210
182
    #
211
 
    # is_in_active_category
 
183
    # is_active
212
184
    #
213
185
    ##########################################################################
214
186
 
215
 
    def is_in_active_category(self):
 
187
    def is_active(self):
 
188
 
 
189
        if self.active == False:
 
190
            return False
216
191
        
217
192
        for c in self.cat:
218
193
            if c.active == False: