Esempio n. 1
0
def do_execute(backend, criteria, ind, execute_dir, executable_file_path,
               test_index, test_name, report_path):
    """
	Funkcija koja obavlja zadatak radne niti za pokretanja testa

	backend - back-end koji se trenutno koristi
	criteria - kriterijum pregleda zadatka (bodovanje, način izvršavanja itd.)
	ind - indeks pokretanja testa (1..N) - za svaki novi test kreće od jedinice
	execute_dir - direktorijum u kojem se inicira izvršenje
	executable_file_path - relativna putanja do izvršnog fajla (uključujući i njegov naziv) - relativna u odnosu na
	                       execute_dir
	test_index - unikatni identifikator pokretanja testa
	test_name - naziv testa koji se izvršava
	report_path - putanja do fajla sa konzolnim izlazom testa (uključujući i njegov naziv)

	Vraća interni format (objekat klase SingleRunResult) o uspešnosti pokretanja		
	"""
    backend.execute_test(test_name, execute_dir, executable_file_path,
                         test_index, report_path)

    try:
        r = backend.parse_testing_artefacts(test_name, execute_dir,
                                            criteria.blocking_tests,
                                            test_index)
        return r

    except RuntimeError as err:
        util.fatal_error(err.message)
Esempio n. 2
0
def show_diffs_from_student(backend, config):
    """
	Pokreće vizuelni diff alat kako bi se prikazale razlike između izmenjenog zadatka (alternativne verzije) i zadatka
	onako kako ga je student uradio

	backend - back-end koji se trenutno koristi
	config - globalna konfiguracija alata za pregled
	"""
    print 'Uporedjivanje fajlova prepravljenog zadatka sa verzijama fajlova koje je ostavio student...'

    # Biće pretraženi alt i current direktorijumi i biće pokrenut vizuelni diff za fajlove koji se razlikuju:
    onlyfiles = [
        f for f in os.listdir(config.CURRENT_ALT_ASSIGNMENT_PATH)
        if path.isfile(join(config.CURRENT_ALT_ASSIGNMENT_PATH, f))
    ]
    found = False
    for f in onlyfiles:
        alt = join(config.CURRENT_ALT_ASSIGNMENT_PATH, f)
        student = join(config.CURRENT_ASSIGNMENT_PATH, f)
        # Diff se vrši samo ako isti fajl postoji i u config.CURRENT_ASSIGNMENT_PATH direktorijumu:
        if path.isfile(student) and not util.filename_matches(
                f, backend.get_ignore_files_pattern()):
            if not util.cmp_files_ignore_newlines(alt, student):
                found = True
                command = config.VISUAL_DIFF_CMD.format(student, alt)
                ret = call(command, shell=True)
                if ret != 0:
                    util.fatal_error(
                        '''Pokretanje vizuelnog diff alata nije uspelo!
Komanda koja je pokrenuta:\n{0}'''.format(command))
    if not found:
        print 'Trenutno nema razlika izmedju prepravljenog zadatka i studentske verzije!'
Esempio n. 3
0
def destroy(cloud_name, name):
    try:
        driver = cloud.get_cloud_driver(cloud_name)
        key = driver.get_key_pair(name)
        driver.delete_key_pair(key)
    except Exception as e:
        util.fatal_error(str(e))
Esempio n. 4
0
    def __init__(self, data_config, save_dir, data_filenames=None):
        self.data_config = data_config
        self.save_dir = save_dir

        # self.vocab_sizes = {}
        self.joint_label_lookup_maps = {}
        self.reverse_maps = {}
        self.vocab_maps = {}
        self.vocab_lookups = None
        self.oovs = {}

        # make directory for vocabs
        self.vocabs_dir = "%s/assets.extra" % save_dir
        if not os.path.exists(self.vocabs_dir):
            try:
                os.mkdir(self.vocabs_dir)
            except OSError as e:
                util.fatal_error("Failed to create vocabs directory: %s; %s" %
                                 (self.vocabs_dir, e.strerror))
            else:
                tf.logging.log(
                    tf.logging.INFO,
                    "Successfully created vocabs directory: %s" %
                    self.vocabs_dir)
        else:
            tf.logging.log(tf.logging.INFO,
                           "Using vocabs directory: %s" % self.vocabs_dir)

        self.vocab_names_sizes = self.make_vocab_files(self.data_config,
                                                       self.save_dir,
                                                       data_filenames)
Esempio n. 5
0
def dispatch(fn_name):
    try:
        tf.logging.log(
            tf.logging.INFO, f"evaluation_fns_np.dispatch({fn_name}) => "
            f" {fn_dispatcher[fn_name]}")
        return fn_dispatcher[fn_name]
    except KeyError:
        util.fatal_error(f"evaluation_fns_np.dispatch: "
                         f"Undefined evaluation function '{fn_name}'")
Esempio n. 6
0
def get_accumulator(fn_name):
    try:
        tf.logging.log(
            tf.logging.INFO,
            f"evaluation_fns_np.get_accumulator({fn_name}) => "
            f"{accumulator_factory[fn_name]}")
        return accumulator_factory[fn_name]()
    except KeyError:
        util.fatal_error((f"get_accumulator: Undefined evaluation function ",
                          f"'{fn_name}'"))
