Пример #1
0
def grader_validate_rubrics(ctx, course, grader_id, assignment_id, only):
    grader = course.get_grader(grader_id)
    if not grader:
        print "Grader %s does not exist" % grader_id
        ctx.exit(CHISUBMIT_FAIL)

    assignment = course.get_assignment(assignment_id)
    if not assignment:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment, grader = grader, only = only)
    
    for team in teams:

        repo = GradingGitRepo.get_grading_repo(ctx.obj['config'], course, team, assignment)
        if not repo:
            print "Repository for %s does not exist" % (team.id)
            ctx.exit(CHISUBMIT_FAIL)
    
        rubricfile = repo.repo_path + "/%s.rubric.txt" % assignment.id
    
        if not os.path.exists(rubricfile):
            print "Repository for %s does not exist have a rubric for assignment %s" % (team.id, assignment.id)
            ctx.exit(CHISUBMIT_FAIL)
    
        try:
            RubricFile.from_file(open(rubricfile), assignment)
            print "%s: Rubric OK." % team.id
        except ChisubmitRubricException, cre:
            print "%s: Rubric ERROR: %s" % (team.id, cre.message)
Пример #2
0
def grader_create_local_grading_repos(ctx, course, grader_id, assignment_id):
    grader = course.get_grader(grader_id)
    if not grader:
        print "Grader %s does not exist" % grader_id
        ctx.exit(CHISUBMIT_FAIL)

    assignment = course.get_assignment(assignment_id)
    if not assignment:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment, grader = grader)

    if not teams:
        print "No teams found"
        ctx.exit(CHISUBMIT_FAIL)

    repos = create_grading_repos(ctx.obj['config'], course, assignment, teams)

    if not repos:
        print "There was some kind of problem creating the grading repos."
        ctx.exit(CHISUBMIT_FAIL)

    for repo in repos:
        repo.set_grader_author()

    for team in teams:
        print ("Pulling grading branch for team %s... " % team.id),
        gradingrepo_pull_grading_branch(ctx.obj['config'], course, team, assignment, from_staging = True)
        print "done"
        
    return CHISUBMIT_SUCCESS
Пример #3
0
def grader_validate_rubrics(ctx, course, grader_id, assignment_id, only):
    grader = course.get_grader(grader_id)
    if not grader:
        print "Grader %s does not exist" % grader_id
        ctx.exit(CHISUBMIT_FAIL)

    assignment = course.get_assignment(assignment_id)
    if not assignment:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment, grader=grader, only=only)

    for team in teams:

        repo = GradingGitRepo.get_grading_repo(ctx.obj['config'], course, team,
                                               assignment)
        if not repo:
            print "Repository for %s does not exist" % (team.id)
            ctx.exit(CHISUBMIT_FAIL)

        rubricfile = repo.repo_path + "/%s.rubric.txt" % assignment.id

        if not os.path.exists(rubricfile):
            print "Repository for %s does not exist have a rubric for assignment %s" % (
                team.id, assignment.id)
            ctx.exit(CHISUBMIT_FAIL)

        try:
            RubricFile.from_file(open(rubricfile), assignment)
            print "%s: Rubric OK." % team.id
        except ChisubmitRubricException, cre:
            print "%s: Rubric ERROR: %s" % (team.id, cre.message)
Пример #4
0
def instructor_grading_add_rubrics(ctx, course, assignment_id, commit,
                                   all_teams):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment, only_ready_for_grading=not all_teams)

    for team in teams:
        repo = GradingGitRepo.get_grading_repo(ctx.obj['config'], course, team,
                                               assignment)
        team_assignment = team.get_assignment(assignment_id)
        rubric = RubricFile.from_assignment(assignment, team_assignment)
        rubricfile = "%s.rubric.txt" % assignment.id
        rubricfilepath = "%s/%s" % (repo.repo_path, rubricfile)

        if commit:
            if not os.path.exists(rubricfilepath):
                rubric.save(rubricfilepath, include_blank_comments=True)
                rv = repo.commit([rubricfile], "Added grading rubric")
                if rv:
                    print rubricfilepath, "(COMMITTED)"
                else:
                    print rubricfilepath, "(NO CHANGES - Not committed)"
            else:
                print rubricfilepath, "(SKIPPED - already exists)"
        else:
            rubric.save(rubricfilepath, include_blank_comments=True)
            print rubricfilepath
