~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to ivle/db.py

  • Committer: Matt Giuca
  • Date: 2009-01-19 17:28:59 UTC
  • mto: This revision was merged to the branch mainline in revision 1090.
  • Revision ID: matt.giuca@gmail.com-20090119172859-htjq3rfpp0fhtpc9
ivle.worksheet: Added calculate_score. This is a nice clean Storm port of
    ivle.db.calculate_worksheet_score.
tutorial: Replaced use of ivle.db.calculate_worksheet_score with
    ivle.worksheet.calculate_score.
    Guess What!! Removed this module's dependency on ivle.db! Hooray!
    (Note: tutorialservice still depends on it).
bin/ivle-marks: Updated this script to use ivle.worksheet_calculate_score.
    Note that this DOES NOT execute properly -- it seems it didn't even
    before my changes (tries to call db.get_users). Not my fault; I'm
    committing and going to bed!
ivle.db: Removed calculate_worksheet_score.
    As this removes the dependency on get_problem_status, removed that too!
    Almost all the worksheet stuff is gone now!

Show diffs side-by-side

added added

removed removed

Lines of Context:
513
513
                frozenset(['date', 'text']),
514
514
                frozenset(['problemid', 'loginid']))
515
515
 
516
 
    def _get_problem_status(self, login, exercisename, dry=False):
517
 
        """Given a login name and exercise name, returns information about the
518
 
        user's performance on that problem.
519
 
        Returns a tuple of:
520
 
            - A boolean, whether they have successfully passed this exercise.
521
 
            - An int, the number of attempts they have made up to and
522
 
              including the first successful attempt (or the total number of
523
 
              attempts, if not yet successful).
524
 
        Note: exercisename may be an int, in which case it will be directly
525
 
        used as the problemid.
526
 
        """
527
 
        if isinstance(exercisename, int):
528
 
            problemid = exercisename
529
 
        else:
530
 
            problemid = self.get_problem_problemid(exercisename)
531
 
        loginid = self.get_user_loginid(login)  # May raise a DBException
532
 
 
533
 
        # ASSUME that it is completed, get the total number of attempts up to
534
 
        # and including the first successful attempt.
535
 
        # (Get the date of the first successful attempt. Then count the number
536
 
        # of attempts made <= that date).
537
 
        # Will return an empty table if the problem has never been
538
 
        # successfully completed.
539
 
        query = """SELECT COUNT(*) FROM problem_attempt
540
 
    WHERE loginid = %d AND problemid = %d AND active AND date <=
541
 
        (SELECT date FROM problem_attempt
542
 
            WHERE loginid = %d AND problemid = %d AND complete AND active
543
 
            ORDER BY date ASC
544
 
            LIMIT 1);""" % (loginid, problemid, loginid, problemid)
545
 
        if dry: return query
546
 
        result = self.db.query(query)
547
 
        count = int(result.getresult()[0][0])
548
 
        if count > 0:
549
 
            # The user has made at least 1 successful attempt.
550
 
            # Return True for success, and the number of attempts up to and
551
 
            # including the successful one.
552
 
            return (True, count)
553
 
        else:
554
 
            # Returned 0 rows - this indicates that the problem has not been
555
 
            # completed.
556
 
            # Return the total number of attempts, and False for success.
557
 
            query = """SELECT COUNT(*) FROM problem_attempt
558
 
    WHERE loginid = %d AND problemid = %d AND active;""" % (loginid, problemid)
559
 
            result = self.db.query(query)
560
 
            count = int(result.getresult()[0][0])
561
 
            return (False, count)
562
 
 
563
 
    # WORKSHEET/PROBLEM ASSOCIATION AND MARKS CALCULATION
564
 
 
565
 
    def calculate_score_worksheet(self, login, subject, worksheet):
566
 
        """
567
 
        Calculates the score for a user on a given worksheet.
568
 
        Returns a 4-tuple of ints, consisting of:
569
 
        (No. mandatory exercises completed,
570
 
         Total no. mandatory exercises,
571
 
         No. optional exercises completed,
572
 
         Total no. optional exercises)
573
 
        """
574
 
        self.start_transaction()
575
 
        try:
576
 
            mand_done = 0
577
 
            mand_total = 0
578
 
            opt_done = 0
579
 
            opt_total = 0
580
 
            # Get a list of problems and optionality for all problems in the
581
 
            # worksheet
582
 
            query = ("""SELECT problemid, optional FROM worksheet_problem
583
 
    WHERE worksheetid = (SELECT worksheetid FROM worksheet
584
 
                         WHERE subject = %s and identifier = %s);"""
585
 
                    % (_escape(subject), _escape(worksheet)))
586
 
            result = self.db.query(query)
587
 
            # Now get the student's pass/fail for each problem in this worksheet
588
 
            for problemid, optional in result.getresult():
589
 
                done, _ = self._get_problem_status(login, problemid)
590
 
                # done is a bool, whether this student has completed that
591
 
                # problem
592
 
                if _parse_boolean(optional):
593
 
                    opt_total += 1
594
 
                    if done: opt_done += 1
595
 
                else:
596
 
                    mand_total += 1
597
 
                    if done: mand_done += 1
598
 
            self.commit()
599
 
        except:
600
 
            self.rollback()
601
 
            raise
602
 
        return mand_done, mand_total, opt_done, opt_total
603
 
 
604
516
    # ENROLMENT INFORMATION
605
517
 
606
518
    def add_enrolment(self, login, subj_code, semester, year=None, dry=False):