Exemple #1
0
def markAllAsVerified(assignName, silent=False):
    """
    Marks all graded files in the given assignment directory as human-verified.
    
    If silent is True, won't print any feedback.
    """
    files = tamarin.getSubmissions(assignment=assignName, submitted=False)
    files.sort()

    if not silent:
        print('<p class="strip"><b>Marking these files as human '
              'verified:</b><br>')
  
    marked = 0
    for f in files:
        # convert to GradedFile objects
        gf = GradedFile(os.path.basename(f))
        if not gf.humanVerified:
            if not silent: 
                print(gf.graderOutputFilename + ' &nbsp; ==&gt; &nbsp; ', 
                      end='')
            gf.humanVerified = True
            gf.update()
            marked += 1
            if not silent:
                print(gf.graderOutputFilename + '<br>')

    if not silent:
        print('<p class="strip">Marked ' + str(marked) + ' of ' + 
              str(len(files)) + ' submissions for ' + assignName +
              ' as human-verified.</p>')
        print('<p class="strip"><b>Done.</b></p>')
Exemple #2
0
    def getResubmissionGradeAdjustment(self, submissionCount=None):
        """
        Returns the penalty due to additional submissions for this assignment.

        Penalty can be more than can be covered by the grade itself. 
        Returns the penalty even for non-numeric grades. 
        
        The submissionCount is a performance boost.  If the number of 
        submissions (including this one) is given here, will be used instead
        of polling the file system to (re)collect the same data. 
        
        """
        import tamarin
        if not submissionCount:
            # need to count the files here
            files = tamarin.getSubmissions(user=self.username, 
                                           assignment=self.assignment)
            submissionCount = len(files)            

        if submissionCount <= 1:
            return 0
        else:            
            adj = (submissionCount - 1) * tamarin.RESUBMISSION_PENALTY
            return round(adj, tamarin.GRADE_PRECISION)
Exemple #3
0
def displayAssignmentSubmissions(user, assignmentName, 
                                 brief=False, master=False):
    """
    Displays all the submissions the user made for this assignment.
    
    In brief mode, this will just be a list of files, including the grade
    for each one.  Each listing will be a button (or link, if in master mode)
    to the appropriate submission view.
    
    If in full mode (that is, brief=False), will show each submission expanded 
    within this view.
    
    At the top off all submissions, will include a header listing the 
    assignment and the final grade based on last submission and late policy
    adjustments.
    """
    assignment = Assignment(assignmentName)
    files = tamarin.getSubmissions(user=user, assignment=assignmentName)
    
    # calculate final grade and status for this assignment
    # (Assuming that even ungraded and grader-error submissions count as
    # submissions, we only need the grade of the last submission to have an 
    # accurate final grade.)
    grade = '<i>Not yet submitted.</i>'
    reason = None

    if files:
        lastSubmit = files[-1]
        if tamarin.SUBMITTED_ROOT in lastSubmit:
            grade = '<i>Not yet graded.</i>'
            lastFile = SubmittedFile(os.path.basename(lastSubmit))
        else:
            lastFile = GradedFile(os.path.basename(lastSubmit))
            grade = lastFile.getAdjustedGrade(len(files))
            lateness = lastFile.getLateGradeAdjustment()
            resubmits = lastFile.getResubmissionGradeAdjustment(len(files))
            
            if lateness or resubmits:
                # explain grade calcs
                reason = '[= ' + str(lastFile.grade)
                if lateness:
                    reason += ' ' + str(lateness)
                    offset = lastFile.getLateOffset()
                    label = 'early' if offset[0] == '-' else 'late'
                    reason += ' <i>(' + label + ' ' + offset + ')</i>'
                if resubmits:
                    reason += ' ' + str(resubmits)
                    reason += ' <i>(' + str(len(files) - 1) + \
                              '&nbsp;resubmits)</i>'
                reason += ']'
            elif lastFile.isLate():
                # just a little informational timestamping
                reason = '<small>' + lastFile.getLateOffset() + '</small>'
            
            # mark grade if not verified yet
            if not lastFile.humanVerified:
                grade = '<span class="unverified">' + str(grade) + \
                        tamarin.UNVERIFIED_GRADE_LABEL + '</span>'
    else:
        #no files submitted at all yet
        if assignment.isTooLate():
            #can't submit, so grade goes to 0
            grade = 0
            reason = '<i>Too late to submit.</i>'

    # print submission list header, starting with assignment grade
    print('<div class="submissionList">')
    print('<div class="assignment">')
    print('<table class="assignment"><tr><td class="assignment">')
    print('<b>' + assignment.name + '</b> &nbsp;')
    print('<small>(Due: ' + assignment.due + '. ')
    print('Total: ' + str(assignment.maxScore) + ' points.)</small></td>')
    print('<td class="grade"><b>Grade:</b> ' + str(grade) + '</td>')
    if reason:
        print('<td class="reason">' + reason + '</td>')
    print('</tr></table>')

    #list contents
    if files and brief:
        print('<ul>')
    for f in files:
        if brief:
            if master:
                print('<li><a href="masterview.py?submission=' + 
                      os.path.basename(f) + '"', end='')
                if tamarin.MASTER_LINKS_OPEN_NEW_WINDOW:
                    print(' target="_blank"', end='')
                print('>' + os.path.basename(f) + '</a>', end=' ') 
            else:
                print('<li><input type="submit" name="submission" value="' + 
                      os.path.basename(f) + '">', end=' ')
            if tamarin.SUBMITTED_ROOT in f:
                print('&nbsp; [<i>Not yet graded.</i>]')
            else:
                graded = GradedFile(os.path.basename(f))
                shortGrade = str(graded.grade)
                if not graded.humanVerified:
                    shortGrade += tamarin.SHORT_UNVERIFIED_GRADE_LABEL
                if graded.humanComment:
                    shortGrade += tamarin.HUMAN_COMMENT_LABEL
                print('&nbsp; [' + shortGrade + ']')
        else:
            displaySubmission(os.path.basename(f), master)
          
    #list footer
    if files and brief:
        print('</ul>')
    print('</div></div>')