Esempio n. 7
0
def open_assignment(backend, config, station):
	"""
	Otvara pojedinačan studentski zadatak na osnovu zadatog naziva računara na kojem je urađen zadatak

	Zadatak se kopira na putanju config.CURRENT_ASSIGNMENT_PATH, trenutno selektovan računar se menja na zadati.
	Nakon toga poziva se metoda backend.after_assignment_loaded() koja dozvoljava dodatne akcije nakon otvaranja
	zadatka.

	config - globalna konfiguracija alata za pregled
	station - oznaka računara na kojem je zadatak urađen
	"""
	print 'Otvaranje studentskog zadatka sa racunara {0}...'.format(station)
	logging.info('Otvaranje studentskog zadatka sa racunara: {0}'.format(station))

	start_dir = join(config.ASSIGNMENTS_PATH, station)
	matches = backend.find_project_recursive(start_dir)

	if len(matches) == 0:
		print bcolors.FAIL \
              + 'U direktorijumu "{0}" nije pronadjen fajl za identifikaciju projekta (pattern: "{1}")!'\
                  .format(start_dir, backend.get_project_pattern()) + bcolors.ENDC
		return False
	if len(matches) > 1:
		print bcolors.FAIL \
              + 'U direktorijumu "{0}" pronadjeno je vise direktorijuma kandidata za projektni direktorijum: {1}!'\
                  .format(start_dir, matches) + bcolors.ENDC
		return False

	util.clear_directory(config.CURRENT_ASSIGNMENT_PATH)
	util.clear_directory(config.CURRENT_ALT_ASSIGNMENT_PATH)

	onlyfiles = [f for f in os.listdir(matches[0]) if path.isfile(join(matches[0], f))]
	for file in onlyfiles:
		src = join(matches[0], file)
		dst = join(config.CURRENT_ASSIGNMENT_PATH, os.path.basename(file))
		copyfile(src, dst)

	alt = join(config.ALTERED_ASSIGNMENTS_PATH, station)
	if path.isdir(alt):
		print bcolors.BOLD + 'Postoji i izmenjeno resenje ovog zadatka, pa se ono kopira u: "{0}"'\
            .format(config.CURRENT_ALT_ASSIGNMENT_PATH) + bcolors.ENDC
		onlyfiles = [f for f in os.listdir(alt) if path.isfile(join(alt, f))]
		for file in onlyfiles:
			src = join(alt, file)
			dst = join(config.CURRENT_ALT_ASSIGNMENT_PATH, os.path.basename(file))
			copyfile(src, dst)

	write_current_station(config, station)

	proj = basename(util.identify_project_file(backend, config.CURRENT_ASSIGNMENT_PATH))
	print('Identifikovani projektni fajl: {0}'.format(proj))
	try:
		backend.after_assignment_loaded(config.CURRENT_ASSIGNMENT_PATH, proj)
	except RuntimeError as err:
		util.fatal_error(err.message)
Esempio n. 8
0
    def get_embedding_table(self,
                            name,
                            embedding_dim,
                            include_oov,
                            pretrained_fname=None,
                            num_embeddings=None,
                            cwr_ood=False):
        if False:
            pass
        else:
            with tf.variable_scope("%s_embeddings" % name):
                initializer = tf.random_normal_initializer()
                if pretrained_fname:
                    pretrained_embeddings = util.load_pretrained_embeddings(
                        pretrained_fname)

                    pretrained_num_embeddings, pretrained_embedding_dim = pretrained_embeddings.shape
                    if pretrained_embedding_dim != embedding_dim:
                        util.fatal_error(
                            "Pre-trained %s embedding dim does not match specified dim (%d vs %d)."
                            % (name, pretrained_embedding_dim, embedding_dim))
                    if num_embeddings and num_embeddings != pretrained_num_embeddings:
                        util.fatal_error(
                            "Number of pre-trained %s embeddings does not match specified "
                            "number of embeddings (%d vs %d)." %
                            (name, pretrained_num_embeddings, num_embeddings))
                    num_embeddings = pretrained_num_embeddings
                    if not cwr_ood:
                        num_embeddings -= 1
                        pretrained_embeddings = pretrained_embeddings[:-1, :]
                    initializer = tf.constant_initializer(
                        pretrained_embeddings)

                embedding_table = tf.get_variable(
                    name="embeddings",
                    shape=[num_embeddings, embedding_dim],
                    initializer=initializer)

                if include_oov:
                    oov_embedding = tf.get_variable(
                        name="oov_embedding",
                        shape=[1, embedding_dim],
                        initializer=tf.random_normal_initializer())
                    embedding_table = tf.concat(
                        [embedding_table, oov_embedding],
                        axis=0,
                        name="embeddings_table")

                return embedding_table
Esempio n. 9
0
def execute_build_command(backend, config, criteria, comp, stations,
                          current_assignment_path, autobuild_path):
    """
	Izvršenje komande koja obavlja kompajliranje zadatka

	backend - back-end koji se trenutno koristi
	config - globalna konfiguracija alata za pregled
	criteria - kriterijum pregleda zadatka (bodovanje, način izvršavanja itd.)
	comp - oznaka računara na kojem je urađen zadatak koji se pregleda
	stations - kolekcija računara i studenata koji su radili zadatak (ključ - oznaka računara, podatak - lista - broj
	           indeksa i ime/prezime studenta)
	current_assignment_path - putanja na kojoj se nalazi studentski zadatak koji se kompajlira
	autobuild_path - putanja na kojoj se nalazi autobuild varijanta tekućeg zadatka
	"""
    logging.info(
        'Pokrenuto je kompajliranje tekuceg projekta u direktorijumu: {0}'.
        format(current_assignment_path))

    build_report_path = join(autobuild_path,
                             backend.get_build_report_filename())

    code = internal_build_project(backend, config, criteria,
                                  current_assignment_path, autobuild_path)
    if code == 0:
        print bcolors.OKGREEN + 'Kompajliranje projekta je uspesno.' + bcolors.ENDC
    elif code == 1:
        print bcolors.FAIL + '''Kompajliranje projekta je generisalo upozorenja!
Mozete nastaviti sa izvrsenjem testova, ukoliko zelite da pregledate izvestaj o kompajliranju, on se nalazi u fajlu: "{0}"'''.format(
            backend.get_build_report_filename()) + bcolors.ENDC
    else:
        if vm_build_error(build_report_path):
            util.fatal_error('''Kompajliranje projekta je neuspesno. 
Razlog neuspeha je cinjenica da je sva virtuelna memorija potrosena.
Najbolje je da restartujete sistem pa potom nastavite pregled.''')
        else:
            print bcolors.FAIL \
               + 'Kompajliranje projekta je neuspesno. Bice prikazan fajl ("{0}") sa izvestajem kompajliranja.'\
                .format(backend.get_build_report_filename()) + bcolors.ENDC
            raw_input('Pritisnite <ENTER> za nastavak...')
            util.show_text_edit(config, build_report_path)
            final_report.update_final_report(
                config,
                criteria,
                stations,
                comp,
                datetime.datetime.now().isoformat(),
                status=ASSIGNMENT_STATUS_FAILS_TO_COMPILE)
            sys.exit(0)
