Beispiel #1
0
    def new_assignment( self, assignment_name ):

        # Create an example assignment directory and configuration files
        assignment = Assignment()
        assignment.new_assignment( self.grading_root, self.grading_master, assignment_name )

        return assignment
Beispiel #2
0
    def new_assignment(self, assignment_name):

        # Create an example assignment directory and configuration files
        assignment = Assignment()
        assignment.new_assignment(self.grading_root, self.grading_master,
                                  assignment_name)

        return assignment
Beispiel #3
0
    def __init__(self, config_file):
        '''
            Read the autograder configuration file and populate grading root
            and grading master directory names
        '''
        if not os.path.exists(config_file):
            local_config_file = os.path.join(os.getcwd(), config_file)
            if not os.path.exists(local_config_file):
                print 'Error: Autograder Configuration File {} does not exist. Exit...'.format(
                    config_file)
                sys.exit(0)
            else:
                config_file = local_config_file

        self.config_file = config_file

        config = ConfigParser.SafeConfigParser()
        config.read(self.config_file)

        try:
            # All the grading for a particular offering of a particular class happens under this director
            self.grading_root = config.get(
                AgGlobals.AUTOGRADER_CFG_SECTION,
                AgGlobals.AUTOGRADER_CFG_GRADING_ROOT)

            # This is where all the supplied files / solutions etc are kept for each project / assignment.
            # For each project / assignment, there is a separate directory in this directory
            self.grading_master = config.get(
                AgGlobals.AUTOGRADER_CFG_SECTION,
                AgGlobals.AUTOGRADER_CFG_GRADING_MASTER)
        except ConfigParser.NoSectionError as no_sec_err:
            print 'Error: {} in autograder configuration file {}. Exiting...'.format(
                no_sec_err, self.config_file)
            sys.exit()
        except ConfigParser.NoOptionError as no_op_err:
            print 'Error: {} in autograder configuration file {}. Exiting...'.format(
                no_op_err, self.config_file)
            sys.exit()

        if not self.grading_root:
            print 'Error: Empty grading root. Exit...'
            sys.exit()

        if not self.grading_master:
            print 'Error: Empty grading master. Exit...'
            sys.exit()

        self.students_dict = OrderedDict()

        self.asmnt = Assignment()

        self.students_directory = AgGlobals.STUDENTS_DIRECTORY  # self.agg.get_students_directory()
        self.grading_directory = AgGlobals.GRADING_DIRECTORY  # self.agg.get_grading_directory()

        self.ag_state = AgGlobals.AG_STATE_CREATED
Beispiel #4
0
 def completeSubproblem(self, assignment: Assignment, sub: CSP) -> CSP:
     """
     Given a subproblem created with cheap method, it completes it adding new unary constraints in base to the assignment
     :param assignment: already assigned variables
     :param sub: subproblem
     :return: sub-CSP
     """
     assignment = assignment.getAssignment()
     for var in set(assignment.keys()) & self._binaryConstraints.keys(
     ):  # for every binary constraints involving assigned variable, add unary constraint for the other variable involved
         for var2 in set(self._binaryConstraints[var]) & sub.getVariables():
             sub.addUnaryConstraint(
                 var2, self._binaryConstraints[var][var2][0].getDual(),
                 assignment[var])
     return sub
Beispiel #5
0
 def assignmentConsistencyForVar(self, assignment: Assignment,
                                 var: Variable) -> bool:
     """
     Check if a var assignment is consistent or not (in relation to other variable already assigned)
     :param assignment: assignment to check for consistency
     :param var: var to check for assignment
     :return: True if it is consistent, False otherwise
     """
     assignment = assignment.getAssignment()
     assignedValue = assignment[var]
     if assignedValue not in var.getActualDomain():
         return False
     if var in self._unaryConstraints:
         for value in self._unaryConstraints[var]:
             if not self._unaryConstraints[var][value][0](assignedValue,
                                                          value):
                 return False
     if var in self._binaryConstraints:
         for var2 in assignment:
             if var2 is not var:
                 if var2 in self._binaryConstraints[var]:
                     if not self._binaryConstraints[var][var2][0](
                             assignedValue, assignment[var2]):
                         return False
     return True
Beispiel #6
0
 def Assignment(self):
     id = self.Identifier()
     if self.peek().type == "DOT":
         self.expect("DOT")
         cmd = self.Command()
         # Create new Assign instance and return it
         return Assignment(id, cmd=cmd)
     elif self.peek().type == "ASSIGN":
         self.expect("ASSIGN")
         expr = self.Expression()
         # Create new Assign instance and return it
         return Assignment(id, expr=expr)
     elif self.peek().type == "LPAREN":
         self.expect("LPAREN")
         args = self.List()
         self.expect("RPAREN")
         return FunctionCall(id, args)
     else:
         raise Exception("Expected command or assignment")
    def reload_assignments(self):
        self.assignment_dict.clear()
        GlobalVariables.database.cursor.execute("SELECT * FROM `" +
                                                self.tableName + "`")
        results = GlobalVariables.database.cursor.fetchall()

        # Go through each row
        for row in results:
            assignment = Assignment(row[0], row[1], row[2], self.student_list)
            self.assignment_dict[row[0]] = copy.deepcopy(assignment)
Beispiel #8
0
def add(update, context):
    assignment = Assignment(context.args[0],
                            parser.parse(" ".join(context.args[1:])))
    if assignment_key not in context.chat_data.keys():
        context.chat_data[assignment_key] = Assignments()
    if locale_key not in context.chat_data.keys():
        context.chat_data[locale_key] = update.effective_user.language_code
    context.chat_data.get(assignment_key).add(assignment)
    reply_message = "{}\nsuccessfully added.".format(str(assignment))
    context.bot.send_message(chat_id=update.effective_chat.id,
                             text=reply_message)
    def parse(self, raw_obj):
        self.start_date = raw_obj["startDate"]
        self.end_date = raw_obj["endDate"]
        self.week_no = raw_obj["weekNo"]
        self.order_timestamp_long = raw_obj["orderTimestampLong"]

        self.assignments = []
        # Lisame kõik kodutood jarjendisse
        for event in raw_obj["eventList"]:
            event = Assignment(event)
            self.assignments.append(event)
Beispiel #10
0
    def subproblem(self,
                   assignment: Assignment,
                   *,
                   cheap: bool = False) -> CSP:
        """
        Given a (partial) assignment, it returns a csp with all unassigned variables and the new constraints to be satisfied in order to be consistent with original problem
        :param assignment: already assigned variables
        :param cheap: if True it doesn't set new unary constraint in order to save computation
        :return: sub-CSP
        """
        csp = CSP()
        assignment = assignment.getAssignment()
        for var in self._variables - assignment.keys(
        ):  # copy all remaining variables
            csp.addVariable(var)
        for var in set(self._unaryConstraints) & csp.getVariables(
        ):  # copy unary constraints involving remaining variables
            for value in self._unaryConstraints[var]:
                csp.addUnaryConstraint(var,
                                       self._unaryConstraints[var][value][0],
                                       value)
        for var in set(self._binaryConstraints) & csp.getVariables(
        ):  # copy binary constraints involving remaining variables
            for var2 in set(self._binaryConstraints[var]) & csp.getVariables():
                csp.addBinaryConstraint(var,
                                        self._binaryConstraints[var][var2][0],
                                        var2)

        if not cheap:
            for var in set(assignment.keys()) & self._binaryConstraints.keys(
            ):  # for every binary constraints involving assigned variable, add unary constraint for the other variable involved
                for var2 in set(
                        self._binaryConstraints[var]) & csp.getVariables():
                    csp.addUnaryConstraint(
                        var2, self._binaryConstraints[var][var2][0].getDual(),
                        assignment[var])

        return csp
Beispiel #11
0
def main():

    # construct assignment object
    assign = Assignment(foldername)
    # set grading function
    assign.setGradeFunc(grade)

    # execute grading function to each submission
    print "Grading " + foldername + "..."
    assign.grade()

    # commit grading to grades.csv file
    print "Commiting " + foldername + "..."
    assign.commit()

    print "Finished! Please upload the result to classesv2."