Exemple #4
0
def displayGradeSheet(comma=False):
    """
    Produces a grade sheet view for all users and assignments.
    
    Rows correspond to users, sorted by username.  Rows contain the Tamarin 
    adjusted scores for each assignment followed by the total adjusted score. 
    
    By default, uses tabs as delimiters, with the user column padded to 14 
    characters to maintain a readable format even when faced with slightly 
    longer usernames.  If comma is True, just uses commas and no padding. 

    Unverified grades (and any totals depending on them) are marked
    with an appended ?. 
    
    Missing/unsubmitted grades are left blank.  Submitted but ungraded
    submissions are ignored (so blank if no other submissions for that 
    assignment).
    
    The total score is the sum of all numeric values, ignoring any 
    OK, X, or ERR grades.  If there are no numeric values, the total
    is ERR, X, or OK (in that order) if such a value is a component grade.
    Otherwise, the total is blank.  If at least one score is 
    tentative (unverified), the total is also tentative.

    """
    users = tamarin.getUsers()
    delim = ',' if comma else '\t'
    
    # build data structure 
    sheet = dict()
    for user in users:
        sheet[user] = {}  # scores keyed by assignment name
    
    # now process each assignment
    assignments = tamarin.getAssignments()  # already sorted
    for assign in assignments:
        subs = tamarin.getSubmissions(assignment=assign, submitted=False)
        # overwrite until last sub for each user, keyed by lower username
        submissions = {}
        for sub in subs:
            sub = os.path.basename(sub)
            usr = re.match(r"(\w+)" + assign, sub).group(1).lower()
            submissions[usr] = sub
        
        for user in users:
            if user in submissions:
                sub = GradedFile(submissions[user])
                grd = sub.getAdjustedGrade()

                # add to total grade list: (grade, verified?)
                if 'Total' not in sheet[user]:
                    sheet[user]['Total'] = [grd, True]
                elif isinstance(grd, float) or isinstance(grd, int):
                    # grd is a number, so overwrite/adds to whatever is there
                    if isinstance(sheet[user]['Total'][0], str):
                        sheet[user]['Total'][0] = grd
                    else:
                        sheet[user]['Total'][0] += grd
                else:
                    # grd is a string, so maybe replace any str or else ignore
                    if isinstance(sheet[user]['Total'][0], str):
                        if sheet[user]['Total'][0] == 'OK':
                            sheet[user]['Total'][0] = grd
                        elif sheet[user]['Total'][0] == 'X' and grd != 'OK':
                            sheet[user]['Total'][0] = grd
                        else:
                            pass  # grade is already ERR
                    else:
                        pass  # grade is a number, so ignore this string grd

                grd = str(grd)
                if not sub.humanVerified:
                    grd += '?'
                    sheet[user]['Total'][1] = False
                sheet[user][assign] = grd 
            else:
                sheet[user][assign] = ''  # blank
            
    # print details    
    # header
    print(',' if comma else '{:14}\t'.format(' '), end='')
    for assign in assignments:
        print(assign + delim, end='')
    print('Total')

    for user in users:
        print(user + ',' if comma else '{:14}\t'.format(user), end='')
        for assign in assignments:
            print(sheet[user][assign] + delim, end='')
        # print final total
        if 'Total' in sheet[user]:
            if isinstance(sheet[user]['Total'][0], float):
                sheet[user]['Total'][0] = round(sheet[user]['Total'][0], 
                                                tamarin.GRADE_PRECISION)
            print(sheet[user]['Total'][0], end='')
            if not sheet[user]['Total'][1]:
                print('?', end='')
        print('')