Esempio n. 10
0
    def read_criteria_file(self, config):
        if path.isfile(config.RATING_CRITERIA_FILENAME):
            logging.debug(
                'Ucitavanje sadrzaja kriterijumskog fajla: "{0}"'.format(
                    config.RATING_CRITERIA_FILENAME))
            with open(config.RATING_CRITERIA_FILENAME) as data_file:
                try:
                    data = json.load(data_file)
                except ValueError:
                    util.fatal_error(
                        'Fajl sa kriterijumom pregledanja nije u dobrom formatu!'
                    )

            try:
                self.backend_selection = data['backend']
                self.assignment_files = data['files']
                self.score_distribution = data['tests']
                self.blocking_tests = data['blockers']
                self.total_points = data['total_points']
            except KeyError as err:
                util.fatal_error(
                    'Podešavanje "{0}" nedostaje u kriterijumskom fajlu.'.
                    format(err.message))

            # runs opcija nije obavezna. Ako se ne zada, koriste se podrazumevane vrednosti:
            if 'runs' in data:
                self.runs_spec = data['runs']
            else:
                self.runs_spec = {"total": 1, "pass_limit": 1}

            # Formiranje ukupnog težinskog faktora - koji je zbir pojedinačnih težinskih faktora svih testova
            self.total_weight = 0
            for s in self.score_distribution:
                self.total_weight += s.values()[0]

            # Formiranje pojedinačnih procentualnih vrednosti testova - određuje se u odnosu na ta koliko procentualno
            # iznosi težina datog testa u odnosu na ukupan težinski faktor
            for i, s in enumerate(self.score_distribution):
                self.score_distribution[i] = {
                    s.keys()[0]: {
                        "factor":
                        s.values()[0],
                        "percent":
                        float(s.values()[0]) / self.total_weight * 100.00
                    }
                }

            # Provera da li je lista blokirajućih testova validna:
            for b in self.blocking_tests:
                if self.score_distribution[b] is None:
                    util.fatal_error(
                        '''Test pod nazivom "{0}" definisan je kao blokirajuc a pritom nije definisano bodovanje za njega (u fajlu sa kriterijumom ocenjivanja: "{1}")'''
                        .format(b, config.RATING_CRITERIA_FILENAME))
        else:
            util.fatal_error(
                'Kriterijumski fajl nije pronadjen pod nazivom: {0}'.format(
                    config.RATING_CRITERIA_FILENAME))
Esempio n. 11
0
def list_cloud_keys(cloud_name):
    try:
        driver = cloud.get_cloud_driver(cloud_name)
        kk = driver.list_key_pairs()
    except Exception as e:
        util.fatal_error(str(e))

    headers = ['Name']
    keys = ['name']

    jsonList = []

    for key in kk:
        dict = {}
        dict['name'] = key.name

        jsonList.append(dict)

    util.print_list(headers, keys, jsonList)

    return
Esempio n. 12
0
def show_diffs_from_initial(backend, config):
    """
	Pokreće vizuelni diff alat kako bi se prikazale razlike između trenutnog zadatka i postavke zadatka

	backend - back-end koji se trenutno koristi
	config - globalna konfiguracija alata za pregled
	"""
    initfiles = [
        f for f in os.listdir(config.INITIAL_PROJECT_PATH)
        if path.isfile(join(config.INITIAL_PROJECT_PATH, f))
    ]
    if len(initfiles) == 0:
        util.fatal_error(
            'U folder "{0}" potrebno je kopirati fajlove koji cine postavku zadatka!'
            .format(config.INITIAL_PROJECT_PATH))

    print 'Uporedjivanje fajlova zadatka sa pocetnim verzijama fajlova...'
    onlyfiles = [
        f for f in os.listdir(config.CURRENT_ASSIGNMENT_PATH)
        if path.isfile(join(config.CURRENT_ASSIGNMENT_PATH, f))
    ]
    found = False
    for f in onlyfiles:
        init = join(config.INITIAL_PROJECT_PATH, f)
        if not util.filename_matches(f, backend.get_ignore_files_pattern()):
            if not path.isfile(init):
                init = '/dev/null'
            student = join(config.CURRENT_ASSIGNMENT_PATH, f)
            if (init == '/dev/null'
                    or (not util.cmp_files_ignore_newlines(init, student))):
                found = True
                command = config.VISUAL_DIFF_CMD.format(init, student)
                ret = call(command, shell=True)
                if ret != 0:
                    util.fatal_error(
                        '''Pokretanje vizuelnog diff alata nije uspelo!
Komanda koja je pokrenuta:\n{0}'''.format(command))
    if not found:
        print 'Trenutno nema razlika izmedju studentskog zadatka i pocetne verzije!'
Esempio n. 13
0
    def parse_testing_artefacts(self, test_name, dir_path, blocking_tests,
                                unique_id):
        blocker = test_name in blocking_tests

        gtest_status_path = self.get_status_report_path(
            dir_path, test_name, unique_id)
        gtest_report_name = self.get_testing_report_filename(
            test_name, unique_id)

        # Očitavanje statusnog koda koji je dobijen prilikom izvršenja testa (nalazi se u posebnom tekstualnom fajlu):
        if not os.path.isfile(gtest_status_path):
            raise RuntimeError(
                '''Nije uspelo izvrsenje testova - fajl sa statusom izvrsenja ({0}) nije pronadjen.
Ovo je interna greska, kontaktirati autora alata.'''.format(gtest_status_path))

        with open(gtest_status_path, 'r') as f:
            status_str = f.read()

        try:
            status = int(status_str)
        except ValueError:
            raise RuntimeError(
                '''Sadrzaj fajla sa statusom izvrsenja nije u skladu sa ocekivanim. Fajl: {0}
Ovo je interna greska, kontaktirati autora alata.'''.format(gtest_status_path))

        # Sistemski program "timeout" koji se koristi za pokretanje testova vraća kod 124 ukoliko je prekinuo predugo
        # izvršenje:
        if status == 0:
            pass  # Tek treba da se odredi da li je test prošao ili ne, za sada se samo zna da je izvršenje prošlo

        elif status == 124:
            return SingleRunResult(name=test_name,
                                   result='timed-out',
                                   duration=float(self.execution_timeout),
                                   blocker=blocker)

        # Ovde je obrađena malo komplikovanija situacija.
        # Ako je povratni kod 'timeout' komande 1 - onda ima dva podslučaja.
        # Prvi, češći podslučaj je da to indikuje da je pokrenuti test pao.
        # Drugi, ređi podslučaj je da to indikuje nasilni prekid izvršenja testa, usled segfault-a ili slično. U tom slučaju, nema analize rezultata testa.

        elif (status == 1 and (not self.is_execution_report_created(
                dir_path, test_name, unique_id))) or status > 1:
            return SingleRunResult(name=test_name,
                                   result='crashed',
                                   duration=0,
                                   blocker=blocker)

        # Učitavanje XML fajla sa rezultatom izvršenja, ako ima takvog fajla:

        filename = join(dir_path, gtest_report_name)
        error_message = '''Interna greska: format XML fajla sa rezultatima testiranja nije validan!
Fajl cije parsiranje nije uspelo: {0}'''.format(filename)

        if not os.path.isfile(filename):
            raise RuntimeError(
                '''Nije uspelo izvrsenje testova - fajl sa izvestajem ({0}) nije pronadjen.
Ovo verovatno ukazuje na timeout prilikom izvrsenja.'''.format(filename))

        e = ElementTree.parse(filename).getroot()

        if e.tag != 'testsuites':
            raise RuntimeError(error_message)

        for suite in e:
            if not 'name' in suite.attrib:
                raise RuntimeError(error_message)

            suite_name = suite.attrib['name']
            for case in suite:
                blocker = False

                if case.tag != 'testcase':
                    raise RuntimeError(error_message)
                if not 'name' in case.attrib:
                    raise RuntimeError(error_message)
                if not 'status' in case.attrib:
                    raise RuntimeError(error_message)

                name = '{0}.{1}'.format(suite_name, case.attrib['name'])

                # Proverava da li je definisano bodovanje za test koji je izvrsen:
                if name != test_name:
                    util.fatal_error(
                        'Interna greska! Fajl sa izvestajem ne sadrzi rezultate odgovarajuceg testa.\n'
                        + 'Kontaktirati autora alata.')

                if case.attrib['status'] == 'run':
                    if case.find('failure') is None:
                        execution = 'passed'
                    else:
                        execution = 'failed'