Пример #5
0
def grader_pull_grading_branches(ctx, course, grader_id, assignment_id, only):
    grader = course.get_grader(grader_id)
    if not grader:
        print "Grader %s does not exist" % grader_id
        ctx.exit(CHISUBMIT_FAIL)

    assignment = course.get_assignment(assignment_id)
    if not assignment:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course,
                      assignment,
                      grader=grader,
                      only=only,
                      only_ready_for_grading=True)

    if not teams:
        ctx.exit(CHISUBMIT_FAIL)

    for team in teams:
        print "Pulling grading branch for team %s... " % team.id
        gradingrepo_pull_grading_branch(ctx.obj['config'],
                                        course,
                                        team,
                                        assignment,
                                        from_staging=True)

    return CHISUBMIT_SUCCESS
Пример #6
0
def instructor_grading_list_submissions(ctx, course, assignment_id):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment)
    teams.sort(key=operator.attrgetter("id"))

    conn = create_connection(course, ctx.obj['config'])
    
    if conn is None:
        print "Could not connect to git server."
        ctx.exit(CHISUBMIT_FAIL)

    for team in teams:
        ta = team.get_assignment(assignment.id)

        if ta.submitted_at is None:
            print "%25s NOT SUBMITTED" % team.id
        else:
            submission_commit = conn.get_commit(course, team, ta.commit_sha)
            if submission_commit is not None:
                if team.has_assignment_ready_for_grading(assignment):
                    print "%25s SUBMITTED (READY for grading)" % team.id
                else:
                    print "%25s SUBMITTED (NOT READY for grading)" % team.id
            else:
                print "%25s ERROR: Submitted but commit %s not found in repository" % (team.id, ta.commit_sha)
    
    return CHISUBMIT_SUCCESS
Пример #7
0
def instructor_grading_add_rubrics(ctx, course, assignment_id, commit, all_teams):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment, only_ready_for_grading=not all_teams)

    for team in teams:
        repo = GradingGitRepo.get_grading_repo(ctx.obj['config'], course, team, assignment)
        team_assignment = team.get_assignment(assignment_id)
        rubric = RubricFile.from_assignment(assignment, team_assignment)
        rubricfile = "%s.rubric.txt" % assignment.id
        rubricfilepath = "%s/%s" % (repo.repo_path, rubricfile)
        
        if commit:
            if not os.path.exists(rubricfilepath):
                rubric.save(rubricfilepath, include_blank_comments=True)
                rv = repo.commit([rubricfile], "Added grading rubric")
                if rv:
                    print rubricfilepath, "(COMMITTED)"
                else:
                    print rubricfilepath, "(NO CHANGES - Not committed)"
            else:
                print rubricfilepath, "(SKIPPED - already exists)"
        else:
            rubric.save(rubricfilepath, include_blank_comments=True)
            print rubricfilepath
Пример #8
0
def instructor_grading_push_grading_branches(ctx, course, assignment_id,
                                             to_staging, to_students,
                                             all_teams, only):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course,
                      assignment,
                      only=only,
                      only_ready_for_grading=not all_teams)

    if teams is None:
        ctx.exit(CHISUBMIT_FAIL)

    for team in teams:
        print("Pushing grading branch for team %s... " % team.id),
        gradingrepo_push_grading_branch(ctx.obj['config'],
                                        course,
                                        team,
                                        assignment,
                                        to_staging=to_staging,
                                        to_students=to_students)
        print "done."

    return CHISUBMIT_SUCCESS
Пример #9
0
def instructor_grading_list_grader_assignments(ctx, course, assignment_id, grader_id):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    if grader_id is not None:
        grader = course.get_grader(grader_id)
        if grader is None:
            print "Grader %s does not exist" % grader_id
            ctx.exit(CHISUBMIT_FAIL)
    else:
        grader = None

    teams = get_teams(course, assignment)
    teams.sort(key=operator.attrgetter("id"))

    for t in teams:
        team_assignment = t.get_assignment(assignment.id)
        if grader is None:
            if team_assignment.grader is None:
                grader_str = "<no-grader-assigned>"
            else:
                grader_str = team_assignment.grader.id
            print t.id, grader_str
        else:
            if grader == team_assignment.grader:
                print t.id

    return CHISUBMIT_SUCCESS
Пример #10
0
def instructor_grading_create_grading_branches(ctx, course, assignment_id,
                                               all_teams, only):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course,
                      assignment,
                      only=only,
                      only_ready_for_grading=not all_teams)

    if teams is None:
        ctx.exit(CHISUBMIT_FAIL)

    for team in teams:
        repo = GradingGitRepo.get_grading_repo(ctx.obj['config'], course, team,
                                               assignment)

        if repo is None:
            print "%s does not have a grading repository" % team.id
            continue

        ta = team.get_assignment(assignment.id)

        if ta.submitted_at is None:
            print "Skipping grading branch. %s has not submitted." % team.id
        elif repo.has_grading_branch():
            print "Skipping grading branch. %s already has a grading branch." % team.id
        else:
            repo.create_grading_branch()
            print "Created grading branch for %s" % team.id

    return CHISUBMIT_SUCCESS
