source: main/ikobacustom.pcn/trunk/src/ikobacustom/pcn/customers/schoolgrades.py @ 15369

Last change on this file since 15369 was 12570, checked in by Henrik Bettermann, 10 years ago

Add schoolgrades module.

  • Property svn:keywords set to Id
File size: 10.7 KB
Line 
1## $Id: schoolgrades.py 12570 2015-02-09 08:06:11Z henrik $
2##
3## Copyright (C) 2012 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"""Components representing and aggregating school grades.
19"""
20import grok
21from zc.sourcefactory.basic import BasicSourceFactory
22from zope.interface import Interface
23from zope.formlib.interfaces import IInputWidget, IDisplayWidget
24from zope.publisher.interfaces.browser import IBrowserRequest
25from zope import schema
26from zope.schema.interfaces import IObject
27from zope.schema.fieldproperty import FieldProperty
28from waeup.ikoba.widgets.objectwidget import (
29    IkobaObjectWidget, IkobaObjectDisplayWidget
30    )
31from ikobacustom.pcn.interfaces import MessageFactory as _
32
33EXAM_SUBJECTS_DICT = {
34    'accounts': 'Accounts',
35    'add_general_science': 'Add General Science',
36    'add_maths': 'Add Maths',
37    'adv_elect_install_maint': 'Adv. Electrical Installation and Maintenance',
38    'agricultural_science': 'Agricultural Science',
39    'applied_electricity': 'Applied Electricity',
40    'arabi': 'Arabic',
41    'arithmetics': 'Arithmetics',
42    'art': 'Art',
43    'auto_mechanics': 'Auto Mechanics',
44    'awaiting_results': 'Awaiting Results',
45    'basic_electricity': 'Basic Electricity',
46    'bible_knowledge': 'Bible Knowledge',
47    'biology': 'Biology',
48    'biology_alt_syl': 'Biology (Alt.Syl)',
49    'book_keeping': 'Book Keeping',
50    'building_construction': 'Building Construction',
51    'business_management': 'Business Management',
52    'business_construction_management': 'Business/Construction Management (Adv)',
53    'chemistry': 'Chemistry',
54    'chemistry_alt_syl': 'Chemistry (Alt.Syl)',
55    'christian_religious_studies': 'Christian Religious Studies',
56    'class_teaching': 'Class Teaching',
57    'clerical_office_duties': 'Clerical Office Duties',
58    'clothing_and_textiles': 'Clothing and Textiles',
59    'commerce': 'Commerce',
60    'economics': 'Economics',
61    'education': 'Education',
62    'efik': 'Efik',
63    'electronics': 'Electronics',
64    'elementary_surveying': 'Elementary Surveying',
65    'english_language': 'English Language',
66    'engineering_science': 'Engineering Science',
67    'financial_accounting': 'Financial Accounting',
68    'food_and_nutrition': 'Food and Nutrition',
69    'french': 'French',
70    'further_mathematics': 'Further Mathematics',
71    'general_science': 'General Science',
72    'geography': 'Geography',
73    'german': 'German',
74    'government': 'Government',
75    'hausa': 'Hausa',
76    'hausa_literature': 'Hausa Literature',
77    'health_science': 'Health Science',
78    'history': 'History',
79    'home_management': 'Home Management',
80    'human_biology': 'Human Biology',
81    'industrial_electrical_installation': 'Industrial Elect Installation (Adv)',
82    'intergrated_science': 'Intergrated Science',
83    'islamic_studies': 'Islamic Studies',
84    'literature_in_english': 'Literature in English',
85    'literature_in_nigerian_languages': 'Literature in Nigerian Languages',
86    'igbo': 'Igbo',
87    'igbo_literature': 'Igbo Literature',
88    'yoruba': 'Yoruba',
89    'yoruba_literature': 'Yoruba Literature',
90    'management_in_living': 'Management in Living',
91    'mathematics': 'Mathematics',
92    'metalwork': 'Metalwork',
93    'music': 'Music',
94    'nigerian_language': 'Nigerian Language',
95    'office_practice': 'Office Practice',
96    'physical_education': 'Physical Education',
97    'physical_health_education': 'Physical and Health Education',
98    'physics': 'Physics',
99    'physics_alt_syl': 'Physics (Alt.Syl)',
100    'principles_and_practice_of_education': 'Principles and Practice of Education',
101    'principles_of_cost_accounting': 'Principles of Cost Accounting',
102    'rural_science': 'Rural Science',
103    'science': 'Science',
104    'secretarial_duties': 'Secretarial Duties',
105    'shorthand': 'Shorthand',
106    'sierra_leone_studies': 'Sierra Leone Studies',
107    'sierra_leone_languages': 'Sierra Leone Languages',
108    'social_studies': 'Social Studies',
109    'statistics': 'Statistics',
110    'teaching_practice': 'Teaching Practice',
111    'technical_drawing': 'Technical Drawing',
112    'typewriting': 'Typewriting',
113    'visual_art': 'Visual Art',
114    'woodwork': 'Woodwork',
115    'winding_elect_machines': 'Winding of Elect Machines and Elect Eng Sc',
116    'first_written': 'First Written',
117    'second_written': 'Second Written',
118    'pract_tests': 'Practical Tests',
119    # Added 25/08/2014
120    'animal_husbandry_(alt_a)': 'Animal Husbandry (Alt A)',
121    'animal_husbandry_(alt_b)': 'Animal Husbandry (Alt B)',
122    'auto_electrical_work': 'Auto Electrical Work',
123    'auto_mechanical_work': 'Auto Mechanical Work',
124    'catering_craft_practice': 'Catering Craft Practice',
125    'civic_education': 'Civic Education',
126    'computer_studies': 'Computer Studies',
127    'cosmetology': 'Cosmetology',
128    'data_processing': 'Data Processing',
129    'dyeing_&_bleaching': 'Dyeing & Bleaching',
130    'electrical_installation_and_maintenance_work': 'Electrical Installation and Maintenance Work',
131    'fisheries_(alt_a)_ghana_candidates': 'Fisheries (Alt A) Ghana Candidates',
132    'fisheries_(alt_b)_nigeria_candidates': 'Fisheries (Alt B) Nigeria Candidates',
133    'garment_making': 'Garment Making',
134    'general_agriculture': 'General Agriculture',
135    'gsm_phones_maintenance_and_repairs': 'Gsm Phones Maintenance and Repairs',
136    'health_education': 'Health Education',
137    'insurance': 'Insurance',
138    'painting_and_decorating': 'Painting and Decorating',
139    'photography': 'Photography',
140    'printing_craft_practice': 'Printing Craft Practice',
141    'store_management': 'Store Management',
142    'textiles': 'Textiles',
143    # Added 19/01/2015
144    'marketing': 'Marketing',
145    'carpentry_joinery': 'Carpentry and Joinery',
146    'tourism': 'Tourism',
147    'mining': 'Mining',
148    }
149
150EXAM_GRADES = (
151    ('A1', 'Excellent (A1)'),
152    ('A2', 'Very Good (A2)'),
153    ('A3', 'Good (A3)'),
154    ('B2', 'Very Good (B2)'),
155    ('B3', 'Good (B3)'),
156    ('C4', 'Credit (C4)'),
157    ('C5', 'Credit (C5)'),
158    ('C6', 'Credit (C6)'),
159    ('A', 'Pass (A)'),
160    ('B', 'Pass (B)'),
161    ('C', 'Pass (C)'),
162    ('U', 'Pass (U)'),
163    ('D7', 'Pass (D7)'),
164    ('P7', 'Pass (P7)'),
165    ('P8', 'Pass (P8)'),
166    ('E8', 'Pass (E8)'),
167    ('F9', 'Fail (F9)'),
168    ('Aa', 'A (a)'),
169    ('Bb', 'B (b)'),
170    ('Cc', 'C (c)'),
171    ('Dd', 'D (d)'),
172    ('Ee', 'E (e)'),
173    ('Ff', 'F (f)'),
174    ('Gg', 'G (g)'),
175    ('credit-1', 'Credit-1'),
176    ('credit-2', 'Credit-2'),
177    ('dist', 'Distinction'),
178    ('pass', 'Pass'),
179    ('AR', 'Awaiting Results'),
180    )
181
182
183class SubjectSource(BasicSourceFactory):
184    """A source for school subjects used in exam documentation.
185    """
186    def getValues(self):
187        return sorted(EXAM_SUBJECTS_DICT.keys())
188
189    def getTitle(self, value):
190        return "%s:" % EXAM_SUBJECTS_DICT[value]
191
192
193class GradeSource(BasicSourceFactory):
194    """A source for exam grades.
195    """
196    def getValues(self):
197        for entry in EXAM_GRADES:
198            yield entry[0]
199
200    def getTitle(self, value):
201        return dict(EXAM_GRADES)[value]
202
203
204class IResultEntry(Interface):
205    """A school grade entry.
206    """
207    subject = schema.Choice(
208        title = _(u'Subject'),
209        source = SubjectSource(),
210        )
211    grade = schema.Choice(
212        title = _(u'Grade'),
213        source = GradeSource(),
214        )
215
216
217class IResultEntryField(IObject):
218    """A zope.schema-like field for usage in interfaces.
219
220    Marker interface to distuingish result entries from ordinary
221    object fields. Needed for registration of widgets.
222    """
223
224
225#: A unique default value.
226DEFAULT_VALUE = object()
227
228
229class ResultEntry(grok.Model):
230    """A result entry contains a subject and a grade.
231    """
232    grok.implements(IResultEntry)
233    subject = FieldProperty(IResultEntry['subject'])
234    grade = FieldProperty(IResultEntry['grade'])
235
236    def __init__(self, subject=None, grade=None):
237        super(ResultEntry, self).__init__()
238        if subject is not None:
239            self.subject = subject
240        if grade is not None:
241            self.grade = grade
242        return
243
244    def __eq__(self, obj):
245        """Two ResultEntry objects are equal if their `subject` and
246           `grade` are equal.
247        """
248        for name in ('subject', 'grade',):
249            if getattr(self, name) != getattr(obj, name, DEFAULT_VALUE):
250                return False
251        return True
252
253    def __ne__(self, other):
254        """Two ResultEntries are not equal, if their equality test fails.
255
256        a != b <-> not(a == b). Python doc tell, that __ne__ should
257        also be rovided, whenever __eq__ is implemented.
258        """
259        return not self.__eq__(other)
260
261    def to_string(self):
262        """A string representation that can be used in exports.
263
264        Returned is a unicode string of format ``(u'<SUBJ>',u'<GRADE>')``.
265        """
266        return unicode((self.subject, self.grade))
267
268    @classmethod
269    def from_string(cls, string):
270        """Create new ResultEntry instance based on `string`.
271
272        The string is expected to be in format as delivered by
273        meth:`to_string`.
274
275        This is a classmethod. This means, you normally will call::
276
277          ResultEntry.from_string(mystring)
278
279        i.e. use the `ResultEntry` class, not an instance thereof.
280        """
281        string = string.replace("u''", "None")
282        subject, grade = eval(string)
283        return cls(subject, grade)
284
285
286class ResultEntryField(schema.Object):
287    """A zope.schema-like field for usage in interfaces.
288
289    If you want to define an interface containing result entries, you
290    can do so like this::
291
292      class IMyInterface(Interface):
293          my_result_entry = ResultEntryField()
294
295    Default widgets are registered to render result entry fields.
296    """
297    grok.implements(IResultEntryField)
298
299    def __init__(self, **kw):
300        super(ResultEntryField, self).__init__(IResultEntry, **kw)
301        return
302
303
304# register IkobaObjectWidgets as default widgets for IResultEntryFields
305@grok.adapter(IResultEntryField, IBrowserRequest)
306@grok.implementer(IInputWidget)
307def result_entry_input_widget(obj, req):
308    return IkobaObjectWidget(obj, req, ResultEntry)
309
310
311# register a display widget for IResultEntryFields
312@grok.adapter(IResultEntryField, IBrowserRequest)
313@grok.implementer(IDisplayWidget)
314def result_entry_display_widget(obj, req):
315    return IkobaObjectDisplayWidget(obj, req, ResultEntry)
Note: See TracBrowser for help on using the repository browser.