Esempio n. 14
0
    data_root_logs = os.path.join(data_root, "logs")
    if not os.path.isdir(data_root_logs):
        os.mkdir(data_root_logs)
    pg_log = os.path.join(data_root_logs, pgver)
    if not os.path.isdir(pg_log):
        os.mkdir(pg_log)
    if util.get_platform() == "Windows":
        print("Giving current user permission to log dir")
        cur_user = getpass.getuser()
        batcmd = 'icacls "' + pg_log + '" /grant "' + cur_user + \
                 '":(OI)(CI)F'
        err = os.system(batcmd)
        if err:
            msg = "ERROR: Unable to set permissions on log dir " + \
                  " (err=" + str(err) + ")"
            util.fatal_error(msg)
    util.set_column("logdir", pgver, pg_log)

if args.svcname > '':
    util.set_column("svcname", pgver, args.svcname)

## AUTOSTART ###########################################
if ((args.autostart is None) or (autostart == args.autostart)):
    sys.exit(0)

if util.get_platform() == "Windows":
    datadir = util.get_column('datadir', pgver)
    svcname = util.get_column('svcname', pgver,
                              'PostgreSQL ' + dotver + ' Server')
    cmd_file = tempfile.mktemp(".bat")
    fh = open(cmd_file, "w")
Esempio n. 15
0
    '--attention_configs',
    help='Comma-separated list of paths to attention configuration json.')
arg_parser.add_argument(
    '--combine_test_files',
    action='store_true',
    help='Whether to combine list of test files into a single score.')

arg_parser.set_defaults(debug=False)
arg_parser.set_defaults(combine_test_files=False)

args, leftovers = arg_parser.parse_known_args()

util.init_logging(tf.logging.INFO)

if not os.path.isdir(args.save_dir):
    util.fatal_error("save_dir not found: %s" % args.save_dir)

# Load all the various configurations
# todo: validate json
data_config = train_utils.load_json_configs(args.data_config)
model_config = train_utils.load_json_configs(args.model_configs)
task_config = train_utils.load_json_configs(args.task_configs, args)
layer_config = train_utils.load_json_configs(args.layer_configs)
attention_config = train_utils.load_json_configs(args.attention_configs)

# attention_config = {}
# if args.attention_configs and args.attention_configs != '':
#   attention_config =

