Exemplo n.º 1
0
def _validate_grades(c):
    assignment_names = get_assignment_name_set()
    c.execute("SELECT DISTINCT assignment FROM grades")
    for assignment_name, in c.fetchall():
        assert assignment_name in assignment_names, (
            "Unknown assignment in database: %s" % assignment_name)
    c.execute("SELECT DISTINCT assignment FROM gradeslog")
    for assignment_name, in c.fetchall():
        assert assignment_name in assignment_names, (
            "Unknown assignment in database: %s" % assignment_name)
    c.execute("SELECT DISTINCT job FROM builds")
    for assignment_name, in c.fetchall():
        assert assignment_name in assignment_names, (
            "Unknown assignment in database: %s" % assignment_name)
Exemplo n.º 2
0
def _validate_grades(c):
    assignment_names = get_assignment_name_set()
    c.execute("SELECT DISTINCT assignment FROM grades")
    for assignment_name, in c.fetchall():
        assert assignment_name in assignment_names, ("Unknown assignment in database: %s" %
                                                     assignment_name)
    c.execute("SELECT DISTINCT assignment FROM gradeslog")
    for assignment_name, in c.fetchall():
        assert assignment_name in assignment_names, ("Unknown assignment in database: %s" %
                                                     assignment_name)
    c.execute("SELECT DISTINCT job FROM builds")
    for assignment_name, in c.fetchall():
        assert assignment_name in assignment_names, ("Unknown assignment in database: %s" %
                                                     assignment_name)
Exemplo n.º 3
0
def assign_grade_batch(c, users, assignment, score, slipunits, transaction_name, description,
                       source, manual=False, dont_lower=False):
    """
    Assigns a new grade to one or more students. Also supports assigning slip units. You can use
    the special value `None` for score and/or slipunits to use the current value. If the dont_lower
    flag is True, then anybody in `users` who currently has a higher grade will be removed from
    the operation (and slip days will not be adjusted either).

    Returns a list of user ids whose grades were affected (will always be a subset of users).

    """
    if assignment not in get_assignment_name_set():
        raise ValueError("Assignment %s is not known" % assignment)
    if not users:
        return []
    if score is None and slipunits is None:
        return []
    timestamp = now_str()

    if dont_lower:
        if score is None:
            # It makes no sense to do this.
            raise ValueError("You can not use both dont_lower=True and have a score of None, if " +
                             "slipunits is not None.")

        # This comparison (old score vs new score) MUST be done in Sqlite in order for the result
        # to be correct. Sqlite will round the floating point number in the same way it did when
        # the original result was inserted, and the two values will be equal. Converting this to a
        # float in another language may produce undesirable effects.
        c.execute('''SELECT user FROM grades
                     WHERE assignment = ? AND score >= ? AND user IN (%s)''' %
                  (','.join(['?'] * len(users))), [assignment, score] + users)
        users = list(set(users) - {user for user, in c.fetchall()})
        if not users:
            return []

    c.execute('''SELECT users.id FROM grades LEFT JOIN users
                 ON grades.user = users.id WHERE grades.assignment = ? AND users.id IN (%s)''' %
              (','.join(["?"] * len(users))), [assignment] + users)
    for user in list(set(users) - {user for user, in c.fetchall()}):
        # Insert dummy values first, and we will update them later
        c.execute('''INSERT INTO grades (user, assignment) VALUES (?, ?)''',
                  [user, assignment])

    c.execute('''UPDATE grades SET updated = ?, manual = ?
                 WHERE assignment = ? AND user IN (%s)''' % (','.join(['?'] * len(users))),
              [timestamp, int(manual), assignment] + users)

    if score is not None:
        c.execute('''UPDATE grades SET score = ?
                     WHERE assignment = ? AND user IN (%s)''' % (','.join(['?'] * len(users))),
                  [score, assignment] + users)

    if slipunits is not None:
        c.execute('''UPDATE grades SET slipunits = ?
                     WHERE assignment = ? AND user IN (%s)''' % (','.join(['?'] * len(users))),
                  [slipunits, assignment] + users)

    c.execute('''INSERT INTO gradeslog (transaction_name, description, source, updated, user,
                                        assignment, score, slipunits)
                 VALUES %s''' % (','.join(['(?,?,?,?,?,?,?,?)'] * len(users))),
              [field for entry in [[transaction_name, description, source, timestamp, user,
                                    assignment, score, slipunits]
                                   for user in users] for field in entry])
    return users
Exemplo n.º 4
0
def assign_grade_batch(c, users, assignment, score, slipunits, transaction_name, description,
                       source, manual=False, dont_lower=False):
    """
    Assigns a new grade to one or more students. Also supports assigning slip units. You can use
    the special value `None` for score and/or slipunits to use the current value. If the dont_lower
    flag is True, then anybody in `users` who currently has a higher grade will be removed from
    the operation (and slip days will not be adjusted either).

    Returns a list of user ids whose grades were affected (will always be a subset of users).

    """
    if assignment not in get_assignment_name_set():
        raise ValueError("Assignment %s is not known" % assignment)
    if not users:
        return []
    if score is None and slipunits is None:
        return []
    timestamp = now_str()

    if dont_lower:
        if score is None:
            # It makes no sense to do this.
            raise ValueError("You can not use both dont_lower=True and have a score of None, if " +
                             "slipunits is not None.")

        # This comparison (old score vs new score) MUST be done in Sqlite in order for the result
        # to be correct. Sqlite will round the floating point number in the same way it did when
        # the original result was inserted, and the two values will be equal. Converting this to a
        # float in another language may produce undesirable effects.
        c.execute('''SELECT user FROM grades
                     WHERE assignment = ? AND score >= ? AND user IN (%s)''' %
                  (','.join(['?'] * len(users))), [assignment, score] + users)
        users = list(set(users) - {user for user, in c.fetchall()})
        if not users:
            return []

    c.execute('''SELECT users.id FROM grades LEFT JOIN users
                 ON grades.user = users.id WHERE grades.assignment = ? AND users.id IN (%s)''' %
              (','.join(["?"] * len(users))), [assignment] + users)
    for user in list(set(users) - {user for user, in c.fetchall()}):
        # Insert dummy values first, and we will update them later
        c.execute('''INSERT INTO grades (user, assignment) VALUES (?, ?)''',
                  [user, assignment])

    c.execute('''UPDATE grades SET updated = ?, manual = ?
                 WHERE assignment = ? AND user IN (%s)''' % (','.join(['?'] * len(users))),
              [timestamp, int(manual), assignment] + users)

    if score is not None:
        c.execute('''UPDATE grades SET score = ?
                     WHERE assignment = ? AND user IN (%s)''' % (','.join(['?'] * len(users))),
                  [score, assignment] + users)

    if slipunits is not None:
        c.execute('''UPDATE grades SET slipunits = ?
                     WHERE assignment = ? AND user IN (%s)''' % (','.join(['?'] * len(users))),
                  [slipunits, assignment] + users)

    c.execute('''INSERT INTO gradeslog (transaction_name, description, source, updated, user,
                                        assignment, score, slipunits)
                 VALUES %s''' % (','.join(['(?,?,?,?,?,?,?,?)'] * len(users))),
              [field for entry in [[transaction_name, description, source, timestamp, user,
                                    assignment, score, slipunits]
                                   for user in users] for field in entry])
    return users