Beispiel #12
0
 def intake_assignment(self):
     # Add assignment to list
     # Need to check for illegal or missing values
     self.assignment_list.append(Assignment(subject=self.var.get(), days=self.days_till_due_field.get(),
                                            time=self.time_to_complete_field.get(), diff=self.difficulty_field.get(),
                                            priority=None, descrip=self.description_field.get()))
     # Reset dialogues
     self.time_to_complete_field.delete(0, 'end')
     self.description_field.delete(0, 'end')
     self.days_till_due_field.set(1)
     self.difficulty_field.set(1)
     self.description_field.insert(index=END, string="Description")
     self.time_to_complete_field.insert(index=END, string="Time")
     self.var.set("Subject")
Beispiel #13
0
    def __init__( self, config_file ):
        '''
            Read the autograder configuration file and populate grading root
            and grading master directory names
        '''
        if not os.path.exists( config_file ):
            local_config_file = os.path.join( os.getcwd(), config_file )
            if not os.path.exists( local_config_file ):
                print 'Error: Autograder Configuration File {} does not exist. Exit...'.format( config_file )
                sys.exit( 0 )
            else:
                config_file = local_config_file

        self.config_file = config_file

        config = ConfigParser.SafeConfigParser()
        config.read( self.config_file )

        try:
            # All the grading for a particular offering of a particular class happens under this director
            self.grading_root = config.get( AgGlobals.AUTOGRADER_CFG_SECTION, AgGlobals.AUTOGRADER_CFG_GRADING_ROOT )

            # This is where all the supplied files / solutions etc are kept for each project / assignment.
            # For each project / assignment, there is a separate directory in this directory
            self.grading_master = config.get( AgGlobals.AUTOGRADER_CFG_SECTION, AgGlobals.AUTOGRADER_CFG_GRADING_MASTER )
        except ConfigParser.NoSectionError as no_sec_err:
            print 'Error: {} in autograder configuration file {}. Exiting...'.format( no_sec_err, self.config_file )
            sys.exit()
        except ConfigParser.NoOptionError as no_op_err:
            print 'Error: {} in autograder configuration file {}. Exiting...'.format( no_op_err, self.config_file )
            sys.exit()

        if not self.grading_root:
            print 'Error: Empty grading root. Exit...'
            sys.exit()

        if not self.grading_master:
            print 'Error: Empty grading master. Exit...'
            sys.exit()

        self.students_dict = OrderedDict()

        self.asmnt = Assignment()

        self.students_directory = AgGlobals.STUDENTS_DIRECTORY  # self.agg.get_students_directory()
        self.grading_directory = AgGlobals.GRADING_DIRECTORY  # self.agg.get_grading_directory()

        self.ag_state = AgGlobals.AG_STATE_CREATED
    def add_assignment(self, assignment_uuid, assignment_name, total_points,
                       student_list):
        assignment = Assignment(assignment_uuid, assignment_name, total_points,
                                student_list)

        GlobalVariables.database.connection.execute("INSERT INTO `" +
                                                    str(self.tableName) +
                                                    "` VALUES('" +
                                                    str(assignment_uuid) +
                                                    "', '" +
                                                    str(assignment_name) +
                                                    "', '" +
                                                    str(total_points) + "')")
        GlobalVariables.database.connection.commit()

        self.reload_assignments()
Beispiel #15
0
def main():

    
    # construct assignment object
    assign = Assignment(foldername)
    # set grading function
    assign.setGradeFunc(grade)

    # execute grading function to each submission
    print "Grading " + foldername + "..."
    assign.grade()

    # commit grading to grades.csv file
    print "Commiting " + foldername + "..."
    assign.commit()

    print "Finished! Please upload the result to classesv2."
Beispiel #16
0
    def getAssignments(self):
        assignments = []
        r = requests.get(
            "https://stjohnsprep.instructure.com/api/v1/courses/%s/assignments?access_token=%s"
            % (self.id, self.token)).json()
        for assignment in r:
            assignment_id = assignment["id"]
            assignment_name = assignment["name"]
            assignment_description = assignment["description"]
            assignment_created_at = assignment["created_at"]
            assignment_updated_at = assignment["updated_at"]
            assignment_due_at = assignment["due_at"]

            assignments.append(
                Assignment(self.token, assignment_id, assignment_name,
                           assignment_description, assignment_created_at,
                           assignment_updated_at, assignment_due_at))

        return assignments
Beispiel #17
0
 def assignmentConsistency(self, assignment: Assignment) -> bool:
     """
     Check if an assignment is consistent or not
     :param assignment: assignment to check for consistency
     :return: True if it is consistent, False otherwise
     """
     assignment = assignment.getAssignment()
     for var in assignment:
         assignedValue = assignment[var]
         if assignedValue not in var.getActualDomain():
             return False
         if var in self._unaryConstraints:
             for value in self._unaryConstraints[var]:
                 if not self._unaryConstraints[var][value][0](assignedValue,
                                                              value):
                     return False
         if var in self._binaryConstraints:
             for var2 in assignment:
                 if var2 is not var:
                     if var2 in self._binaryConstraints[var]:
                         if not self._binaryConstraints[var][var2][0](
                                 assignedValue, assignment[var2]):
                             return False
     return True
Beispiel #18
0
def create_assignment(assignment, assignment_id, due_date):
  a = Assignment(assignment, assignment_id, due_date)
  return a.print_assignment_subheader()
Beispiel #19
0
if __name__ == "__main__":

    # Loading configuration
    pd.set_option('display.float_format', lambda x: '%.0f' % x)
    args = get_config()

    # First Step
    first_step = DataGeneration(args)
    zones_athens = first_step.get_examined_zones()
    trip_generation = first_step.get_trip_generation()
    print(trip_generation)

    # Second Step
    second_step = TripDistribution(zones_athens)
    try:
        cost_matrix = pd.read_csv('data/tables/DistanceTableAthens.csv',
                                  header=None)
    except:
        second_step.cost_matrix()
        cost_matrix = pd.read_csv('data/tables/DistanceTableAthens.csv',
                                  header=None)

    cost_matrix.index = zones_athens.NAME
    cost_matrix.columns = zones_athens.NAME
    trips = second_step.gravity_model(trip_generation, cost_matrix)
    print(trips)

    #Third Step
    third_step = Assignment(zones_athens, trips, cost_matrix)
    G = third_step.route_assignement()
    third_step.visualize(G)
Beispiel #20
0
import time
from Assignment import Assignment
from Course import Course

calculus = Course("Calculus",90)
calculus.currGPA = 90
mathHW = Assignment(calculus,"homework","hw 3") # course, category, name
calculus.addAssignment(mathHW)

english = Course("English",95)
english.currGPA = 95
englishHW = Assignment(english,"homework","hw 1")
english.addAssignment(english)

mathHW.upcomingAssign(95,"03/01/16") # goal grade, deadline
englishHW.upcomingAssign(100,"03/03/16")

print mathHW.compare(englishHW).name # get the name of the assignment
										# with the higher priority

calculus.setGradeDist(90, 90, 90, 90)
 def Assign(self):
     var = self.getId()
     tok = self.lex.getNextToken()
     self.match(tok, "ASSIGN_TOK")
     expr = self.getExpression()
     Assignment(var, expr).execute()