# Combine layer, task and layer, attention maps
# layer_task_config = {}
Esempio n. 16
0
def unpack_assignments(config, stations, two_groups):
    """
	Raspakuje arhivu sa svim studentskim radovima iz direktorijuma config.ARCHIVE_PATH

	config - globalna konfiguracija alata za pregled
	stations - kolekcija računara i studenata koji su radili zadatak (ključ - oznaka računara, podatak - lista - broj
	           indeksa i ime/prezime studenta)
	two_groups - boolean koji indikuje da li je zadatak rađen u dve grupe (A i B)
	"""
    util.make_sure_path_exists(config.TEMP_PATH)

    # Ukoliko se u prihvatnom direktorijumu nalazi arhiva, ona će biti raspakovana u direktorijum sa studentskim
    # zadacima i potom premeštena u backup direktorijum:
    archives = glob.glob(
        join(config.ARCHIVE_PATH, config.ASSIGNMENTS_ARCHIVE_PATTERN))
    found = 0
    for a in archives:
        found = found + 1
        print 'Pronadjena je nova arhiva sa zadacima koja ce biti obradjena'
        print 'Raspakivanje arhive "{0}" u direktorijum "{1}"...'.format(
            a, config.TEMP_PATH)
        command = config.EXTRACT_ASSIGNMENTS_CMD.format(a, config.TEMP_PATH)
        ret = call(command, shell=True)
        if ret != 0:
            util.fatal_error(
                'Raspakivanje arhive sa zadacima je neuspesno!\nKomanda koja je pokrenuta:\n{0}'
                .format(command))

    if found == 0:
        util.fatal_error('''Nije pronadjena arhiva sa zadacima! 
Molim proverite da li arhiva koju ste prilozili ima adekvatan naziv i adekvatnu ekstenziju! 
Ocekuje se naziv poput sledeceg: {0}'''.format(
            config.ASSIGNMENTS_ARCHIVE_PATTERN))

    # Učitavanje liste studenata iz raspakovanog sadrzaja arhive:
    matches = glob.glob(join(config.TEMP_PATH, config.STUDENTS_LIST_PATTERN))

    if len(matches) == 0:
        util.fatal_error(
            'Nije pronadjena lista studenata (pattern za trazenje: "{0}")'.
            format(config.STUDENTS_LIST_PATTERN))
    if len(matches) > 1:
        util.fatal_error(
            'Pronadjen je vise od jednog fajla koji je kandidat za listu studenata. Kandidati: {0}'
            .format(matches))

    # Ako zadatak ima samo jednu grupu (nema grupe A i B), onda se lista studenata samo kopira na destinaciju
    # (neće biti njene podele na dve podgrupe):
    if not two_groups:
        copyfile(matches[0], join(config.ASSIGNMENTS_PATH,
                                  basename(matches[0])))

    logging.debug(
        'Ucitavanje spiska studenata prilikom raspakivanja arhive...')
    ifile = open(matches[0], "rb")
    reader = csv.DictReader(ifile,
                            dialect='excel',
                            fieldnames=['station', 'id', 'name'])
    for row in reader:
        station = row['station'].strip()
        id = row['id'].strip()
        name = row['name'].strip()
        if id:
            logging.debug(
                'Ucitano: Stanica: {0}, Broj indeksa: {1}, Ime: {2}'.format(
                    station, id, name))
            stations[station] = [id, name]
    ifile.close()
    logging.debug('Ucitavanje spiska studenata zavrseno')

    if two_groups:
        group1_list = open(
            join(config.GROUP1_DIR, config.ASSIGNMENTS_PATH,
                 "spisak_stud_koji_trenutno_rade_proveru.txt"), "a+")
        group2_list = open(
            join(config.GROUP2_DIR, config.ASSIGNMENTS_PATH,
                 "spisak_stud_koji_trenutno_rade_proveru.txt"), "a+")

    # Arhive koje su pronađene u direktorijumu sa studentskim zadacima biće raspakovane i potom obrisane:
    archives = sorted(
        glob.glob(
            join(config.TEMP_PATH, config.SINGLE_ASSIGNMENT_ARCHIVE_PATTERN)))
    for a in archives:
        logging.debug(
            'Pronadjena je sledeca arhiva sa pojedinacnim zadatkom: {0}'.
            format(a))

        # Manipulacija nazivom arhive, kako bi se došlo do oznake stanice na kojoj je student radio:
        name = os.path.basename(a)[:-len(config.SINGLE_ASSIGNMENT_ARCHIVE_EXT)]
        tokens = name.split('_')
        station = tokens[len(tokens) - 1]

        # Proces kopiranja zadataka vođen je spiskom studenata koji su radili proveru.
        # Ako stanica nije na tom spisku, znači da je u pitanju blanko direktorijum i on se preskače.
        if station in stations:
            if two_groups:
                station_num = int(station[1:])
                if station_num % 2 == 0:
                    station_directory = join(config.GROUP1_DIR,
                                             config.ASSIGNMENTS_PATH, station)
                    if not station in stations:
                        util.fatal_error(
                            'Racunar sa oznakom "{0}" nije pronadjen u spisku studenata koji rade proveru!'
                            .format(station))
                    group1_list.write('{0}, {1}, {2}\n'.format(
                        station, stations[station][0], stations[station][1]))
                else:
                    station_directory = join(config.GROUP2_DIR,
                                             config.ASSIGNMENTS_PATH, station)
                    if not station in stations:
                        util.fatal_error(
                            'Racunar sa oznakom "{0}" nije pronadjen u spisku studenata koji rade proveru!'
                            .format(station))
                    group2_list.write('{0}, {1}, {2}\n'.format(
                        station, stations[station][0], stations[station][1]))
            else:
                station_directory = join(config.ASSIGNMENTS_PATH, station)

            logging.debug(
                'Raspakivanje zadatka "{0}" u direktorijum "{1}"'.format(
                    a, station_directory))
            util.make_sure_path_exists(station_directory)
            command = config.EXTRACT_SINGLE_ASSIGNMENT_CMD.format(
                a, station_directory)
            ret = call(command, shell=True)
            if ret != 0:
                util.fatal_error(
                    'Raspakivanje pojedinacnog zadatka je neuspesno!\nKomanda koja je pokrenuta:\n{0}'
                    .format(command))
            os.remove(a)

    util.clear_directory(config.TEMP_PATH)