Пример #11
0
def instructor_grading_list_submissions(ctx, course, assignment_id):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment)
    teams.sort(key=operator.attrgetter("id"))

    conn = create_connection(course, ctx.obj['config'])

    if conn is None:
        print "Could not connect to git server."
        ctx.exit(CHISUBMIT_FAIL)

    for team in teams:
        ta = team.get_assignment(assignment.id)

        if ta.submitted_at is None:
            print "%25s NOT SUBMITTED" % team.id
        else:
            submission_commit = conn.get_commit(course, team, ta.commit_sha)
            if submission_commit is not None:
                if team.has_assignment_ready_for_grading(assignment):
                    print "%25s SUBMITTED (READY for grading)" % team.id
                else:
                    print "%25s SUBMITTED (NOT READY for grading)" % team.id
            else:
                print "%25s ERROR: Submitted but commit %s not found in repository" % (
                    team.id, ta.commit_sha)

    return CHISUBMIT_SUCCESS
Пример #12
0
def instructor_grading_list_grader_assignments(ctx, course, assignment_id,
                                               grader_id):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    if grader_id is not None:
        grader = course.get_grader(grader_id)
        if grader is None:
            print "Grader %s does not exist" % grader_id
            ctx.exit(CHISUBMIT_FAIL)
    else:
        grader = None

    teams = get_teams(course, assignment)
    teams.sort(key=operator.attrgetter("id"))

    for t in teams:
        team_assignment = t.get_assignment(assignment.id)
        if grader is None:
            if team_assignment.grader is None:
                grader_str = "<no-grader-assigned>"
            else:
                grader_str = team_assignment.grader.id
            print t.id, grader_str
        else:
            if grader == team_assignment.grader:
                print t.id

    return CHISUBMIT_SUCCESS
Пример #13
0
def instructor_grading_create_grading_branches(ctx, course, assignment_id, all_teams, only):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment, only = only, only_ready_for_grading=not all_teams)

    if teams is None:
        ctx.exit(CHISUBMIT_FAIL)

    for team in teams:
        repo = GradingGitRepo.get_grading_repo(ctx.obj['config'], course, team, assignment)

        if repo is None:
            print "%s does not have a grading repository" % team.id
            continue
        
        ta = team.get_assignment(assignment.id)

        if ta.submitted_at is None:
            print "Skipping grading branch. %s has not submitted." % team.id
        elif repo.has_grading_branch():
            print "Skipping grading branch. %s already has a grading branch." % team.id
        else:
            repo.create_grading_branch()
            print "Created grading branch for %s" % team.id

    return CHISUBMIT_SUCCESS
Пример #14
0
def instructor_team_pull_repos(ctx, course, assignment_id, directory, only_ready_for_grading, reset, only):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    conn = create_connection(course, ctx.obj['config'])
    
    if conn is None:
        print "Could not connect to git server."
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment, only = only)

    directory = os.path.expanduser(directory)
    
    if not os.path.exists(directory):
        os.makedirs(directory)

    max_len = max([len(t.id) for t in teams])

    for team in sorted([t for t in teams if t.active], key=operator.attrgetter("id")):
        team_dir = "%s/%s" % (directory, team.id)
        team_git_url = conn.get_repository_git_url(course, team) 
        ta = team.get_assignment(assignment.id)

        if not team.has_assignment_ready_for_grading(assignment) and only_ready_for_grading:
            print "%-*s  SKIPPING (not ready for grading)" % (max_len, team.id)
            continue
        
        try:
            msg = ""
            if not os.path.exists(team_dir):
                r = LocalGitRepo.create_repo(team_dir, clone_from_url=team_git_url)
                msg = "Cloned repo"
            else:
                r = LocalGitRepo(team_dir)
                if reset:
                    r.fetch("origin")
                    r.reset_branch("origin", "master")
                    msg = "Reset to match origin/master" 
                else:
                    if r.repo.is_dirty():
                        print "%-*s  ERROR: Cannot pull. Local repository has unstaged changes." % (max_len, team.id)
                        continue
                    r.checkout_branch("master")
                    r.pull("origin", "master")
                    msg = "Pulled latest changes"
            if only_ready_for_grading:
                r.checkout_commit(ta.commit_sha)
                msg += " and checked out commit %s" % (ta.commit_sha)               
            print "%-*s  %s" % (max_len, team.id, msg)
        except ChisubmitException, ce:
            print "%-*s  ERROR: Could not checkout or pull master branch (%s)" % (max_len, team.id, ce.message)
        except GitCommandError, gce:
            print "%-*s  ERROR: Could not checkout or pull master branch" % (max_len, team.id)
            print gce
