Ignore:
Timestamp:
24 Jan 2015, 18:30:11 (10 years ago)
Author:
Henrik Bettermann
Message:

Student statistic can now be broken down by faculties or by departments.

Location:
main/waeup.kofa/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.kofa/trunk/CHANGES.txt

    r12513 r12515  
    77* Check if p_id exists in payments_catalog when importing payment tickets in
    88  create mode.
     9
     10* Student statistic can now be broken down by faculties or by departments.
    911
    1012
  • main/waeup.kofa/trunk/src/waeup/kofa/students/reports/browser_templates/studentstatisticsreportgeneratorpage.pt

    r11254 r12515  
    66    to view/download.
    77  </p>
     8  <br />
     9  <label for="breakdown" i18n:translate="">Breakdown</label>
     10    <select name="breakdown" class="form-control half">
     11      <span tal:repeat="items view/breakdowns" tal:omit-tag="">
     12        <option
     13            tal:define="name python: items[1]; title python: items[0]"
     14            tal:attributes="value name">
     15          <span tal:replace="title">TITLE</span>
     16        </option>
     17      </span>
     18    </select>
    819  <br />
    920  <label for="session" i18n:translate="">Study Modes Group</label>
  • main/waeup.kofa/trunk/src/waeup/kofa/students/reports/student_statistics.py

    r11254 r12515  
    3232    creation_dt_string = Attribute('Human readable report creation datetime')
    3333
    34 def get_student_stats(session, mode):
     34def get_student_stats(session, mode, breakdown):
    3535    """Get students in a certain session and study mode.
    3636
    37     Returns a table ordered by faculty code (one per row) and
     37    Returns a table ordered by code (faculty or department, one per row) and
    3838    registration state (cols). The result is a 3-tuple representing
    39     ((<FACULTY_CODES>), (<STATES>), (<NUM_OF_STUDENTS>)). The
     39    ((<CODES>), (<STATES>), (<NUM_OF_STUDENTS>)). The
    4040    (<NUM_OF_STUDENTS>) is an n-tuple with each entry containing the
    41     number of students found in that faculty and with the respective
     41    number of students found in that faculty/department and with the respective
    4242    state.
    4343
     
    5454    states = tuple([x.value for x in registration_states_vocab])
    5555    states = states + (u'Total',)
    56     fac_codes = tuple(sorted([x for x in site['faculties'].keys()],
    57                              key=lambda x: x.lower()))
    58     fac_codes = fac_codes + (u'Total',)
     56    if breakdown == 'faccode':
     57        codes = tuple(sorted([x for x in site['faculties'].keys()],
     58                                 key=lambda x: x.lower()))
     59    elif breakdown == 'depcode':
     60        faculties = site['faculties']
     61        depcodes = []
     62        for fac in faculties.values():
     63            for dep in fac.values():
     64                depcodes.append(dep.code)
     65        codes = tuple(sorted([x for x in depcodes],
     66                                 key=lambda x: x.lower()))
     67    codes = codes + (u'Total',)
    5968    # XXX: Here we do _one_ query and then examine the single
    6069    #   students. One could also do multiple queries and just look for
     
    6372    cat = queryUtility(ICatalog, name="students_catalog")
    6473    result = cat.searchResults(current_session=(session, session))
    65     table = [[0 for x in xrange(len(states))] for y in xrange(len(fac_codes))]
     74    table = [[0 for x in xrange(len(states))] for y in xrange(len(codes))]
    6675    mode_groups = getUtility(IKofaUtils).MODE_GROUPS
    6776    for stud in result:
    6877        if mode != 'All' and stud.current_mode not in mode_groups[mode]:
    6978            continue
    70         if stud.faccode not in fac_codes:
     79        if getattr(stud, breakdown) not in codes:
    7180            # studs can have a faccode ``None``
    7281            continue
    73         row = fac_codes.index(stud.faccode)
     82        row = codes.index(getattr(stud, breakdown))
    7483        col = states.index(stud.state)
    7584        table[row][col] += 1
     
    7988    # turn lists into tuples
    8089    table = tuple([tuple(row) for row in table])
    81     return (fac_codes, states, table)
     90    return (codes, states, table)
    8291
    8392from reportlab.lib import colors
     
    124133    mode = None
    125134
    126     def __init__(self, session, mode, author='System'):
     135    def __init__(self, session, mode, breakdown, author='System'):
    127136        super(StudentStatisticsReport, self).__init__(
    128             args=[session, mode], kwargs={'author':author})
     137            args=[session, mode, breakdown], kwargs={'author':author})
    129138        self.session = academic_sessions_vocab.getTerm(session).title
    130139        self.mode = mode
     140        self.breakdown = breakdown
    131141        self.author = author
    132142        self.creation_dt_string = self.creation_dt.astimezone(
    133143            getUtility(IKofaUtils).tzinfo).strftime("%Y-%m-%d %H:%M:%S %Z")
    134         self.data = get_student_stats(session, mode)
     144        self.data = get_student_stats(session, mode, breakdown)
    135145
    136146    def create_pdf(self):
     
    156166    grok.name('student_stats')
    157167
    158     def generate(self, site, session=None, mode=None, author=None):
    159         result = StudentStatisticsReport(session=session, mode=mode, author=author)
     168    def generate(self, site, session=None, mode=None, breakdown=None, author=None):
     169        result = StudentStatisticsReport(
     170            session=session, mode=mode, breakdown=breakdown, author=author)
    160171        return result
    161172
     
    185196        return None
    186197
    187     def update(self, CREATE=None, session=None, mode=None):
     198    def update(self, CREATE=None, session=None, mode=None, breakdown=None):
    188199        self.parent_url = self.url(self.context.__parent__)
    189200        self._set_session_values()
    190201        self._set_mode_values()
     202        self._set_breakdown_values()
    191203        if CREATE and session:
    192204            # create a new report job for students by session
     
    195207            kw = dict(
    196208                session=int(session),
    197                 mode=mode)
     209                mode=mode,
     210                breakdown=breakdown)
    198211            self.flash(_('New report is being created in background'))
    199212            job_id = container.start_report_job(
     
    201214            ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
    202215            grok.getSite().logger.info(
    203                 '%s - report %s created: %s (session=%s, mode=%s)' % (
    204                 ob_class, job_id, self.context.title, session, mode))
     216                '%s - report %s created: %s (session=%s, mode=%s, breakdown=%s)' % (
     217                ob_class, job_id, self.context.title, session, mode, breakdown))
    205218            self.redirect(self.parent_url)
    206219            return
     
    215228        mode_groups = getUtility(IKofaUtils).MODE_GROUPS
    216229        self.modes = sorted([(key, key) for key in mode_groups.keys()])
     230        return
     231
     232    def _set_breakdown_values(self):
     233        self.breakdowns = [('Faculties', 'faccode'), ('Departments', 'depcode')]
    217234        return
    218235
  • main/waeup.kofa/trunk/src/waeup/kofa/students/reports/tests/test_student_statistics.py

    r12110 r12515  
    2424    def test_iface(self):
    2525        # ensure we fullfill interface contracts
    26         obj = StudentStatisticsReport(2010, 'Undergraduate Full-Time')
     26        obj = StudentStatisticsReport(
     27            2010, 'Undergraduate Full-Time', 'faccode')
    2728        verifyClass(IStudentStatisticsReport, StudentStatisticsReport)
    2829        verifyObject(IStudentStatisticsReport, obj)
     
    3132    def test_get_student_stats_session_simple(self):
    3233        # we can get a table with one student
    33         result1 = get_student_stats(2010, 'Undergraduate Full-Time')
    34         result2 = get_student_stats(2009, 'Undergraduate Full-Time')
     34        result1 = get_student_stats(2010, 'Undergraduate Full-Time', 'faccode')
     35        result2 = get_student_stats(2009, 'Undergraduate Full-Time', 'faccode')
    3536        self.assertEqual(
    3637            result1,
     
    4950    def test_get_student_stats_session_multiple(self):
    5051        # we can get a table with several students
    51         self.create_cert(u'fac2', u'dept2', u'CERT2')
    52         result1 = get_student_stats(2010, 'Undergraduate Full-Time')
    53         result2 = get_student_stats(2009, 'Undergraduate Full-Time')
     52        self.create_cert(u'fac2', u'dep2', u'CERT2')
     53        result1 = get_student_stats(2010, 'Undergraduate Full-Time', 'faccode')
     54        result2 = get_student_stats(2009, 'Undergraduate Full-Time', 'faccode')
    5455        self.assertEqual(
    5556            result1,
     
    6869        return
    6970
     71    def test_get_student_stats_session_multiple_dep_breakdown(self):
     72        # we can get a table with several students
     73        self.create_cert(u'fac2', u'dep2', u'CERT2')
     74        result1 = get_student_stats(2010, 'Undergraduate Full-Time', 'depcode')
     75        result2 = get_student_stats(2009, 'Undergraduate Full-Time', 'depcode')
     76        self.assertEqual(
     77            result1,
     78            ((u'dep1', u'dep2', u'Total'),
     79             self.states,
     80             ((1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1),
     81              (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
     82              (1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1),)))
     83        self.assertEqual(
     84            result2,
     85            ((u'dep1', u'dep2', u'Total'),
     86             self.states,
     87             ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
     88              (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
     89              (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),)))
     90        return
     91
    7092    def test_create_pdf(self):
    7193        self.create_cert(u'FAC2', u'dept2', u'CERT2')
    72         report = StudentStatisticsReport(2010, 'Undergraduate Full-Time')
     94        report = StudentStatisticsReport(
     95            2010, 'Undergraduate Full-Time', 'faccode')
    7396        result = report.create_pdf()
    7497        self.assertTrue(result.startswith('%PDF-'))
     
    104127        self.browser.getControl(name="generator").value = ['student_stats']
    105128        self.browser.getControl("Configure").click()
     129        self.browser.getControl(name="breakdown").value = ['depcode']
    106130        self.browser.getControl(name="mode").value = ['All']
    107131        self.browser.getControl(name="session").value = ['2004']
     
    134158        self.assertTrue(
    135159            'INFO - zope.mgr - students.reports.student_statistics.StudentStatisticsReportGeneratorPage - '
    136             'report %s created: Student Statistics (session=2004, mode=All)'
     160            'report %s created: Student Statistics (session=2004, mode=All, breakdown=depcode)'
    137161            % job_id in logcontent
    138162            )
  • main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_batching.py

    r12513 r12515  
    288288        # XXX: there is no addPayment method to give predictable names
    289289        self.payment = student['payments']['my-payment'] = payment
    290         notify(grok.ObjectModifiedEvent(self.payment))
    291290        return payment
    292291
Note: See TracChangeset for help on using the changeset viewer.