Esempio n. 17
0
def update_final_report(config, criteria, stations, station, time, status = None, comment = None, results = None,
						score = None, correction = None):
	"""
	Ažurira finalni izveštaj sa pojedinačnim elementom ocene zadatka

	Mehanizam rada je takav da će menjati samo jedan <assignment> nod u XML fajlu i to onaj koji se tiče zadatka kojem
	se prijavljuju izmene u rezultatu. Ostatak sadržaja neće biti učitavan i menjan.

	config - globalna konfiguracija alata za pregled
	criteria - kriterijum pregleda zadatka (bodovanje, način izvršavanja itd.)
	stations - kolekcija računara i studenata koji su radili zadatak (ključ - oznaka računara, podatak - lista - broj
	           indeksa i ime/prezime studenta)
	station - oznaka računara na kojem je zadatak urađen
	time - timestamp poslednje izmene na rezultatima
	status - status celog zadatka
	comment - komentar pregledača na zadatak
	results - lista tuple objekata TestResults - rezultat izvršenja testova
	score - procentualni učinak studenta na zadatku
	correction - korekcija koju je pregledač uveo
	"""
	print 'Azuriranje XML fajla sa izvestajem sa ispita: "{0}"'.format(config.FINAL_REPORT_FILENAME)

	try:
		criteria.total_points # Provera da li je definisana varijabla
	except NameError:
		criteria.total_points = 100

	total_points_f = float(criteria.total_points)

	if not (results is None):
		total = 0.0
		for r in results:
			if r.success:
				total += r.score

	# Ako fajl ne postoji, kreiraj korenski element:
	if not(path.isfile(config.FINAL_REPORT_FILENAME)):
		root = objectify.Element('assignments')
	else:
		with open(config.FINAL_REPORT_FILENAME) as f:
			xml = f.read()
 
		root = objectify.fromstring(xml)

	# Probaj pronaci <assignment> tag koji se odnosi na zadatu stanicu:
	assign = None
	for a in root.getchildren():
		if a.get('station') == station:
			assign = a

	# Ako prethodno ne postoji takav <assignment>, kreiraj novi:
	if assign == None:
		assign = objectify.SubElement(root, 'assignment')
		# Podesi nove podatke:
		assign.set('station', station)
		assign['id'] = stations[station][0]
		assign['name'] = stations[station][1]

	# Podesi nove podatke:
	assign.time = time

	if not (results is None):
		assign['test-score'] = '{:.2f}'.format(total)

	if not (comment is None):
		assign['comment'] = comment

	if not (score is None):
		assign['direct-score'] = '{:.2f}'.format(score)
		assign['final-pct'] = '{:.2f}'.format(score)

	if not (correction is None):
		# Ako je zadata korekcija 0 - onda se korekcija ukida:
		if correction == 0:
			sub = assign.find('correction')
			if (sub is not None):
				assign.remove(sub)

		else:
			assign['correction'] = '{:+.2f}'.format(correction)

		final_number = 0
		reason = u'nema uspešnih testova'
		if assign.find('test-score') is not None:
			final_number = float(assign['test-score'])
			reason = u'{:+.2f}% na uspešne testove'.format(final_number)
		if correction != 0:
			final_number = final_number + correction
			reason = reason + u' i {:+.2f}% korekcija'.format(correction)
		
		final = '{:.2f}'.format(final_number)
		points = int(round(final_number * (total_points_f / 100.0), 0))

		assign['final-pct'] = final
		assign['final-points'] = points
		assign['reason'] = reason

	if not (results is None):
		# Ako je bilo direktno zadatog rezultata, nakon što su izvršeni automatski testovi, taj skor se briše:
		sub = assign.find('direct-score')
		if (sub is not None):
			assign.remove(sub)

		while True:
			sub = assign.find('tests')
			if (sub is None):
				break;
			assign.remove(sub)
		
		tests_root = objectify.SubElement(assign, 'tests')
		for r in results:
			test = objectify.SubElement(tests_root, 'test')
			test.attrib['name'] = r.name
			test['runs'] = r.runs
			test['passes'] = r.passes
			test['failures'] = r.failures
			test['test-fails'] = r.test_fails
			test['crashes'] = r.crashes
			test['time-outs'] = r.time_outs
			test['total-duration'] = '{:.2f}'.format(r.total_duration)
			test['max-duration'] = '{:.2f}'.format(r.max_duration)
			test['success'] = r.success
			test['score'] = '{:.2f}'.format(r.score)
			test['factor'] = r.factor

			executions = objectify.SubElement(test, 'executions')
			for e in r.executions:
				elem = objectify.SubElement(executions, 'passed')
				elem._setText(str(e).lower())

	# Logika za odredjivanje broja poena, u odnosu na status rada i ostale parametre:
	if not (status is None):
		assign['status'] = status

		if status == ASSIGNMENT_STATUS_BLOCKED:
			final = '0'
			points = 0
			reason = u'makar jedan od blokirajućih testova ne prolazi'

		elif status == ASSIGNMENT_STATUS_FAILS_TO_COMPILE:
			final = '0'
			points = 0
			reason = u'projekat se ne kompajlira uspešno'

		elif status == ASSIGNMENT_STATUS_DIRECTLY_RATED:
			final = assign['direct-score']
			final_number = float(assign['direct-score'])
			points = int(round(final_number * (total_points_f / 100.0), 0))

			reason = u'direktno zadata ocena'

		elif status == ASSIGNMENT_STATUS_OK:
			final_number = float(assign['test-score'])
			reason = u'{0}% na uspešne testove'.format(final_number)
			sub = assign.find('correction')
			if (sub is not None):
				corr = float(assign['correction'])
				final_number = final_number + corr
				reason = reason + u' i {:+.2f}% korekcija'.format(corr)
			final = '{:.2f}'.format(final_number)
			points = int(round(final_number * (total_points_f / 100.0), 0))

		elif status == ASSIGNMENT_STATUS_SKIPPED:
			final_number = 0
			points = 0
			final = '{:.2f}'.format(final_number)
			reason = u'rad je preskočen'

		else:
			util.fatal_error('''Interna greska: status "{0}" nema definisana pravila za bodovanje!
Kontaktirati autora programa.'''.format(status))

		assign['final-pct'] = final
		assign['final-points'] = points
		assign['reason'] = reason

	# Upiši izmenjen fajl:
	f = open(config.FINAL_REPORT_FILENAME, 'w')
	objectify.deannotate(root)	# Skidanje objectify anotacija
	# Dodaje se XML zaglavlje u kojem se navodi UTF-8 kao upotrebljeno enkodiranje i referencira se XSLT dokument:
	f.write('<?xml version="1.0" encoding="UTF-8"?>\n<?xml-stylesheet type="text/xsl" href="{0}"?>\n'
			.format(config.FINAL_REPORT_XSLT_FILENAME))
	f.write(etree.tostring(root, xml_declaration=False, encoding='utf-8', pretty_print=True))
	f.close()
Esempio n. 18
0
def import_from_file(cloud_name, name, pub_key_file):
    try:
        driver = cloud.get_cloud_driver(cloud_name)
        driver.import_key_pair_from_file(name, pub_key_file)
    except Exception as e:
        util.fatal_error(str(e))