Пример #15
0
def instructor_grading_show_grading_status(ctx, course, assignment_id,
                                           by_grader):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment)
    teams.sort(key=operator.attrgetter("id"))

    team_status = []
    graders = set()

    for team in teams:
        ta = team.get_assignment(assignment_id)
        grade_ids = [g.grade_component_id for g in ta.grades]

        if ta.grader is not None:
            grader_id = ta.grader.id
        else:
            grader_id = "<no grader assigned>"

        graders.add(grader_id)

        has_some = False
        has_all = True
        for gc in assignment.grade_components:
            if gc.id in grade_ids:
                has_some = True
            else:
                has_all = False

        if not has_some:
            team_status.append((team.id, grader_id, "NOT GRADED"))
        elif has_all:
            team_status.append((team.id, grader_id, "GRADED"))
        else:
            team_status.append((team.id, grader_id, "PARTIALLY GRADED"))

    if not by_grader:
        for team, grader, status in team_status:
            print "%-40s %-20s %s" % (team, status, grader)
    else:
        for grader in sorted(list(graders)):
            print grader
            print "-" * len(grader)

            team_status_grader = [ts for ts in team_status if ts[1] == grader]

            for team, _, status in team_status_grader:
                print "%-40s %s" % (team, status)

            print

    return CHISUBMIT_SUCCESS
Пример #16
0
def instructor_grading_show_grading_status(ctx, course, assignment_id, by_grader):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment)
    teams.sort(key=operator.attrgetter("id"))
    
    team_status = []
    graders = set()
    
    for team in teams:
        ta = team.get_assignment(assignment_id)
        grade_ids = [g.grade_component_id for g in ta.grades]

        if ta.grader is not None:
            grader_id = ta.grader.id
        else:
            grader_id = "<no grader assigned>"
            
        graders.add(grader_id)

        has_some = False
        has_all = True
        for gc in assignment.grade_components:
            if gc.id in grade_ids:
                has_some = True
            else:
                has_all = False

        if not has_some:
            team_status.append((team.id, grader_id, "NOT GRADED"))
        elif has_all:
            team_status.append((team.id, grader_id, "GRADED"))
        else:
            team_status.append((team.id, grader_id, "PARTIALLY GRADED"))

    if not by_grader:
        for team, grader, status in team_status:
            print "%-40s %-20s %s" % (team, status, grader)
    else:
        for grader in sorted(list(graders)):
            print grader
            print "-" * len(grader)
            
            team_status_grader = [ts for ts in team_status if ts[1] == grader]
            
            for team, _, status in team_status_grader:
                print "%-40s %s" % (team, status)

            print

    return CHISUBMIT_SUCCESS
Пример #17
0
def instructor_grading_create_grading_repos(ctx, course, assignment_id, all_teams):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment, only_ready_for_grading=not all_teams)

    repos = create_grading_repos(ctx.obj['config'], course, assignment, teams)

    if repos == None:
        ctx.exit(CHISUBMIT_FAIL)

    return CHISUBMIT_SUCCESS
Пример #18
0
def instructor_grading_create_grading_repos(ctx, course, assignment_id,
                                            all_teams):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment, only_ready_for_grading=not all_teams)

    repos = create_grading_repos(ctx.obj['config'], course, assignment, teams)

    if repos == None:
        ctx.exit(CHISUBMIT_FAIL)

    return CHISUBMIT_SUCCESS
Пример #19
0
def instructor_grading_pull_grading_branches(ctx, course, assignment_id, from_staging, from_students, only):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment, only = only)

    if teams is None:
        ctx.exit(CHISUBMIT_FAIL)

    for team in teams:
        print "Pulling grading branch for team %s... " % team.id
        gradingrepo_pull_grading_branch(ctx.obj['config'], course, team, assignment, from_staging = from_staging, from_students = from_students)

    return CHISUBMIT_SUCCESS
Пример #20
0
def instructor_grading_push_grading_branches(ctx, course, assignment_id, to_staging, to_students, all_teams, only):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment, only = only, only_ready_for_grading=not all_teams)

    if teams is None:
        ctx.exit(CHISUBMIT_FAIL)

    for team in teams:
        print ("Pushing grading branch for team %s... " % team.id),
        gradingrepo_push_grading_branch(ctx.obj['config'], course, team, assignment, to_staging = to_staging, to_students = to_students)
        print "done."

    return CHISUBMIT_SUCCESS