Beispiel #22
0
    def parseCommand():
        if (Parser.tokens.actual.token_type == "PTVIRGULA"):
            node = NoOp()
            Parser.tokens.selectNext()
            return node
        elif (Parser.tokens.actual.token_type == "DATA_TYPE"):
            identifier = Identifier()
            identifier.tipo = Parser.tokens.actual.value
            Parser.tokens.selectNext()
            if (Parser.tokens.actual.token_type == "NOME"):
                identifier.value = Parser.tokens.actual.value
                Parser.tokens.selectNext()
            if (Parser.tokens.actual.token_type == "EQUAL"):
                node = Assignment(Parser.tokens.actual.value)
                Parser.tokens.selectNext()
                node.children.append(identifier)
                node.children.append(Parser.parseRelexpr())
                if (Parser.tokens.actual.token_type == "PTVIRGULA"):
                    Parser.tokens.selectNext()
                    return node
                else:
                    raise ValueError('Esperado um ponto e virgula')

            else:
                raise ValueError('Esperado um assignment')

        elif (Parser.tokens.actual.token_type == "LOG"):
            node = Echo(Parser.tokens.actual.value)
            Parser.tokens.selectNext()
            if (Parser.tokens.actual.token_type == "APAR"):
                Parser.tokens.selectNext()
                node.children.append(Parser.parseRelexpr())
                if (Parser.tokens.actual.token_type == "FPAR"):
                    Parser.tokens.selectNext()
                    if (Parser.tokens.actual.token_type == "PTVIRGULA"):
                        Parser.tokens.selectNext()
                        return node
                    else:
                        raise ValueError('Esperado um ponto e virgula')
                else:
                    raise ValueError('Esperado um parentesis')
            else:
                raise ValueError('Esperado um parentesis')

        elif (Parser.tokens.actual.token_type == "IF"):
            node = If(Parser.tokens.actual.value)
            Parser.tokens.selectNext()
            node.children.append(Parser.parseRelexpr())
            # if(Parser.tokens.actual.token_type == "INTERR"):
            # Parser.tokens.selectNext()
            node.children.append(Parser.parseCommand())
            # if(Parser.tokens.actual.token_type == "DOISP"):
            # Parser.tokens.selectNext()
            node.children.append(Parser.parseCommand())
            return node
            # else:
            #     return node
            # else:
            #     raise ValueError('Esperado um parenteses')

        elif (Parser.tokens.actual.token_type == "WHILE"):
            node = While(Parser.tokens.actual.value)
            Parser.tokens.selectNext()
            node.children.append(Parser.parseRelexpr())
            node.children.append(Parser.parseCommand())
            return node

        elif (Parser.tokens.actual.token_type == "FUNCTION"):
            Parser.tokens.selectNext()
            if (Parser.tokens.actual.token_type == "NOME"):
                node = FuncDec(Parser.tokens.actual.value)
                Parser.tokens.selectNext()
                if (Parser.tokens.actual.token_type == "EQUAL"):
                    Parser.tokens.selectNext()
                    if (Parser.tokens.actual.token_type == "DATA_TYPE"):
                        node.return_type = Parser.tokens.actual.value
                        Parser.tokens.selectNext()
                        if (Parser.tokens.actual.token_type == "APAR"):
                            Parser.tokens.selectNext()
                            while (True):
                                if (Parser.tokens.actual.token_type ==
                                        "DATA_TYPE"):
                                    identifier = Identifier()
                                    identifier.tipo = Parser.tokens.actual.value
                                    Parser.tokens.selectNext()
                                    if (Parser.tokens.actual.token_type ==
                                            "NOME"):
                                        identifier.value = Parser.tokens.actual.value
                                        Parser.tokens.selectNext()
                                        node.children.append(identifier)
                                        if (Parser.tokens.actual.token_type ==
                                                "VIRGULA"):
                                            Parser.tokens.selectNext()
                                        elif (Parser.tokens.actual.token_type
                                              == "FPAR"):
                                            Parser.tokens.selectNext()
                                            node.children.append(
                                                Parser.parseBlock())
                                            return node
                                        else:
                                            raise ValueError(
                                                "Esperado uma virgula ou parentesis"
                                            )
                                elif (Parser.tokens.actual.token_type == "FPAR"
                                      ):
                                    Parser.tokens.selectNext()
                                    node.children.append(Parser.parseBlock())
                                    return node
                                else:
                                    raise ValueError("Esperado um identifier")
                        else:
                            raise ValueError("Esperado um parentesis")
                    else:
                        raise ValueError(
                            "Esperado o tipo do retorno da funcao")
            else:
                raise ValueError("Esperado o nome da funcao")

        elif (Parser.tokens.actual.token_type == "RETURN"):
            node = Return(Parser.tokens.actual.token_type)
            Parser.tokens.selectNext()
            node.children.append(Parser.parseRelexpr())
            if (Parser.tokens.actual.token_type == "PTVIRGULA"):
                Parser.tokens.selectNext()
                return node
            else:
                raise ValueError('Esperado um ponto e virgula')

        elif (Parser.tokens.actual.token_type == "NOME"):
            node = FuncCall(Parser.tokens.actual.value)
            Parser.tokens.selectNext()
            if (Parser.tokens.actual.token_type == "APAR"):
                Parser.tokens.selectNext()
                while (True):
                    if (Parser.tokens.actual.token_type == "FPAR"):
                        Parser.tokens.selectNext()
                        return node
                    else:
                        node.children.append(Parser.parseRelexpr())
                        if (Parser.tokens.actual.token_type == "VIRGULA"):
                            Parser.tokens.selectNext()
                        elif (Parser.tokens.actual.token_type == "FPAR"):
                            Parser.tokens.selectNext()
                            return node
                        else:
                            raise ValueError(
                                "Esperado uma virgula ou parentesis")
            else:
                raise ValueError("Esperado um parentesis")

        else:
            return Parser.parseBlock()
Beispiel #23
0
 def __copy__(self):
     return self.subproblem(Assignment())