Esempio n. 19
0
def execute_run_tests_command(backend, config, criteria, stations, run_path,
                              comp):
    """
	Izvršenje komande koja obavlja pokretanje svih testova za zadatak

	backend - back-end koji se trenutno koristi
	config - globalna konfiguracija alata za pregled
	criteria - kriterijum pregleda zadatka (bodovanje, način izvršavanja itd.)
	stations - kolekcija računara i studenata koji su radili zadatak (ključ - oznaka računara, podatak - lista - broj
	           indeksa i ime/prezime studenta)
	run_path - putanja na kojoj se nalazi studentski zadatak čiji se testovi izvršavaju
	comp - oznaka računara na kojem je urađen zadatak koji se pregleda
	"""
    if not path.isdir(config.AUTOTEST_PATH):
        util.fatal_error(
            '''Prilikom postavljanja zadatka nije postavljena autotest varijanta zadatka.\n'
Ako zelite da koristite automatsko testiranje, kreirajte direktorijum "{0}" i postavite autotest varijantu u njega.'''
            .format(config.AUTOTEST_PATH))

    if not path.isdir(run_path):
        util.fatal_error(
            'Ne mogu se pokrenuti testovi jer projekat nije prethodno kompajliran.\n'
            + 'Upotrebite komandu build za kompajliranje projekta.')

    util.make_sure_path_exists(config.REPORTS_PATH)
    current_reports_path = join(config.REPORTS_PATH, comp)
    util.make_sure_path_exists(current_reports_path)
    util.clear_directory(current_reports_path)

    logging.info(
        'Pokrenuti su automatski testovi tekuceg projekta u direktorijumu: {0}'
        .format(run_path))

    proj = util.identify_project_file(backend, run_path)
    executable = backend.identify_project_executable(proj)

    all_results = []
    tests = []
    for s in criteria.score_distribution:
        tests.append(s.keys()[0])

    # Zakazivanje izvršenja testova od strane (potencijalno) više niti za izvršenje testova:

    print('Sledeci testovi ce biti izvrseni: {0}'.format(', '.join(tests)))
    print('Svaki test se izvrsava {0} put(a)'.format(
        criteria.runs_spec['total']))

    for t in tests:
        execution_results[t] = [None] * criteria.runs_spec['total']

    for i in range(backend.get_parallel_testing_threads_count()):
        t = Thread(target=execution_worker_thread,
                   args=(backend, criteria, i, run_path, executable))
        t.daemon = True
        t.start()

    for t in tests:
        test_index = 0
        for run in range(1, criteria.runs_spec['total'] + 1):
            execution_queue.put([
                test_index, t,
                get_console_report_path(config, comp, t, test_index)
            ])
            test_index += 1

    execution_queue.join()

    # Grupisanje dobijenih rezultata - konsolidacija rezultata po svakom pojedinačnom testu (po nazivu testa):

    for t in tests:
        results = execution_results[t]

        # Određivanje najdužeg vremena izvršenja ovog testa:
        max_duration = results[0].duration
        executions = []
        for r in results:
            if r.duration > max_duration:
                max_duration = r.duration
            executions.append(r.result == 'passed')

        passes = sum(1 for x in results if x.result == 'passed')

        entry = TestResults(
            name=t,
            runs=criteria.runs_spec['total'],
            passes=passes,
            failures=sum(1 for x in results if x.result != 'passed'),
            test_fails=sum(1 for x in results if x.result == 'failed'),
            crashes=sum(1 for x in results if x.result == 'crashed'),
            time_outs=sum(1 for x in results if x.result == 'timed-out'),
            total_duration=sum(x.duration for x in results),
            max_duration=max_duration,
            score=get_score(criteria, t)["percent"],
            factor=get_score(criteria, t)["factor"],
            success=(passes / float(criteria.runs_spec['total'])) >=
            criteria.runs_spec['pass_limit'],
            executions=executions)

        all_results.append(entry)

    # Ispis rezimea pokretanja testova na konzolu:

    total = len(criteria.score_distribution)
    passed = 0
    score = 0
    blockers = False
    for t in all_results:
        print ''
        header_line = 'TEST: {0}, ukupno izvrsenja: {1}'.format(t.name, t.runs)
        print '*' * len(header_line)
        print bcolors.BOLD + header_line + bcolors.ENDC
        print '*' * len(header_line)

        if t.runs < criteria.runs_spec['total']:
            print bcolors.FAIL \
               + 'Detektovano je dovoljno negativnih ishoda pa nije obavljeno svih {0} zahtevanih pokretanja'\
                .format(criteria.runs_spec['total']) + bcolors.ENDC

        if t.passes > 0:
            print bcolors.OKGREEN + 'PROSAO: {0} put(a)'.format(
                t.passes) + bcolors.ENDC
        if t.failures > 0:
            print bcolors.FAIL + 'PAO: {0} put(a), od toga:'.format(
                t.failures) + bcolors.ENDC
            if t.test_fails > 0:
                print bcolors.FAIL + '    Formirao los rezultat:       {0} put(a)'.format(
                    t.test_fails) + bcolors.ENDC
            if t.crashes > 0:
                print bcolors.FAIL + '    Nasilno prekinuo izvrsenje:  {0} put(a)'.format(
                    t.crashes) + bcolors.ENDC
            if t.time_outs > 0:
                print bcolors.FAIL + '    Prekoracio dozvoljeno vreme: {0} put(a)'.format(
                    t.time_outs) + bcolors.ENDC

        print 'Ukupno vreme izvrsenja: {0}, najduze pokretanje: {1}'.format(
            t.total_duration, t.max_duration)

        if t.success:
            print bcolors.OKGREEN + 'Test se smatra uspesnim, tezina: {0} (od ukupno {1}), procentualno: {2:.2f}%'\
             .format(t.factor, criteria.total_weight, t.score) + bcolors.ENDC
            passed += 1
            score += t.score
        else:
            print bcolors.FAIL + 'Test se smatra neuspesnim' + bcolors.ENDC
            if t in criteria.blocking_tests:
                blockers = True
                print bcolors.FAIL + 'Ovo je blokirajuci test!' + bcolors.ENDC

    print ''
    if passed == total:
        print bcolors.OKGREEN \
           + '''Uspesno su izvrseni svi testovi (ukupno je: {0} testova).\nUkupno ostvareno procenata: {1:.2f}%'''.format(total, score) + bcolors.ENDC
    else:
        failed = total - passed
        print bcolors.FAIL + '''Palo je {0} testova, od ukupno {1}!
Procenat testova koji prolaze: {2:.2f}%, procentualni ucinak: {3:.2f}%'''.format(
            failed, total,
            float(passed) / total * 100.0, score) + bcolors.ENDC

    status = ASSIGNMENT_STATUS_OK
    if blockers:
        print bcolors.FAIL + bcolors.BOLD \
           + 'Pao je makar jedan blokirajuci test! U izvestaju je naznaceno da u ovom radu postoje takvi testovi.' \
           + bcolors.ENDC
        status = ASSIGNMENT_STATUS_BLOCKED

    final_report.update_final_report(config,
                                     criteria,
                                     stations,
                                     comp,
                                     datetime.datetime.now().isoformat(),
                                     status=status,
                                     results=all_results)