Пример #21
0
def grader_pull_grading_branches(ctx, course, grader_id, assignment_id, only):
    grader = course.get_grader(grader_id)
    if not grader:
        print "Grader %s does not exist" % grader_id
        ctx.exit(CHISUBMIT_FAIL)

    assignment = course.get_assignment(assignment_id)
    if not assignment:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment, grader = grader, only = only, only_ready_for_grading=True)

    if not teams:
        ctx.exit(CHISUBMIT_FAIL)

    for team in teams:
        print "Pulling grading branch for team %s... " % team.id
        gradingrepo_pull_grading_branch(ctx.obj['config'], course, team, assignment, from_staging = True)

    return CHISUBMIT_SUCCESS
Пример #22
0
def instructor_grading_pull_grading_branches(ctx, course, assignment_id,
                                             from_staging, from_students,
                                             only):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment, only=only)

    if teams is None:
        ctx.exit(CHISUBMIT_FAIL)

    for team in teams:
        print "Pulling grading branch for team %s... " % team.id
        gradingrepo_pull_grading_branch(ctx.obj['config'],
                                        course,
                                        team,
                                        assignment,
                                        from_staging=from_staging,
                                        from_students=from_students)

    return CHISUBMIT_SUCCESS
Пример #23
0
def grader_create_local_grading_repos(ctx, course, grader_id, assignment_id):
    grader = course.get_grader(grader_id)
    if not grader:
        print "Grader %s does not exist" % grader_id
        ctx.exit(CHISUBMIT_FAIL)

    assignment = course.get_assignment(assignment_id)
    if not assignment:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment, grader=grader)

    if not teams:
        print "No teams found"
        ctx.exit(CHISUBMIT_FAIL)

    repos = create_grading_repos(ctx.obj['config'], course, assignment, teams)

    if not repos:
        print "There was some kind of problem creating the grading repos."
        ctx.exit(CHISUBMIT_FAIL)

    for repo in repos:
        repo.set_grader_author()

    for team in teams:
        print("Pulling grading branch for team %s... " % team.id),
        gradingrepo_pull_grading_branch(ctx.obj['config'],
                                        course,
                                        team,
                                        assignment,
                                        from_staging=True)
        print "done"

    return CHISUBMIT_SUCCESS
Пример #24
0
def instructor_grading_collect_rubrics(ctx, course, assignment_id, dry_run,
                                       grader_id):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    if grader_id is not None:
        grader = course.get_grader(grader_id)
        if grader is None:
            print "Grader %s does not exist" % grader_id
            ctx.exit(CHISUBMIT_FAIL)
    else:
        grader = None

    gcs = assignment.grade_components

    teams = get_teams(course, assignment, grader=grader)

    for team in teams:
        repo = GradingGitRepo.get_grading_repo(ctx.obj['config'], course, team,
                                               assignment)
        if repo is None:
            print "Repository for %s does not exist" % (team.id)
            continue

        rubricfile = repo.repo_path + "/%s.rubric.txt" % assignment.id

        if not os.path.exists(rubricfile):
            print "Repository for %s does not have a rubric for assignment %s" % (
                team.id, assignment.id)
            continue

        try:
            rubric = RubricFile.from_file(open(rubricfile), assignment)
        except ChisubmitRubricException, cre:
            print "ERROR: Rubric for %s does not validate (%s)" % (team.id,
                                                                   cre.message)
            continue

        points = []
        for gc in gcs:
            grade = rubric.points[gc.description]
            if grade is None:
                points.append(0.0)
            else:
                if not dry_run:
                    team.set_assignment_grade(assignment.id, gc.id, grade)
                points.append(grade)

        penalties = {}
        total_penalties = 0.0
        if rubric.penalties is not None:
            for desc, p in rubric.penalties.items():
                penalties[desc] = p
                total_penalties += p

        if not dry_run:
            team.set_assignment_penalties(assignment.id, penalties)

        if ctx.obj["verbose"]:
            print team.id
            print "+ %s" % points
            print "- %.2f" % total_penalties

        if not dry_run:
            new_team = course.get_team(team.id)
            assignment_team = new_team.get_assignment(assignment.id)
            total_grade = assignment_team.get_total_grade()
        else:
            total_grade = sum(points) + total_penalties

        if ctx.obj["verbose"]:
            print "TOTAL: %.2f" % total_grade
            print
        else:
            print "%-40s %.2f" % (team.id, total_grade)
