source: main/waeup.kofa/trunk/src/waeup/kofa/students/studylevel.py @ 9684

Last change on this file since 9684 was 9684, checked in by Henrik Bettermann, 12 years ago

Calculate grade and weight from score and show on courseticketpage only if score attribute is set.

  • Property svn:keywords set to Id
File size: 6.9 KB
Line 
1## $Id: studylevel.py 9684 2012-11-19 11:16:54Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18"""
19Container which holds the data of a student study level
20and contains the course tickets.
21"""
22import grok
23from zope.component.interfaces import IFactory
24from zope.component import createObject
25from zope.interface import implementedBy
26from waeup.kofa.students.interfaces import (
27    IStudentStudyLevel, IStudentNavigation, ICourseTicket)
28from waeup.kofa.utils.helpers import attrs_to_fields
29from waeup.kofa.students.vocabularies import StudyLevelSource
30
31def getGradeWeightFromScore(score):
32    if score is None:
33        return (None, None)
34    if score >= 70:
35        return ('A',5)
36    if score >= 60:
37        return ('B',4)
38    if score >= 50:
39        return ('C',3)
40    if score >= 45:
41        return ('D',2)
42    if score >= 40:
43        return ('E',1)
44    return ('F',0)
45
46class StudentStudyLevel(grok.Container):
47    """This is a container for course tickets.
48    """
49    grok.implements(IStudentStudyLevel, IStudentNavigation)
50    grok.provides(IStudentStudyLevel)
51
52    def __init__(self):
53        super(StudentStudyLevel, self).__init__()
54        self.level = None
55        return
56
57    @property
58    def student(self):
59        try:
60            return self.__parent__.__parent__
61        except AttributeError:
62            return None
63
64    @property
65    def certcode(self):
66        try:
67            return self.__parent__.certificate.code
68        except AttributeError:
69            return None
70
71    @property
72    def number_of_tickets(self):
73        return len(self)
74
75    @property
76    def total_credits(self):
77        total = 0
78        for ticket in self.values():
79            total += ticket.credits
80        return total
81
82    @property
83    def is_current_level(self):
84        try:
85            return self.__parent__.current_level == self.level
86        except AttributeError:
87            return False
88
89    def writeLogMessage(self, view, message):
90        return self.__parent__.__parent__.writeLogMessage(view, message)
91
92    @property
93    def level_title(self):
94        studylevelsource = StudyLevelSource()
95        return studylevelsource.factory.getTitle(self.__parent__, self.level)
96
97    def addCourseTicket(self, ticket, course):
98        """Add a course ticket object.
99        """
100        if not ICourseTicket.providedBy(ticket):
101            raise TypeError(
102                'StudentStudyLeves contain only ICourseTicket instances')
103        ticket.code = course.code
104        ticket.title = course.title
105        ticket.fcode = course.__parent__.__parent__.__parent__.code
106        ticket.dcode = course.__parent__.__parent__.code
107        ticket.credits = course.credits
108        ticket.passmark = course.passmark
109        ticket.semester = course.semester
110        self[ticket.code] = ticket
111        return
112
113    def addCertCourseTickets(self, cert):
114        """Collect all certificate courses and create course
115        tickets automatically.
116        """
117        if cert is not None:
118            for key, val in cert.items():
119                if val.level != self.level:
120                    continue
121                ticket = createObject(u'waeup.CourseTicket')
122                ticket.automatic = True
123                ticket.mandatory = val.mandatory
124                ticket.carry_over = False
125                self.addCourseTicket(ticket, val.course)
126        return
127
128StudentStudyLevel = attrs_to_fields(StudentStudyLevel)
129
130class StudentStudyLevelFactory(grok.GlobalUtility):
131    """A factory for student study levels.
132    """
133    grok.implements(IFactory)
134    grok.name(u'waeup.StudentStudyLevel')
135    title = u"Create a new student study level.",
136    description = u"This factory instantiates new student study level instances."
137
138    def __call__(self, *args, **kw):
139        return StudentStudyLevel()
140
141    def getInterfaces(self):
142        return implementedBy(StudentStudyLevel)
143
144class CourseTicket(grok.Model):
145    """This is a course ticket which allows the
146    student to attend the course. Lecturers will enter scores and more at
147    the end of the term.
148
149    A course ticket contains a copy of the original course and
150    certificate course data. If the courses and/or the referrin certificate
151    courses are removed, the corresponding tickets remain unchanged.
152    So we do not need any event
153    triggered actions on course tickets.
154    """
155    grok.implements(ICourseTicket, IStudentNavigation)
156    grok.provides(ICourseTicket)
157
158    def __init__(self):
159        super(CourseTicket, self).__init__()
160        self.code = None
161        return
162
163    @property
164    def student(self):
165        """Get the associated student object.
166        """
167        try:
168            return self.__parent__.__parent__.__parent__
169        except AttributeError:
170            return None
171
172    @property
173    def certcode(self):
174        try:
175            return self.__parent__.__parent__.certificate.code
176        except AttributeError:
177            return None
178
179    def writeLogMessage(self, view, message):
180        return self.__parent__.__parent__.__parent__.writeLogMessage(view, message)
181
182    def getLevel(self):
183        """Returns the id of the level the ticket has been added to.
184        """
185        # XXX: shouldn't that be an attribute?
186        try:
187            return self.__parent__.level
188        except AttributeError:
189            return None
190
191    def getLevelSession(self):
192        """Returns the session of the level the ticket has been added to.
193        """
194        # XXX: shouldn't that be an attribute?
195        try:
196            return self.__parent__.level_session
197        except AttributeError:
198            return None
199
200    @property
201    def grade(self):
202        """Returns the grade calculated from score.
203        """
204        return getGradeWeightFromScore(self.score)[0]
205
206    @property
207    def weight(self):
208        """Returns the weight calculated from score.
209        """
210        return getGradeWeightFromScore(self.score)[1]
211
212CourseTicket = attrs_to_fields(CourseTicket)
213
214class CourseTicketFactory(grok.GlobalUtility):
215    """A factory for student study levels.
216    """
217    grok.implements(IFactory)
218    grok.name(u'waeup.CourseTicket')
219    title = u"Create a new course ticket.",
220    description = u"This factory instantiates new course ticket instances."
221
222    def __call__(self, *args, **kw):
223        return CourseTicket()
224
225    def getInterfaces(self):
226        return implementedBy(CourseTicket)
Note: See TracBrowser for help on using the repository browser.