Esempio n. 20
0
def internal_build_project(backend, config, criteria, current_assignment_path,
                           autobuild_path):
    """
	Interna pomoćna metoda koja vrši kompajliranje projekta (studentskog zadatka)

	backend - back-end koji se trenutno koristi
	config - globalna konfiguracija alata za pregled
	criteria - kriterijum pregleda zadatka (bodovanje, način izvršavanja itd.)
	current_assignment_path - putanja do zadatka koji se kompajlira
	autobuild_path - putanja na kojoj se nalazi autobuild varijanta tekućeg zadatka

	Vraća indikaciju da li je kompajliranje uspešno obavljeno
	0 - kompajliranje je uspešno
	1 - produkovan je izvršni fajl ali je kompajliranje vratilo upozorenja
	2 - kompajliranje je neuspešno
	"""
    logging.info(
        'Pokrenuto je kompajliranje projekta u direktorijumu: {0}'.format(
            current_assignment_path))

    # Brisanje trenutnog sadrzaja autobuild direktorijuma:
    print('Brisanje sadrzaja direktorijuma "{0}"'.format(autobuild_path))
    util.make_sure_path_exists(autobuild_path)
    util.clear_directory(autobuild_path)

    # Kopiranje svih fajlova iz osnovnog direktorijuma u autobuild poddirektorijum:
    print('Kopiranje izvornih fajlova iz "{0}" u "{1}"'.format(
        current_assignment_path, autobuild_path))
    onlyfiles = [
        f for f in os.listdir(current_assignment_path)
        if path.isfile(join(current_assignment_path, f))
    ]
    autotestfiles = [
        f for f in os.listdir(config.AUTOTEST_PATH)
        if path.isfile(join(config.AUTOTEST_PATH, f))
    ]

    for f in onlyfiles:
        if (f in criteria.assignment_files) or (
                f not in autotestfiles
                and filename_matches_assignment_pattern(backend, f)):
            copyfile(join(current_assignment_path, f), join(autobuild_path, f))

    # Obrada događaja koji se inicira pre nego što se obavi kompajliranje zadatka:
    try:
        backend.before_build(autobuild_path)
    except RuntimeError as err:
        util.fatal_error(err.message)

    # Kopiranje dodatnih fajlova iz autotest direktorijuma u autobuild poddirektorijum:
    print('Kopiranje autotest fajlova iz "{0}" u "{1}"'.format(
        config.AUTOTEST_PATH, autobuild_path))

    if len(autotestfiles) == 0:
        util.fatal_error(
            'Projekat se ne moze kompajlirati jer autotest varijanta zadatka nije postavljena u direktorijum: "{0}"!'
            .format(config.AUTOTEST_PATH))

    for f in autotestfiles:
        # Proverava se da li je fajl naveden u listi fajlova u kojima studenti unose resenje zadatka.
        # Ako je tako, onda taj fajl ne bi smeo da bude postavljen u autotest folder.
        if f in criteria.assignment_files:
            util.fatal_error(
                '''Fajl "{0}" je postavljen u "{1}" direktorijum a ocekuje se da studenti unose svoje resenje u taj fajl.
Fajlovi iz "{1}" direktorijuma kopiraju se preko studentskog resenja, tako da bi kopiranjem ovog fajla unistili kljucni deo resenja.
Molim da procitate deo uputstva za koriscenje alata za pregled koji se odnosi na postavljanje fajlova u ovaj direktorijum.'''
                .format(f, config.AUTOTEST_PATH))

        copyfile(join(config.AUTOTEST_PATH, f), join(autobuild_path, f))

    # Potom, sledi kompajliranje projekta:
    ret = backend.build_project(
        util.identify_project_file(backend, autobuild_path))

    # Poslednja linija izvešaja o kompajliranju treba da sadrži informaciju o potencijalnim upozorenjima i greškama tokom kompajliranja:

    f = open(join(autobuild_path, backend.get_build_report_filename()), 'r')
    lines = f.readlines()
    last_line = lines[len(lines) - 1]
    regex = re.compile(
        '(?P<errors>\d+)\serror\(s\),\s(?P<warnings>\d+)\swarning\(s\)',
        re.IGNORECASE)
    m = regex.match(last_line)

    if m:
        errors = int(m.group('errors'))
        warnings = int(m.group('warnings'))

        if (errors == 0 and warnings == 0):
            return 0

        if (errors == 0):
            return 1

        return 2
    else:
        util.fatal_error(
            '''Interna greska: izvestaj o kompajliranju ne sadrzi poslednju liniju sa brojem gresaka i upozorenja.
Nije moguce utvrditi ishod kompajliranja. Potrebno je kontaktirati autora alata.'''
        )
Esempio n. 21
0
def dispatch(fn_name):
    try:
        return fn_dispatcher[fn_name]
    except KeyError:
        util.fatal_error('Undefined evaluation function `%s' % fn_name)
Esempio n. 22
0
def get_accumulator(fn_name):
    try:
        return accumulator_factory[fn_name]()
    except KeyError:
        util.fatal_error('Undefined evaluation function `%s' % fn_name)
Esempio n. 23
0
def execute_export_command(config, criteria, stations):
    """
	Izvršavanje komande koja vrši izvoz rezultata u format koji se može lako uvesti u Evidenciju

	config - globalna konfiguracija alata za pregled
	criteria - kriterijum pregleda zadatka (bodovanje, način izvršavanja itd.)
	stations - kolekcija računara i studenata koji su radili zadatak (ključ - oznaka računara, podatak - lista - broj
	           indeksa i ime/prezime studenta)
	"""
    error_message = 'Interna greška: format XML fajla nije validan!\nFajl čije parsiranje nije uspelo: {0}'\
     .format(config.FINAL_REPORT_FILENAME)

    if not (path.isfile(config.FINAL_REPORT_FILENAME)):
        util.fatal_error(
            'Ne može se izvršiti izvoz podataka pošto fajl sa izveštajem još uvek ne postoji!'
        )
    else:
        with open(config.FINAL_REPORT_FILENAME) as f:
            xml = f.read()

        root = objectify.fromstring(xml)

    # Provera dve uslova:
    # 1) Da li su svi radovi ocenjeni?
    # 2) Da li postoje preskočeni radovi u izveštaju?
    # Ako je bilo koji od ovih uslova tačan, izvoz rezultata nije moguć:

    done_stations = {}
    for child in root.getchildren():
        if child.tag != 'assignment':
            util.fatal_error(error_message)
        if child['status'] == ASSIGNMENT_STATUS_SKIPPED:
            util.fatal_error(
                'Ne može se izvršiti izvoz rezultata jer postoje preskočeni radovi!\n'
                + 'Molim da ocenite ove radove pa pokušate izvoz ponovo.')
        done_stations[child.attrib['station']] = 1

    if set(stations) != set(done_stations):
        util.fatal_error(
            'Ne može se izvršiti izvoz rezultata jer nisu svi radovi ocenjeni!\n'
            + 'Molim da ocenite ove radove pa pokušate izvoz ponovo.')

    try:
        criteria.total_points  # Provera da li je definisana varijabla
    except NameError:
        criteria.total_points = 100

    total_points_f = float(criteria.total_points)

    with open(config.EXPORTED_REPORT_FILENAME, 'w') as wfile:

        # Upis zaglavlja u CSV fajl:
        wfile.write('indeks,ime,prezime,poeni,ukupno_poena,ip,datum\n')

        for child in root.getchildren():
            if child.tag != 'assignment':
                util.fatal_error(error_message)

            indeks = child['id']
            naziv = child['name'].text
            razmak = naziv.find(' ')

            # Odredjivanje imena i prezimena:
            if razmak == -1:
                ime = naziv
                prezime = ''
            else:
                ime = naziv[:razmak]
                prezime = naziv[razmak + 1:]

            final_score = float(child['final-pct'])
            poeni = int(round(final_score * (total_points_f / 100.0), 0))

            wfile.write('"{0}","{1}","{2}",{3},{4},,\n'.format(
                indeks, ime, prezime, poeni, criteria.total_points))

    command = config.COMPRESS_REPORT_COMMAND
    ret = call(command, shell=True)
    if ret != 0:
        util.fatal_error(
            '''Pokretanje alata za komprimovanje CSV izveštaja u ZIP arhivu nije uspelo!
Komanda koja je pokrenuta:\n{0}'''.format(command))

    print 'Završen je izvoz podataka. Arhiva {0} sadrži rezultate pregleda.'.format(
        config.EXPORTED_ARCHIVE_FILENAME)