Beispiel #24
0
class Autograder( object ):

    def __init__( self, config_file ):
        '''
            Read the autograder configuration file and populate grading root
            and grading master directory names
        '''
        if not os.path.exists( config_file ):
            local_config_file = os.path.join( os.getcwd(), config_file )
            if not os.path.exists( local_config_file ):
                print 'Error: Autograder Configuration File {} does not exist. Exit...'.format( config_file )
                sys.exit( 0 )
            else:
                config_file = local_config_file

        self.config_file = config_file

        config = ConfigParser.SafeConfigParser()
        config.read( self.config_file )

        try:
            # All the grading for a particular offering of a particular class happens under this director
            self.grading_root = config.get( AgGlobals.AUTOGRADER_CFG_SECTION, AgGlobals.AUTOGRADER_CFG_GRADING_ROOT )

            # This is where all the supplied files / solutions etc are kept for each project / assignment.
            # For each project / assignment, there is a separate directory in this directory
            self.grading_master = config.get( AgGlobals.AUTOGRADER_CFG_SECTION, AgGlobals.AUTOGRADER_CFG_GRADING_MASTER )
        except ConfigParser.NoSectionError as no_sec_err:
            print 'Error: {} in autograder configuration file {}. Exiting...'.format( no_sec_err, self.config_file )
            sys.exit()
        except ConfigParser.NoOptionError as no_op_err:
            print 'Error: {} in autograder configuration file {}. Exiting...'.format( no_op_err, self.config_file )
            sys.exit()

        if not self.grading_root:
            print 'Error: Empty grading root. Exit...'
            sys.exit()

        if not self.grading_master:
            print 'Error: Empty grading master. Exit...'
            sys.exit()

        self.students_dict = OrderedDict()

        self.asmnt = Assignment()

        self.students_directory = AgGlobals.STUDENTS_DIRECTORY  # self.agg.get_students_directory()
        self.grading_directory = AgGlobals.GRADING_DIRECTORY  # self.agg.get_grading_directory()

        self.ag_state = AgGlobals.AG_STATE_CREATED


    '''
        Generate a blank autograder configuration file
    '''
    @classmethod
    def generage_autograder_config_skel( self, config_file_name ):
        cfg_file_path = os.path.join( os.getcwd(), config_file_name )
        if os.path.exists( cfg_file_path ):
            print 'Error: The configuration file {} already exists. Exit...'.format( cfg_file_path )
            return False

        assignment_config = ConfigParser.SafeConfigParser()
        assignment_config.add_section( AgGlobals.AUTOGRADER_CFG_SECTION )

        assignment_config.set( AgGlobals.AUTOGRADER_CFG_SECTION, AgGlobals.AUTOGRADER_CFG_GRADING_ROOT, AgGlobals.AUTOGRADER_CFG_GRADING_ROOT_COMMENT )
        assignment_config.set( AgGlobals.AUTOGRADER_CFG_SECTION, AgGlobals.AUTOGRADER_CFG_GRADING_MASTER, AgGlobals.AUTOGRADER_CFG_GRADING_MASTER_COMMENT )

        with open( config_file_name, 'wb' ) as configfile:
            assignment_config.write( configfile )

        print 'Success: Blank autograder configuration file {} successfully created'.format( config_file_name )



    def created( self ):
        return AgGlobals.is_flags_set( self.ag_state, AgGlobals.AG_STATE_CREATED )


    '''
        Setup an autograder directory tree for grading
        projects / assignments for a particular offering
        of a particular class
    '''
    def setup_grading_dir_tree( self ):
        if os.path.exists( self.grading_root ):
            print 'Error: Autograder grading root directory {} already exists. Exit...'.format( self.grading_root )
            sys.exit( 0 )

        os.mkdir( self.grading_root )
        os.mkdir( os.path.join( self.grading_root, self.grading_master ) )

        # All the student git repos are cloned in this directory
        os.mkdir( os.path.join( self.grading_root, self.students_directory ) )

        # All the compiling and grading of student submission happens here.
        # For each student there is a directory with the cloned student repo name in this directory.
        os.mkdir( os.path.join( self.grading_root, self.grading_directory ) )

        # Copy the autograder configuration file to autograder directory for later usage
        shutil.copy2( self.config_file, os.path.join( self.grading_root, AgGlobals.AUTOGRADER_CFG_NAME ) )

        # Get the directory where Autograder.py module is stored
        autograder_module_dir = os.path.dirname( os.path.realpath( __file__ ) )
        # Copy the student comments style sheet to the grading root directory
        shutil.copy2( os.path.join( autograder_module_dir, AgGlobals.STUDENT_LOG_CSS_FILE_NAME ), self.grading_root )


        # Create the skeleton of the student data csv file
        student_db = os.path.join( self.grading_root, self.students_directory, AgGlobals.STUDENT_DB )
        with open( student_db, 'wb' ) as students:
            writer = csv.writer( students, delimiter = ',', quotechar = '|', quoting = csv.QUOTE_MINIMAL )
            writer.writerow( AgGlobals.STUDENT_DB_FIEDLS )

        # Create an example assignment directory and configuration files
        assignment_name = '{}_{}'.format( self.grading_master[:-1], 1 )  # 'assignment1'
        self.new_assignment( assignment_name )

        print 'Success: Setting up autograder directory structure'
        print 'Grading root: {}'.format( self.grading_root )


    ''' Generate a new blank assignment.
        Creates the directory and the default assignment configuration file '''
    def new_assignment( self, assignment_name ):

        # Create an example assignment directory and configuration files
        assignment = Assignment()
        assignment.new_assignment( self.grading_root, self.grading_master, assignment_name )

        return assignment


    def load_assignment( self, assignment_name ):
        if self.asmnt.load_assignment( self.grading_root, self.grading_master, assignment_name ):
            self.ag_state = AgGlobals.set_flags( self.ag_state, AgGlobals.AG_STATE_ASSIGNMENT_LOADED )
            return True

        return False


    def validate_config( self ):
        # Check whether the grading root directory exists.
        # All the student submissions and assignment definitions are stored
        # under this directory.
        # gradingroot\
        #       autograder.cfg
        #       assignments\
        #           assignment1\
        #           assignment2\
        #       grading\
        #           stud1
        #               assignment1\
        #               assignment2\
        #           stud2
        #               assignment1\
        #               assignment2\
        #       students\
        #           students.csv
        #           stud1
        #               assignment1\
        #               assignment2\
        #           stud2
        #               assignment1\
        #               assignment2\
        if not os.path.exists( self.grading_root ):
            print '\nGrading root directory {} does not exist, Exit...'.format( self.grading_root )
            return False
            # sys.exit()

        # Check whether the assignment master directory exists.
        # This is where all the solution and provided files are stored
        master = os.path.join( self.grading_root, self.grading_master )
        if not os.path.exists( master ):
            print '\nMaster directory {} does not exist, exit...'.format( master )
            return False
            # sys.exit()

        # Check whether the student directory exists.
        # This is where all the cloned student repos are stored
        students = os.path.join( self.grading_root, self.students_directory )
        if not os.path.exists( students ):
            print '\nStudent directory {} does not exist, exit...'.format( students )
            return False
            # sys.exit()

        # Check whether the grading directory exists.
        # This is where all grading happens.
        grading = os.path.join( self.grading_root, self.grading_directory )
        if not os.path.exists( grading ):
            print '\nGrading directory {} does not exist, exit...'.format( grading )
            return False
            # sys.exit()

        self.ag_state = AgGlobals.set_flags( self.ag_state, AgGlobals.AG_STATE_CONFIGURATION_CHECKED )
        return True


    def read_students( self ):
        if not self.validate_config():
            sys.exit()

        students = os.path.join( self.grading_root, self.students_directory, AgGlobals.STUDENT_DB )

        if not os.path.exists( students ):
            print '\nStudnt data file {} does not exist, exit...'.format( students )
            sys.exit()

        # self.students = []
        self.students_dict = OrderedDict()
        with open( students ) as student_db:
            reader = csv.DictReader( student_db )
            for row in reader:
                stud = Student( row )
                # self.students.append( stud )
                self.students_dict[stud.get_index()] = stud

        return len( self.students_dict ) > 0


    def update_repos( self ):
        # When student database is sorted in the ascending order of  student index numbers
        # the length of the index number of the last student is the longest. Get the length
        # of that index number and pass that to the cloning method so that when creating the
        # local student repository directory name each directory have the index number of each
        # student prefixed to student name in such a way prefixed index numbers have the same
        # length with 0s padded in the left. e.g. 003_manujinda
        index_len = len( '{}'.format( self.students_dict[next( reversed( self.students_dict ) )].get_index() ) )
        for stud_no in self.students_dict.keys():
            stud = self.students_dict[stud_no]
            stud_dir = os.path.join( self.grading_root, self.students_directory, stud.get_dir( index_len ) )
            if not os.path.exists( stud_dir ):
                # Student repository has not been cloned. Have to clone it first
                stud.clone_student_repo( stud_dir )
            else:
                stud.pull_student_repo( stud_dir )


    '''
        Grading of student submissions
    '''
    def do_grading2( self, stud_no = None, prob_no = None ):

        print 'Grading',

        # A specific problem number is provided for grading
        if prob_no:
            try:
                prob_no = int( prob_no )
            except ValueError:
                print '\nError: Problem number "{}" must be an integer. Exiting...'.format( prob_no )
                exit()

            if not self.asmnt.is_valid_problem_id( prob_no ):
                print '\nError: Invalid problem number {}'.format( prob_no )
                exit()

            print 'problem number {}'.format( prob_no ),

        # Grade a specific student
        if stud_no:
            # Check whether this is a valid student number
            if stud_no in self.students_dict.keys():
                students = [stud_no]
                print 'of student {}'.format( stud_no ),
            else:
                print '\nError: Invalid student number for grading {}. Exiting...'.format( stud_no )
                exit()
        else:
            # Grade all the students
            students = self.students_dict.keys()

        print 'of {}'.format( self.asmnt.get_assignment_sub_dir() )

        # If students are loaded and problems are loaded
        if len( students ) > 0 and AgGlobals.is_flags_set( self.ag_state, AgGlobals.AG_STATE_ASSIGNMENT_LOADED, AgGlobals.AG_STATE_PROBLEMS_LOADED, AgGlobals.AG_STATE_INPUTS_LOADED ) :

            # This is the path for the students directory
            source = os.path.join( self.grading_root, self.students_directory )

            # This is the path for the grading directory
            destination = os.path.join( self.grading_root, self.grading_directory )

            # Length of the longest student index. This is used to insert
            # leading 0's in the student directory name
            index_len = len( '{}'.format( self.students_dict[next( reversed( self.students_dict ) )].get_index() ) )

            # Get the assignment / project master sub directory
            asmnt_master_sub_dir = self.asmnt.get_masterdir()

            # Get a set of all the provided file names for this assignment / project
            provided_files = self.asmnt.get_provided_files_set()

            # Create a list of paths to all the provided files in the assignment master sub directory
            provided_file_paths = []
            for pf in provided_files:

                # Generate the file path for this provided file
                pf_path = os.path.join( asmnt_master_sub_dir, pf )

                # Check whether this file exists in the assignment master sub directory
                if os.path.exists( pf_path ):
                    provided_file_paths.append( pf_path )

                # If this file does not exists, we cannot proceed with the grading
                else:
                    print 'Error: Provided file {} does not exist. Cannot proceed with grading. Exit...'.format( pf_path )
                    sys.exit( 1 )

            now_time = datetime.now()
            deadline = self.asmnt.get_deadline()

            if not deadline:
                print 'Error: Assignment deadline not properly set or assignment not properly loaded. Exiting...'
                sys.exit()

            update_repos = False
            if now_time > deadline:
                print '\nWarning: Assignment deadline has passed!'
                print 'Now     : {}'.format( now_time.strftime( '%x :: %X' ) )
                print 'Deadline: {}'.format( deadline.strftime( '%x :: %X' ) )
                lateness = now_time - deadline
                print 'Lateness: {}\n'.format( str( lateness ).split( '.', 2 )[0] )
                # print 'Lateness: {}'.format( lateness - timedelta( microseconds = lateness.microseconds ) )
                choice = raw_input( 'Do you want to update repos (Y | n)? ' )

                if choice.lower() == 'y':
                    update_repos = True

            # Open grading log file for this student
            log_directory_path = os.path.join( asmnt_master_sub_dir, AgGlobals.LOG_FILE_DIRECTORY )
            grading_log = open( os.path.join( log_directory_path, AgGlobals.AUTOGRADER_LOG_FILE_NAME ), 'a' )
            AgGlobals.write_to_log( grading_log, '\n{0}<< Grading Session on {1} : START >>{0}\n'.format( '-' * 20, now_time.strftime( '%x :: %X' ) ) )

            # Create the gradebook
            gradebook_headers = self.asmnt.generate_gradebook_headers( prob_no )
            if stud_no:
                grades_file_stud_path = os.path.join( log_directory_path, self.students_dict[stud_no].get_stud_grades_file_name( index_len, self.asmnt.get_assignment_sub_dir() ) )
                gradebook = open( grades_file_stud_path, 'wb' )
            else:
                gradebook = open( os.path.join( log_directory_path, AgGlobals.get_gradebook_file_name( self.asmnt.get_assignment_sub_dir(), prob_no ) ), 'wb' )
            gradebook_headers += [ AgGlobals.GRADEBOOK_HEADER_TOTAL, AgGlobals.GRADEBOOK_HEADER_COMMENT ]
            gb = csv.DictWriter( gradebook, gradebook_headers )
            gb.writeheader()

            # Get the directory where Autograder.py module is stored
            autograder_module_dir = os.path.dirname( os.path.realpath( __file__ ) )
            # Open and read grading output skeleton html
            html_file = open( os.path.join( autograder_module_dir, AgGlobals.STUDENT_LOG_HTML_SKELETON_FILE_NAME ), 'r' )
            html_skeleton = html_file.read()

            # For each student
            for stud_no in students:
                stud = self.students_dict[stud_no]

                print '\nStudent: {}) {}'.format( stud.get_index(), stud.get_name() )

                grading_log_stud_path = os.path.join( log_directory_path, stud.get_stud_log_file_name( index_len, self.asmnt.get_assignment_sub_dir() ) )
                grading_log_stud = open( grading_log_stud_path, 'a' )
                # AgGlobals.write_to_log( grading_log_stud, '\n{0}<< Grading Session on {1} : START >>{0}\n'.format( '-' * 20, datetime.now() ) )
                # AgGlobals.write_to_log( grading_log_stud, '\n{0} Student: {1} {0}\n'.format( '#' * 10, stud.get_name() ) )
                AgGlobals.write_to_log( grading_log_stud, '\n<h2 class=grading_session>Grading Session on {}</h2>'.format( datetime.now().strftime( '%x :: %X' ) ), 1 )

                AgGlobals.write_to_log( grading_log, '\n{0} Student: {1} {0}\n'.format( '#' * 10, stud.get_name() ) )

                marks_dict = {}
                for h in gradebook_headers:
                    marks_dict[h] = 0.0
                marks_dict[AgGlobals.GRADEBOOK_HEADER_STUDENT] = stud.get_index()
                marks_dict[AgGlobals.GRADEBOOK_HEADER_COMMENT] = ''

                # Student's directory name
                stud_dir_name = stud.get_dir( index_len )

                # Path for the student's directory in the students directory
                stud_local_repo_path = os.path.join( source, stud_dir_name )

                # Path for the student's directory in the grading directory
                stud_dir_path = os.path.join( destination, stud_dir_name, self.asmnt.get_assignment_sub_dir() )

                # Update student repos only if this is before the deadline
                if now_time <= deadline or update_repos:
                    # Update local student repository
                    if not os.path.exists( stud_local_repo_path ):
                        # Student repository has not been cloned. Have to clone it first
                        stud.clone_student_repo( stud_local_repo_path, grading_log, grading_log_stud )
                    else:
                        stud.pull_student_repo( stud_local_repo_path, grading_log, grading_log_stud )

                # Copy all the student submitted files from student directory in students directory
                # to a directory with the same name in the grading directory
                stud.copy_student_repo( source, destination, index_len )

                # Check whether student has created a directory with the proper name in his or her
                # repository to upload files for this assignment / project
                if not os.path.exists( stud_dir_path ):
                    print '\tError: Student {} does not have the assignment directory {} in the repository.'.format( stud.get_name(), stud_dir_path )
                    AgGlobals.write_to_log( grading_log, '\tError: {} directory does not exist in the repo\n'.format( self.asmnt.get_assignment_sub_dir() ) )
                    AgGlobals.write_to_log( grading_log_stud, '<p class=error>Error: {} directory does not exist in the repo</p>'.format( self.asmnt.get_assignment_sub_dir() ), 1 )
                    marks_dict[AgGlobals.GRADEBOOK_HEADER_COMMENT] = '{} directory does not exist in the repo'.format( self.asmnt.get_assignment_sub_dir() )
                    self.write_stud_marks( marks_dict, gb, grading_log_stud_path, html_skeleton )
                    grading_log_stud.close()
                    continue

                # Copy the provided files into student's directory in the grading directory
                for pf_path in provided_file_paths:
                    shutil.copy2( pf_path, stud_dir_path )

                self.asmnt.grade2( stud_dir_path, grading_log, grading_log_stud, marks_dict )

                grading_log_stud.close()
                grading_log.flush()
                os.fsync( grading_log )

                self.write_stud_marks( marks_dict, gb, grading_log_stud_path, html_skeleton )

                gradebook.flush()
                os.fsync( gradebook )

            grading_log.close()
            gradebook.close()


    def write_stud_marks( self, marks_dict, gb_csv, grading_log_stud_path, html_skeleton ):
        tot = 0
        for h in marks_dict:
            if h != AgGlobals.GRADEBOOK_HEADER_STUDENT and h != AgGlobals.GRADEBOOK_HEADER_COMMENT:
                tot += marks_dict[h]

        marks_dict[AgGlobals.GRADEBOOK_HEADER_TOTAL] = tot

        gb_csv.writerow( marks_dict )

        grading_log_stud_html = open( AgGlobals.get_stud_html_log_file_path( grading_log_stud_path ), 'wb' )
        grading_log_stud = open( grading_log_stud_path, 'r' )
        stud_log_entries = grading_log_stud.read()
        AgGlobals.write_to_log( grading_log_stud_html, html_skeleton )
        AgGlobals.write_to_log( grading_log_stud_html, stud_log_entries )
        AgGlobals.write_to_log( grading_log_stud_html, '</body>\n</html>' )
        grading_log_stud.close()
        grading_log_stud_html.close()


    '''
    If a valid assignment configuration file has been loaded, this will generate necessary problem configuration file
    '''
    def gen_prob_config_skel( self ):
        if AgGlobals.is_flags_set( self.ag_state, AgGlobals.AG_STATE_ASSIGNMENT_LOADED ):
            self.asmnt.generate_problem_config()


    def load_problems( self ):
        if AgGlobals.is_flags_set( self.ag_state, AgGlobals.AG_STATE_ASSIGNMENT_LOADED ):
            result = self.asmnt.load_problems()
            if result:
                self.ag_state = AgGlobals.set_flags( self.ag_state, AgGlobals.AG_STATE_PROBLEMS_LOADED )

            return result
        return False


    def generate_files( self ):
        if AgGlobals.is_flags_set( self.ag_state, AgGlobals.AG_STATE_ASSIGNMENT_LOADED ):
            self.asmnt.generate_provided_files()
            self.asmnt.generate_submitted_files()
            self.asmnt.generate_input_config()


    def load_input( self ):
        if AgGlobals.is_flags_set( self.ag_state, AgGlobals.AG_STATE_ASSIGNMENT_LOADED ):
            if self.asmnt.load_input():
                self.ag_state = AgGlobals.set_flags( self.ag_state, AgGlobals.AG_STATE_INPUTS_LOADED )

                return True
        return False


    def compile( self ):
        if AgGlobals.is_flags_set( self.ag_state, AgGlobals.AG_STATE_ASSIGNMENT_LOADED ):
            if self.asmnt.compile():
                self.ag_state = AgGlobals.set_flags( self.ag_state, AgGlobals.AG_STATE_COMPILED )

                return True
        return False


    def link( self ):
        if AgGlobals.is_flags_set( self.ag_state, AgGlobals.AG_STATE_ASSIGNMENT_LOADED ):
            if self.asmnt.compile():
                if self.asmnt.link():
                    self.ag_state = AgGlobals.set_flags( self.ag_state, AgGlobals.AG_STATE_LINKED )

                    return True
        return False


    def generate_output( self ):
        if AgGlobals.is_flags_set( self.ag_state, AgGlobals.AG_STATE_ASSIGNMENT_LOADED ):
            if self.asmnt.compile():
                if self.asmnt.link() and self.asmnt.load_input():
                    if self.asmnt.generate_output():
                        self.ag_state = AgGlobals.set_flags( self.ag_state, AgGlobals.AG_STATE_OUTPUTS_GENERATED )

                        return True
        return False