Пример #25
0
def instructor_grading_assign_graders(ctx, course, assignment_id,
                                      from_assignment, avoid_assignment,
                                      only_graders, reset):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    from_assignment = None
    if from_assignment is not None:
        from_assignment = course.get_assignment(from_assignment)
        if from_assignment is None:
            print "Project %s does not exist" % from_assignment
            ctx.exit(CHISUBMIT_FAIL)

    avoid_assignment = None
    if avoid_assignment is not None:
        avoid_assignment = course.get_assignment(avoid_assignment)
        if avoid_assignment is None:
            print "Project %s does not exist" % avoid_assignment
            ctx.exit(CHISUBMIT_FAIL)

    if reset and from_assignment is not None:
        print "--reset and --from_assignment are mutually exclusive"
        ctx.exit(CHISUBMIT_FAIL)

    if avoid_assignment is not None and from_assignment is not None:
        print "--avoid_assignment and --from_assignment are mutually exclusive"
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment)
    graders = course.graders[:]

    if only_graders is None:
        graders = course.graders[:]
    else:
        gd = {g.user.id: g for g in course.graders}
        only_graders = only_graders.strip().split(",")

        graders = []
        for g in only_graders:
            if g in gd:
                graders.append(gd[g])
            else:
                print "No such grader: %s" % g
                ctx.exit(CHISUBMIT_FAIL)

    if len(graders) == 0:
        print "There are ZERO graders in this course!"
        ctx.exit(CHISUBMIT_FAIL)

    min_teams_per_grader = len(teams) / len(graders)
    extra_teams = len(teams) % len(graders)

    teams_per_grader = dict([(g.user.id, min_teams_per_grader)
                             for g in graders])
    teams_per_grader_assigned = dict([(g.user.id, 0) for g in graders])

    random.seed(course.id + assignment_id)
    random.shuffle(graders)

    # so many graders in this course that some will end up expecting zero
    # teams to grade. Make sure they are able to get at least one.
    for g in graders[:extra_teams]:
        teams_per_grader[g.user.id] += 1

    team_grader = {t.id: None for t in teams}
    ta = {t.id: t.get_assignment(assignment.id) for t in teams}

    if from_assignment is not None:
        common_teams = [
            t for t in course.teams if t.has_assignment(assignment.id)
            and t.has_assignment(from_assignment.id)
        ]
        for t in common_teams:
            team_assignment_from = t.get_assignment(from_assignment.id)

            # try to assign the same grader that would grade the same team's other assignment
            grader = team_assignment_from.grader
            if grader is not None and teams_per_grader[grader.user.id] > 0:
                team_grader[t.id] = grader.user.id
                teams_per_grader[grader.user.id] -= 1
                teams_per_grader_assigned[grader.user.id] += 1

    if not reset:
        for t in teams:
            if ta[t.id].grader is None:
                team_grader[t.id] = None
            else:
                grader_id = ta[t.id].grader.id
                team_grader[t.id] = grader_id
                teams_per_grader[grader_id] -= 1
                teams_per_grader_assigned[grader_id] += 1

    not_ready_for_grading = []
    ta_avoid = {}
    graders_cycle = itertools.cycle(graders)
    for t in teams:
        if team_grader[t.id] is not None:
            continue

        if not t.has_assignment_ready_for_grading(assignment):
            not_ready_for_grading.append(t.id)
            continue

        for g in graders_cycle:
            if teams_per_grader[g.user.id] == 0:
                continue
            else:
                if avoid_assignment is not None:
                    taa = ta_avoid.setdefault(
                        t.id, t.get_assignment(avoid_assignment.id))
                    if taa.grader.user.id == grader.user.id:
                        continue

                valid = True
                for s in t.students:
                    conflicts = g.get_conflicts()
                    if s.user.id in conflicts:
                        valid = False
                        break

                if valid:
                    team_grader[t.id] = g.user.id
                    teams_per_grader[g.user.id] -= 1
                    teams_per_grader_assigned[g.user.id] += 1
                    break

    for t in teams:
        if team_grader[t.id] is None:
            if t.id not in not_ready_for_grading:
                print "Team %s has no grader" % (t.id)
            else:
                print "Team %s's submission isn't ready for grading yet" % (
                    t.id)
        else:
            if ta[t.id].grader != team_grader[t.id]:
                t.set_assignment_grader(assignment.id, team_grader[t.id])

    print
    for grader_id, assigned in teams_per_grader_assigned.items():
        if teams_per_grader[grader_id] != 0:
            print grader_id, assigned, "(still needs to be assigned %i more assignments)" % (
                teams_per_grader[grader_id])
        else:
            print grader_id, assigned

    return CHISUBMIT_SUCCESS
Пример #26
0
def instructor_grading_assign_graders(ctx, course, assignment_id, from_assignment, avoid_assignment, only_graders, reset):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    from_assignment = None
    if from_assignment is not None:
        from_assignment = course.get_assignment(from_assignment)
        if from_assignment is None:
            print "Project %s does not exist" % from_assignment
            ctx.exit(CHISUBMIT_FAIL)

    avoid_assignment = None
    if avoid_assignment is not None:
        avoid_assignment = course.get_assignment(avoid_assignment)
        if avoid_assignment is None:
            print "Project %s does not exist" % avoid_assignment
            ctx.exit(CHISUBMIT_FAIL)

    if reset and from_assignment is not None:
        print "--reset and --from_assignment are mutually exclusive"
        ctx.exit(CHISUBMIT_FAIL)

    if avoid_assignment is not None and from_assignment is not None:
        print "--avoid_assignment and --from_assignment are mutually exclusive"
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment)
    graders = course.graders[:]
    
    if only_graders is None:
        graders = course.graders[:]
    else:
        gd = {g.user.id: g for g in course.graders}
        only_graders = only_graders.strip().split(",")
        
        graders = []
        for g in only_graders:
            if g in gd:
                graders.append(gd[g])
            else:
                print "No such grader: %s" % g
                ctx.exit(CHISUBMIT_FAIL)        
    
    if len(graders) == 0:
        print "There are ZERO graders in this course!"
        ctx.exit(CHISUBMIT_FAIL)

    min_teams_per_grader = len(teams) / len(graders)
    extra_teams = len(teams) % len(graders)

    teams_per_grader = dict([(g.user.id, min_teams_per_grader) for g in graders])
    teams_per_grader_assigned = dict([(g.user.id, 0) for g in graders])
    
    random.seed(course.id + assignment_id)
    random.shuffle(graders)

    # so many graders in this course that some will end up expecting zero
    # teams to grade. Make sure they are able to get at least one.
    for g in graders[:extra_teams]:
        teams_per_grader[g.user.id] += 1

    team_grader = {t.id: None for t in teams}
    ta = {t.id: t.get_assignment(assignment.id) for t in teams}

    if from_assignment is not None:
        common_teams = [t for t in course.teams if t.has_assignment(assignment.id) and t.has_assignment(from_assignment.id)]
        for t in common_teams:
            team_assignment_from = t.get_assignment(from_assignment.id)

            # try to assign the same grader that would grade the same team's other assignment
            grader = team_assignment_from.grader
            if grader is not None and teams_per_grader[grader.user.id] > 0:
                team_grader[t.id] = grader.user.id 
                teams_per_grader[grader.user.id] -= 1
                teams_per_grader_assigned[grader.user.id] += 1

    if not reset:
        for t in teams:
            if ta[t.id].grader is None:
                team_grader[t.id] = None
            else:
                grader_id = ta[t.id].grader.id 
                team_grader[t.id] = grader_id
                teams_per_grader[grader_id] -= 1
                teams_per_grader_assigned[grader_id] += 1

    not_ready_for_grading = []
    ta_avoid = {}
    graders_cycle = itertools.cycle(graders)
    for t in teams:
        if team_grader[t.id] is not None:
            continue
        
        if not t.has_assignment_ready_for_grading(assignment):
            not_ready_for_grading.append(t.id)
            continue

        for g in graders_cycle:
            if teams_per_grader[g.user.id] == 0:
                continue
            else:
                if avoid_assignment is not None:
                    taa = ta_avoid.setdefault(t.id, t.get_assignment(avoid_assignment.id))
                    if taa.grader.user.id == grader.user.id:
                        continue
                
                valid = True
                for s in t.students:
                    conflicts = g.get_conflicts()
                    if s.user.id in conflicts:
                        valid = False
                        break

                if valid:
                    team_grader[t.id] = g.user.id 
                    teams_per_grader[g.user.id] -= 1
                    teams_per_grader_assigned[g.user.id] += 1                        
                    break                    

    for t in teams:
        if team_grader[t.id] is None:
            if t.id not in not_ready_for_grading:
                print "Team %s has no grader" % (t.id)
            else:
                print "Team %s's submission isn't ready for grading yet" % (t.id)
        else:
            if ta[t.id].grader !=  team_grader[t.id]:
                t.set_assignment_grader(assignment.id, team_grader[t.id])

    print 
    for grader_id, assigned in teams_per_grader_assigned.items():
        if teams_per_grader[grader_id] != 0:
            print grader_id, assigned, "(still needs to be assigned %i more assignments)" % (teams_per_grader[grader_id])
        else:
            print grader_id, assigned

    return CHISUBMIT_SUCCESS