Beispiel #25
0
class Autograder(object):
    def __init__(self, config_file):
        '''
            Read the autograder configuration file and populate grading root
            and grading master directory names
        '''
        if not os.path.exists(config_file):
            local_config_file = os.path.join(os.getcwd(), config_file)
            if not os.path.exists(local_config_file):
                print 'Error: Autograder Configuration File {} does not exist. Exit...'.format(
                    config_file)
                sys.exit(0)
            else:
                config_file = local_config_file

        self.config_file = config_file

        config = ConfigParser.SafeConfigParser()
        config.read(self.config_file)

        try:
            # All the grading for a particular offering of a particular class happens under this director
            self.grading_root = config.get(
                AgGlobals.AUTOGRADER_CFG_SECTION,
                AgGlobals.AUTOGRADER_CFG_GRADING_ROOT)

            # This is where all the supplied files / solutions etc are kept for each project / assignment.
            # For each project / assignment, there is a separate directory in this directory
            self.grading_master = config.get(
                AgGlobals.AUTOGRADER_CFG_SECTION,
                AgGlobals.AUTOGRADER_CFG_GRADING_MASTER)
        except ConfigParser.NoSectionError as no_sec_err:
            print 'Error: {} in autograder configuration file {}. Exiting...'.format(
                no_sec_err, self.config_file)
            sys.exit()
        except ConfigParser.NoOptionError as no_op_err:
            print 'Error: {} in autograder configuration file {}. Exiting...'.format(
                no_op_err, self.config_file)
            sys.exit()

        if not self.grading_root:
            print 'Error: Empty grading root. Exit...'
            sys.exit()

        if not self.grading_master:
            print 'Error: Empty grading master. Exit...'
            sys.exit()

        self.students_dict = OrderedDict()

        self.asmnt = Assignment()

        self.students_directory = AgGlobals.STUDENTS_DIRECTORY  # self.agg.get_students_directory()
        self.grading_directory = AgGlobals.GRADING_DIRECTORY  # self.agg.get_grading_directory()

        self.ag_state = AgGlobals.AG_STATE_CREATED

    '''
        Generate a blank autograder configuration file
    '''

    @classmethod
    def generage_autograder_config_skel(self, config_file_name):
        cfg_file_path = os.path.join(os.getcwd(), config_file_name)
        if os.path.exists(cfg_file_path):
            print 'Error: The configuration file {} already exists. Exit...'.format(
                cfg_file_path)
            return False

        assignment_config = ConfigParser.SafeConfigParser()
        assignment_config.add_section(AgGlobals.AUTOGRADER_CFG_SECTION)

        assignment_config.set(AgGlobals.AUTOGRADER_CFG_SECTION,
                              AgGlobals.AUTOGRADER_CFG_GRADING_ROOT,
                              AgGlobals.AUTOGRADER_CFG_GRADING_ROOT_COMMENT)
        assignment_config.set(AgGlobals.AUTOGRADER_CFG_SECTION,
                              AgGlobals.AUTOGRADER_CFG_GRADING_MASTER,
                              AgGlobals.AUTOGRADER_CFG_GRADING_MASTER_COMMENT)

        with open(config_file_name, 'wb') as configfile:
            assignment_config.write(configfile)

        print 'Success: Blank autograder configuration file {} successfully created'.format(
            config_file_name)

    def created(self):
        return AgGlobals.is_flags_set(self.ag_state,
                                      AgGlobals.AG_STATE_CREATED)

    '''
        Setup an autograder directory tree for grading
        projects / assignments for a particular offering
        of a particular class
    '''

    def setup_grading_dir_tree(self):
        if os.path.exists(self.grading_root):
            print 'Error: Autograder grading root directory {} already exists. Exit...'.format(
                self.grading_root)
            sys.exit(0)

        os.mkdir(self.grading_root)
        os.mkdir(os.path.join(self.grading_root, self.grading_master))

        # All the student git repos are cloned in this directory
        os.mkdir(os.path.join(self.grading_root, self.students_directory))

        # All the compiling and grading of student submission happens here.
        # For each student there is a directory with the cloned student repo name in this directory.
        os.mkdir(os.path.join(self.grading_root, self.grading_directory))

        # Copy the autograder configuration file to autograder directory for later usage
        shutil.copy2(
            self.config_file,
            os.path.join(self.grading_root, AgGlobals.AUTOGRADER_CFG_NAME))

        # Get the directory where Autograder.py module is stored
        autograder_module_dir = os.path.dirname(os.path.realpath(__file__))
        # Copy the student comments style sheet to the grading root directory
        shutil.copy2(
            os.path.join(autograder_module_dir,
                         AgGlobals.STUDENT_LOG_CSS_FILE_NAME),
            self.grading_root)

        # Create the skeleton of the student data csv file
        student_db = os.path.join(self.grading_root, self.students_directory,
                                  AgGlobals.STUDENT_DB)
        with open(student_db, 'wb') as students:
            writer = csv.writer(students,
                                delimiter=',',
                                quotechar='|',
                                quoting=csv.QUOTE_MINIMAL)
            writer.writerow(AgGlobals.STUDENT_DB_FIEDLS)

        # Create an example assignment directory and configuration files
        assignment_name = '{}_{}'.format(self.grading_master[:-1],
                                         1)  # 'assignment1'
        self.new_assignment(assignment_name)

        print 'Success: Setting up autograder directory structure'
        print 'Grading root: {}'.format(self.grading_root)

    ''' Generate a new blank assignment.
        Creates the directory and the default assignment configuration file '''

    def new_assignment(self, assignment_name):

        # Create an example assignment directory and configuration files
        assignment = Assignment()
        assignment.new_assignment(self.grading_root, self.grading_master,
                                  assignment_name)

        return assignment

    def load_assignment(self, assignment_name):
        if self.asmnt.load_assignment(self.grading_root, self.grading_master,
                                      assignment_name):
            self.ag_state = AgGlobals.set_flags(
                self.ag_state, AgGlobals.AG_STATE_ASSIGNMENT_LOADED)
            return True

        return False

    def validate_config(self):
        # Check whether the grading root directory exists.
        # All the student submissions and assignment definitions are stored
        # under this directory.
        # gradingroot\
        #       autograder.cfg
        #       assignments\
        #           assignment1\
        #           assignment2\
        #       grading\
        #           stud1
        #               assignment1\
        #               assignment2\
        #           stud2
        #               assignment1\
        #               assignment2\
        #       students\
        #           students.csv
        #           stud1
        #               assignment1\
        #               assignment2\
        #           stud2
        #               assignment1\
        #               assignment2\
        if not os.path.exists(self.grading_root):
            print '\nGrading root directory {} does not exist, Exit...'.format(
                self.grading_root)
            return False
            # sys.exit()

        # Check whether the assignment master directory exists.
        # This is where all the solution and provided files are stored
        master = os.path.join(self.grading_root, self.grading_master)
        if not os.path.exists(master):
            print '\nMaster directory {} does not exist, exit...'.format(
                master)
            return False
            # sys.exit()

        # Check whether the student directory exists.
        # This is where all the cloned student repos are stored
        students = os.path.join(self.grading_root, self.students_directory)
        if not os.path.exists(students):
            print '\nStudent directory {} does not exist, exit...'.format(
                students)
            return False
            # sys.exit()

        # Check whether the grading directory exists.
        # This is where all grading happens.
        grading = os.path.join(self.grading_root, self.grading_directory)
        if not os.path.exists(grading):
            print '\nGrading directory {} does not exist, exit...'.format(
                grading)
            return False
            # sys.exit()

        self.ag_state = AgGlobals.set_flags(
            self.ag_state, AgGlobals.AG_STATE_CONFIGURATION_CHECKED)
        return True

    def read_students(self):
        if not self.validate_config():
            sys.exit()

        students = os.path.join(self.grading_root, self.students_directory,
                                AgGlobals.STUDENT_DB)

        if not os.path.exists(students):
            print '\nStudnt data file {} does not exist, exit...'.format(
                students)
            sys.exit()

        # self.students = []
        self.students_dict = OrderedDict()
        with open(students) as student_db:
            reader = csv.DictReader(student_db)
            for row in reader:
                stud = Student(row)
                # self.students.append( stud )
                self.students_dict[stud.get_index()] = stud

        return len(self.students_dict) > 0

    def update_repos(self):
        # When student database is sorted in the ascending order of  student index numbers
        # the length of the index number of the last student is the longest. Get the length
        # of that index number and pass that to the cloning method so that when creating the
        # local student repository directory name each directory have the index number of each
        # student prefixed to student name in such a way prefixed index numbers have the same
        # length with 0s padded in the left. e.g. 003_manujinda
        index_len = len('{}'.format(self.students_dict[next(
            reversed(self.students_dict))].get_index()))
        for stud_no in self.students_dict.keys():
            stud = self.students_dict[stud_no]
            stud_dir = os.path.join(self.grading_root, self.students_directory,
                                    stud.get_dir(index_len))
            if not os.path.exists(stud_dir):
                # Student repository has not been cloned. Have to clone it first
                stud.clone_student_repo(stud_dir)
            else:
                stud.pull_student_repo(stud_dir)

    '''
        Grading of student submissions
    '''

    def do_grading2(self, stud_no=None, prob_no=None):

        print 'Grading',

        # A specific problem number is provided for grading
        if prob_no:
            try:
                prob_no = int(prob_no)
            except ValueError:
                print '\nError: Problem number "{}" must be an integer. Exiting...'.format(
                    prob_no)
                exit()

            if not self.asmnt.is_valid_problem_id(prob_no):
                print '\nError: Invalid problem number {}'.format(prob_no)
                exit()

            print 'problem number {}'.format(prob_no),

        # Grade a specific student
        if stud_no:
            # Check whether this is a valid student number
            if stud_no in self.students_dict.keys():
                students = [stud_no]
                print 'of student {}'.format(stud_no),
            else:
                print '\nError: Invalid student number for grading {}. Exiting...'.format(
                    stud_no)
                exit()
        else:
            # Grade all the students
            students = self.students_dict.keys()

        print 'of {}'.format(self.asmnt.get_assignment_sub_dir())

        # If students are loaded and problems are loaded
        if len(students) > 0 and AgGlobals.is_flags_set(
                self.ag_state, AgGlobals.AG_STATE_ASSIGNMENT_LOADED,
                AgGlobals.AG_STATE_PROBLEMS_LOADED,
                AgGlobals.AG_STATE_INPUTS_LOADED):

            # This is the path for the students directory
            source = os.path.join(self.grading_root, self.students_directory)

            # This is the path for the grading directory
            destination = os.path.join(self.grading_root,
                                       self.grading_directory)

            # Length of the longest student index. This is used to insert
            # leading 0's in the student directory name
            index_len = len('{}'.format(self.students_dict[next(
                reversed(self.students_dict))].get_index()))

            # Get the assignment / project master sub directory
            asmnt_master_sub_dir = self.asmnt.get_masterdir()

            # Get a set of all the provided file names for this assignment / project
            provided_files = self.asmnt.get_provided_files_set()

            # Create a list of paths to all the provided files in the assignment master sub directory
            provided_file_paths = []
            for pf in provided_files:

                # Generate the file path for this provided file
                pf_path = os.path.join(asmnt_master_sub_dir, pf)

                # Check whether this file exists in the assignment master sub directory
                if os.path.exists(pf_path):
                    provided_file_paths.append(pf_path)

                # If this file does not exists, we cannot proceed with the grading
                else:
                    print 'Error: Provided file {} does not exist. Cannot proceed with grading. Exit...'.format(
                        pf_path)
                    sys.exit(1)

            now_time = datetime.now()
            deadline = self.asmnt.get_deadline()

            if not deadline:
                print 'Error: Assignment deadline not properly set or assignment not properly loaded. Exiting...'
                sys.exit()

            update_repos = False
            if now_time > deadline:
                print '\nWarning: Assignment deadline has passed!'
                print 'Now     : {}'.format(now_time.strftime('%x :: %X'))
                print 'Deadline: {}'.format(deadline.strftime('%x :: %X'))
                lateness = now_time - deadline
                print 'Lateness: {}\n'.format(str(lateness).split('.', 2)[0])
                # print 'Lateness: {}'.format( lateness - timedelta( microseconds = lateness.microseconds ) )
                choice = raw_input('Do you want to update repos (Y | n)? ')

                if choice.lower() == 'y':
                    update_repos = True

            # Open grading log file for this student
            log_directory_path = os.path.join(asmnt_master_sub_dir,
                                              AgGlobals.LOG_FILE_DIRECTORY)
            grading_log = open(
                os.path.join(log_directory_path,
                             AgGlobals.AUTOGRADER_LOG_FILE_NAME), 'a')
            AgGlobals.write_to_log(
                grading_log,
                '\n{0}<< Grading Session on {1} : START >>{0}\n'.format(
                    '-' * 20, now_time.strftime('%x :: %X')))

            # Create the gradebook
            gradebook_headers = self.asmnt.generate_gradebook_headers(prob_no)
            if stud_no:
                grades_file_stud_path = os.path.join(
                    log_directory_path,
                    self.students_dict[stud_no].get_stud_grades_file_name(
                        index_len, self.asmnt.get_assignment_sub_dir()))
                gradebook = open(grades_file_stud_path, 'wb')
            else:
                gradebook = open(
                    os.path.join(
                        log_directory_path,
                        AgGlobals.get_gradebook_file_name(
                            self.asmnt.get_assignment_sub_dir(), prob_no)),
                    'wb')
            gradebook_headers += [
                AgGlobals.GRADEBOOK_HEADER_TOTAL,
                AgGlobals.GRADEBOOK_HEADER_COMMENT
            ]
            gb = csv.DictWriter(gradebook, gradebook_headers)
            gb.writeheader()

            # Get the directory where Autograder.py module is stored
            autograder_module_dir = os.path.dirname(os.path.realpath(__file__))
            # Open and read grading output skeleton html
            html_file = open(
                os.path.join(autograder_module_dir,
                             AgGlobals.STUDENT_LOG_HTML_SKELETON_FILE_NAME),
                'r')
            html_skeleton = html_file.read()

            # For each student
            for stud_no in students:
                stud = self.students_dict[stud_no]

                print '\nStudent: {}) {}'.format(stud.get_index(),
                                                 stud.get_name())

                grading_log_stud_path = os.path.join(
                    log_directory_path,
                    stud.get_stud_log_file_name(
                        index_len, self.asmnt.get_assignment_sub_dir()))
                grading_log_stud = open(grading_log_stud_path, 'a')
                # AgGlobals.write_to_log( grading_log_stud, '\n{0}<< Grading Session on {1} : START >>{0}\n'.format( '-' * 20, datetime.now() ) )
                # AgGlobals.write_to_log( grading_log_stud, '\n{0} Student: {1} {0}\n'.format( '#' * 10, stud.get_name() ) )
                AgGlobals.write_to_log(
                    grading_log_stud,
                    '\n<h2 class=grading_session>Grading Session on {}</h2>'.
                    format(datetime.now().strftime('%x :: %X')), 1)

                AgGlobals.write_to_log(
                    grading_log,
                    '\n{0} Student: {1} {0}\n'.format('#' * 10,
                                                      stud.get_name()))

                marks_dict = {}
                for h in gradebook_headers:
                    marks_dict[h] = 0.0
                marks_dict[
                    AgGlobals.GRADEBOOK_HEADER_STUDENT] = stud.get_index()
                marks_dict[AgGlobals.GRADEBOOK_HEADER_COMMENT] = ''

                # Student's directory name
                stud_dir_name = stud.get_dir(index_len)

                # Path for the student's directory in the students directory
                stud_local_repo_path = os.path.join(source, stud_dir_name)

                # Path for the student's directory in the grading directory
                stud_dir_path = os.path.join(
                    destination, stud_dir_name,
                    self.asmnt.get_assignment_sub_dir())

                # Update student repos only if this is before the deadline
                if now_time <= deadline or update_repos:
                    # Update local student repository
                    if not os.path.exists(stud_local_repo_path):
                        # Student repository has not been cloned. Have to clone it first
                        stud.clone_student_repo(stud_local_repo_path,
                                                grading_log, grading_log_stud)
                    else:
                        stud.pull_student_repo(stud_local_repo_path,
                                               grading_log, grading_log_stud)

                # Copy all the student submitted files from student directory in students directory
                # to a directory with the same name in the grading directory
                stud.copy_student_repo(source, destination, index_len)

                # Check whether student has created a directory with the proper name in his or her
                # repository to upload files for this assignment / project
                if not os.path.exists(stud_dir_path):
                    print '\tError: Student {} does not have the assignment directory {} in the repository.'.format(
                        stud.get_name(), stud_dir_path)
                    AgGlobals.write_to_log(
                        grading_log,
                        '\tError: {} directory does not exist in the repo\n'.
                        format(self.asmnt.get_assignment_sub_dir()))
                    AgGlobals.write_to_log(
                        grading_log_stud,
                        '<p class=error>Error: {} directory does not exist in the repo</p>'
                        .format(self.asmnt.get_assignment_sub_dir()), 1)
                    marks_dict[
                        AgGlobals.
                        GRADEBOOK_HEADER_COMMENT] = '{} directory does not exist in the repo'.format(
                            self.asmnt.get_assignment_sub_dir())
                    self.write_stud_marks(marks_dict, gb,
                                          grading_log_stud_path, html_skeleton)
                    grading_log_stud.close()
                    continue

                # Copy the provided files into student's directory in the grading directory
                for pf_path in provided_file_paths:
                    shutil.copy2(pf_path, stud_dir_path)

                self.asmnt.grade2(stud_dir_path, grading_log, grading_log_stud,
                                  marks_dict)

                grading_log_stud.close()
                grading_log.flush()
                os.fsync(grading_log)

                self.write_stud_marks(marks_dict, gb, grading_log_stud_path,
                                      html_skeleton)

                gradebook.flush()
                os.fsync(gradebook)

            grading_log.close()
            gradebook.close()

    def write_stud_marks(self, marks_dict, gb_csv, grading_log_stud_path,
                         html_skeleton):
        tot = 0
        for h in marks_dict:
            if h != AgGlobals.GRADEBOOK_HEADER_STUDENT and h != AgGlobals.GRADEBOOK_HEADER_COMMENT:
                tot += marks_dict[h]

        marks_dict[AgGlobals.GRADEBOOK_HEADER_TOTAL] = tot

        gb_csv.writerow(marks_dict)

        grading_log_stud_html = open(
            AgGlobals.get_stud_html_log_file_path(grading_log_stud_path), 'wb')
        grading_log_stud = open(grading_log_stud_path, 'r')
        stud_log_entries = grading_log_stud.read()
        AgGlobals.write_to_log(grading_log_stud_html, html_skeleton)
        AgGlobals.write_to_log(grading_log_stud_html, stud_log_entries)
        AgGlobals.write_to_log(grading_log_stud_html, '</body>\n</html>')
        grading_log_stud.close()
        grading_log_stud_html.close()

    '''
    If a valid assignment configuration file has been loaded, this will generate necessary problem configuration file
    '''

    def gen_prob_config_skel(self):
        if AgGlobals.is_flags_set(self.ag_state,
                                  AgGlobals.AG_STATE_ASSIGNMENT_LOADED):
            self.asmnt.generate_problem_config()

    def load_problems(self):
        if AgGlobals.is_flags_set(self.ag_state,
                                  AgGlobals.AG_STATE_ASSIGNMENT_LOADED):
            result = self.asmnt.load_problems()
            if result:
                self.ag_state = AgGlobals.set_flags(
                    self.ag_state, AgGlobals.AG_STATE_PROBLEMS_LOADED)

            return result
        return False

    def generate_files(self):
        if AgGlobals.is_flags_set(self.ag_state,
                                  AgGlobals.AG_STATE_ASSIGNMENT_LOADED):
            self.asmnt.generate_provided_files()
            self.asmnt.generate_submitted_files()
            self.asmnt.generate_input_config()

    def load_input(self):
        if AgGlobals.is_flags_set(self.ag_state,
                                  AgGlobals.AG_STATE_ASSIGNMENT_LOADED):
            if self.asmnt.load_input():
                self.ag_state = AgGlobals.set_flags(
                    self.ag_state, AgGlobals.AG_STATE_INPUTS_LOADED)

                return True
        return False

    def compile(self):
        if AgGlobals.is_flags_set(self.ag_state,
                                  AgGlobals.AG_STATE_ASSIGNMENT_LOADED):
            if self.asmnt.compile():
                self.ag_state = AgGlobals.set_flags(
                    self.ag_state, AgGlobals.AG_STATE_COMPILED)

                return True
        return False

    def link(self):
        if AgGlobals.is_flags_set(self.ag_state,
                                  AgGlobals.AG_STATE_ASSIGNMENT_LOADED):
            if self.asmnt.compile():
                if self.asmnt.link():
                    self.ag_state = AgGlobals.set_flags(
                        self.ag_state, AgGlobals.AG_STATE_LINKED)

                    return True
        return False

    def generate_output(self):
        if AgGlobals.is_flags_set(self.ag_state,
                                  AgGlobals.AG_STATE_ASSIGNMENT_LOADED):
            if self.asmnt.compile():
                if self.asmnt.link() and self.asmnt.load_input():
                    if self.asmnt.generate_output():
                        self.ag_state = AgGlobals.set_flags(
                            self.ag_state,
                            AgGlobals.AG_STATE_OUTPUTS_GENERATED)

                        return True
        return False
Beispiel #26
0
    def create_assignments(self, title, description, weight, max_score):
        from Assignment import Assignment
        temp = Assignment(title, description, weight, max_score)

        #Adds this new Assignment to the parent Category's list of assignments
        assignment_list.append(temp)
Beispiel #27
0
        d2[t] = d[t]

print d2
exit()

# Dictionary to CSV file writing
my_dict = {"x": 2, "a": 1}

with open('mycsvfile.csv', 'wb') as f:  # Just use 'w' mode in 3.x
    w = csv.DictWriter(f, ['x', 'a'])
    w.writeheader()
    w.writerow(my_dict)

exit()

asmnt = Assignment()

asmnt.load_assignment( \
'C:\Users\manujinda\Documents\Manujinda\UOregon\Classes\\4_2016_Summer\Boyana\grading', \
'assignments', 'assignment_2' )

asmnt.load_problems()

headers = asmnt.generate_gradebook_headers()

print headers

asmnt_master_sub_dir = asmnt.get_masterdir()
log_directory_path = os.path.join(asmnt_master_sub_dir,
                                  AgGlobals.LOG_FILE_DIRECTORY)
gradebook = open(os.path.join(log_directory_path, 'gradebook.csv'), 'w')