Пример #27
0
def instructor_grading_collect_rubrics(ctx, course, assignment_id, dry_run, grader_id):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    if grader_id is not None:
        grader = course.get_grader(grader_id)
        if grader is None:
            print "Grader %s does not exist" % grader_id
            ctx.exit(CHISUBMIT_FAIL)
    else:
        grader = None

    gcs = assignment.grade_components

    teams = get_teams(course, assignment, grader=grader)

    for team in teams:
        repo = GradingGitRepo.get_grading_repo(ctx.obj['config'], course, team, assignment)
        if repo is None:
            print "Repository for %s does not exist" % (team.id)
            continue

        rubricfile = repo.repo_path + "/%s.rubric.txt" % assignment.id

        if not os.path.exists(rubricfile):
            print "Repository for %s does not have a rubric for assignment %s" % (team.id, assignment.id)
            continue

        try:
            rubric = RubricFile.from_file(open(rubricfile), assignment)
        except ChisubmitRubricException, cre:
            print "ERROR: Rubric for %s does not validate (%s)" % (team.id, cre.message)
            continue

        points = []
        for gc in gcs:
            grade = rubric.points[gc.description]
            if grade is None:
                points.append(0.0)
            else:
                if not dry_run:
                    team.set_assignment_grade(assignment.id, gc.id, grade)
                points.append(grade)

        penalties = {}
        total_penalties = 0.0
        if rubric.penalties is not None:
            for desc, p in rubric.penalties.items():
                penalties[desc] = p
                total_penalties += p

        if not dry_run:
            team.set_assignment_penalties(assignment.id, penalties)

        if ctx.obj["verbose"]:
            print team.id
            print "+ %s" % points
            print "- %.2f" % total_penalties

        if not dry_run:
            new_team = course.get_team(team.id)
            assignment_team = new_team.get_assignment(assignment.id)
            total_grade = assignment_team.get_total_grade()
        else:
            total_grade = sum(points) + total_penalties
            
        if ctx.obj["verbose"]:
            print "TOTAL: %.2f" % total_grade
            print
        else:
            print "%-40s %.2f" % (team.id, total_grade)
Пример #28
0
def instructor_team_pull_repos(ctx, course, assignment_id, directory,
                               only_ready_for_grading, reset, only):
    assignment = course.get_assignment(assignment_id)
    if assignment is None:
        print "Assignment %s does not exist" % assignment_id
        ctx.exit(CHISUBMIT_FAIL)

    conn = create_connection(course, ctx.obj['config'])

    if conn is None:
        print "Could not connect to git server."
        ctx.exit(CHISUBMIT_FAIL)

    teams = get_teams(course, assignment, only=only)

    directory = os.path.expanduser(directory)

    if not os.path.exists(directory):
        os.makedirs(directory)

    max_len = max([len(t.id) for t in teams])

    for team in sorted([t for t in teams if t.active],
                       key=operator.attrgetter("id")):
        team_dir = "%s/%s" % (directory, team.id)
        team_git_url = conn.get_repository_git_url(course, team)
        ta = team.get_assignment(assignment.id)

        if not team.has_assignment_ready_for_grading(
                assignment) and only_ready_for_grading:
            print "%-*s  SKIPPING (not ready for grading)" % (max_len, team.id)
            continue

        try:
            msg = ""
            if not os.path.exists(team_dir):
                r = LocalGitRepo.create_repo(team_dir,
                                             clone_from_url=team_git_url)
                msg = "Cloned repo"
            else:
                r = LocalGitRepo(team_dir)
                if reset:
                    r.fetch("origin")
                    r.reset_branch("origin", "master")
                    msg = "Reset to match origin/master"
                else:
                    if r.repo.is_dirty():
                        print "%-*s  ERROR: Cannot pull. Local repository has unstaged changes." % (
                            max_len, team.id)
                        continue
                    r.checkout_branch("master")
                    r.pull("origin", "master")
                    msg = "Pulled latest changes"
            if only_ready_for_grading:
                r.checkout_commit(ta.commit_sha)
                msg += " and checked out commit %s" % (ta.commit_sha)
            print "%-*s  %s" % (max_len, team.id, msg)
        except ChisubmitException, ce:
            print "%-*s  ERROR: Could not checkout or pull master branch (%s)" % (
                max_len, team.id, ce.message)
        except GitCommandError, gce:
            print "%-*s  ERROR: Could not checkout or pull master branch" % (
                max_len, team.id)
            print gce